zoukankan      html  css  js  c++  java
  • C++指针

    指针

    指针和数字

    从概念上看, 指针和整数是截然不同的类型。

    整数是可以执行加、减。。。等运算的数字,而指针是描述的位置。因此,不能简单的将整数赋给指针;

    int * pt;

    pt = 0xB8000000;  这种是错误的

    0xB8000000 是组合段偏移地址, 是老师计算机系统中视频内存的, 但这条语句并么有告诉程序, 这个数字是一个地址。所以需要强制类型转换;

    int * pt;

    pt = (int *) 0xB8000000;

    使用new来分配内存(变量是存放在栈stack的内存里面, 而new从堆heap或者自由存储free store去分配内存)

    指针初始化为变量的地址, 变量是在编译时分配的有名称的内存, 而指针只是为通过名称直接访问的内存提供了一个别名。

    指针的真正用武之地在于, 在运行阶段分配未命名的内存以存储值。在这种情况下, 只能通过指针来访问内存。

    在c语言中可以用malloc()来分配内存, 在c++中仍然可以这样做,但c++还有更好的方法, new运算符。

     int *pn = new int;

    new运算符根据类型来确定需要多少字节。并返回地址。在这里我们说pn指向一个数据对象, 这里的“对象”不是“面向对象编程”中的对象,而是一样东西。 术语“数据对象”比“变量” 更通用, 它指的是

    为数据项分配的内存块。,因此pn指向的是内存

    #include <iostream>
    
    
    int main(int argc, char const *argv[]) {
    
    
      using namespace std;
      int i = 10;
      int * p = new int;
      int * b = &i;
      std::cout << "p:" << p << '
    ';
      *p = 1001;
      std::cout << "p:" << p << '
    ';
    
      std::cout << "*p:" << *p << '
    ';
      delete p;
      // delete p; //not ok now
      // delete b;  // not ok now
    
    
      return 0;
    };

    那么我们要来思考一个问题, 就是内存被耗尽, 计算机可能没有足够的内存而无法满足new请求, 这种情况会引发异常。

    使用new创建动态数组

    对于小型数据对象来说,声明一个变量, 比使用new和指针更简单。但对于大型数据(如数组,字符串和结构), 应使用new, 这正是new的用武之地。

    同时|:

    1.静态联编:如果通过声明来创建数组, 在编译时给数组分配内存被被称为静态联编
    2. 动态联编:使用new时, 运行阶段需要数组, 则创建它, 不需要,就不创建, 还可以选择长度, 被称为动态联编。
    #include <iostream>
    
    
    int main(int argc, char const *argv[]) {
    
    
      using namespace std;
      int * i = new int [3];
      std::cout << "i:" << i << '
    ';
      i[0] = 0;
      i[1] = 1;
      i[2] = 2;
      std::cout << "i[0]:" << i[0] << '
    ';
      std::cout << "i[1]:" << i[1] << '
    ';
      std::cout << "i[2]:" << i[2] << '
    ';
    
      i += 1;  // 所以这种操作是错误的
      std::cout << "i" << i << '
    ';
      std::cout << "i[0]:" << i[0] << '
    ';
      std::cout << "i[1]:" << i[1] << '
    ';
      std::cout << "i[2]:" << i[2] << '
    ';
      delete [] i;
    
    
      return 0;
    }

    但是为撒子delete了以后就错了, 由于i是new出来的, 在堆里面, 越界操作就是野指针,所以delete的时候找不到,系统会报错。

    使用delete释放内存

     C++的魅力之一就是使用new请求来内存管理。另一方面就是使用delete, 那么delete用法:

    int * pt = new int;
    short * ps = new short [500];
    
    delete pt;
    delete [] ps;

     需要遵守的规则:

    1. 不要使用delete来释放不是new分配的内存

     2. 不要使用delete释放同一内存块2次

    3. 如果使用new【】为数组分配内存, 则应使用delete【】释放。

    4. 如果使用new为一个实体分配内存, 则应使用delete(没有方括号)来释放。

    5.对空指针应用delete是安全的

     指针代码块

    int -- float

    #include <iostream>
    #include <cstring>
    
    // int
    /*
    int main(int argc, char const *argv[]) {
      using namespace std;
      int b=12;
      int * a = &b;
      int * c;
      c = &b;
      std::cout << c << ";" << a << '
    ';
      std::cout << *c << '
    ';
      std::cout << *a << '
    ';
      return 0;
    }
    */
    
    /*
    int main(int argc, char const *argv[]) {
      int * b = (int *)11;
      std::cout << b << '
    ';
    
      int *p = new int;
      *p = 1001;
      std::cout << *p << '
    ';
      delete p;
      return 0;
    }
    */

    char

    // str
    /*
    int main(int argc, char const *argv[]) {
      using namespace std;
    
      char a[] = "abc";
      char * b = a;
      std::cout << b << '
    ';
    
      char * c = new char[strlen(a) + 1];
      c = a;
      std::cout << a << '
    ';
      delete [] c;
      return 0;
    }
    */

    list

    // list
    /*
    int main(int argc, char const *argv[]) {
    
      using namespace std;
    
      int a[] = {1,2,3};
      int b[2][2] = {{1, 2}, {3, 4}};
      // int * p = b;
      int * p = b[0];
      std::cout << *(p) << '
    ';
    
      int * c = new int[3];
      c[0] = 3;
      std::cout << c[0] << '
    ';
      delete [] c;
      return 0;
    }
    */

    struct

    // struct

    #include <iostream>
    #include <string.h>

    using namespace std;

    struct abc{
      char name[10];
      float volume;
      int b;
    };

    int main(int argc, char const *argv[]){
      abc ps;
      ps.volume = 20.00;
      memcpy(ps.name, "hello", 6);
      printf("%s ", ps.name);

      abc *pp = new abc;
      pp->b = 222;
      printf("%d ", pp->b);

      return 0;
    }

    对象指针写法

    // 目录和文件都小写, 重要的事情才大写
    
    // 类的名字首字母大写
    #include <iostream>
    #include <string>
    
    using namespace std;
    
    
    class Person {
    private:
        int _pid;
        string _name;
        int _age;
    
    public:
        int testAbc = 123;
        int testAbd = 124;
    
        Person();
    
        ~Person();
    
        void setpid(int pid);
    
        int getpid();
    
        void setname(string name);
    
        string getname();
    
        void setage(int age);
    
        int getage();
    };
    
    Person::Person() {
        std::cout << "构造函数: " << this->testAbc << '
    ';
    }
    
    Person::~Person() {
        std::cout << "析构函数: " << this->testAbd << '
    ';
    }
    
    
    void Person::setpid(int pid) {
        this->_pid = pid; // this 表示当前对象下的_pid
    }
    
    int Person::getpid() {
        return this->_pid;
    }
    
    void Person::setname(string name) {
        this->_name = name;
    }
    
    string Person::getname() {
        return _name;
    }
    
    void Person::setage(int age) {
        this->_age = age;
    }
    
    int Person::getage() {
        return _age;
    }
    
    int main() {
    // 锦绣城, 双滦区 2区观鱼园
    // -----普通方式----- //
    /*
    Person per;
    per.setpid(1);
    per.setname("tom");
    per.setage(20);
    
    int pid = per.getpid();
    string name = per.getname();
    int age = per.getage();
    
    std::cout << "pid: " << pid << " ";
    std::cout << "name: " << name<< " ";
    std::cout << "age: " << age << '
    ';
    */
    
    // -----指针方式-----//
        Person *per = new Person();
        per->setpid(1);
        per->setname("Baker");
        per->setage(20);
        delete per;
    
    
        return 0;
    }
  • 相关阅读:
    策略模式
    Java反射机制
    两个无符号的正大数相加
    MySQL大表优化方案
    造成mysql慢查询的原因
    mysql对于很长的字符列的索引方案
    lyt经典版MySQL基础——函数
    lyt经典版MySQL基础——存储过程
    lyt经典版MySQL基础——变量
    lyt经典版MySQL基础——视图
  • 原文地址:https://www.cnblogs.com/renfanzi/p/7359237.html
Copyright © 2011-2022 走看看