六、关于c++的复合类型(四)

指针

1.指针是一个变量,但这个变量与普通变量最大的不同就是普通变量存储着值,而指针存储着值的地址而不是值本身。

2.一个变量的地址要怎么找到呢?这里使用地址运算符&,可以获取一个变量的地址,地址一般是一个十六进制表示的整数。

   int a;

   int *b = &a;//这样就可以得到变量a的地址

3.指针存储的是变量的地址,所以指针名表示地址。*运算符被称为间接值或解除引用运算符,常用于指针,得到该地址处存储的值。

   int a = 100;

   int *b = &a;

   *b;  //100

4.声明和初始化指针

int * a; //这里我们说的类型是指向int的指针(int *),也可以这么说,a是指针(地址),*a是int,而不是指针

注:把int *看成一种复合类型,是指向int的指针

5.指针的危害

指针我们可以这样理解,跟我们普通变量一样,一开始会分配一块内存空间,而普通变量在内存空间里存的是值,而指针变量在分配的内存空间里存的是另一个变量地址。在C++创建指针时,计算机就给分配了一块地址,但是这块地址中存的另一个变量的地址计算机就没有给分配。

int *a; //分配了指针变量a的内存地址,但这时还不知道这块地址里面存的是哪个变量的地址

*a =223323; //*a是指存的变量的值,而上面并没有指定是哪个变量的地址,所以223323不知道要放到什么地方,可能就会放到                        我 们有用的内存区域造成数据损坏

所以在指针应用解除引用运算符(*)前,要注意看看指针是不是已经指向一个明确的地址(int *a =&b;)

6.关于不同类型的指针

int *a,b;

double *c,d;

a = &b;(注意不是*a = &b,*a是指所指向内存的值)

c = &d;

sizeof(a);  //4

sizeof(c);  //4 (为什么这个是4而不是8,因为c的类型不是double而是double *,指针是一个地址,所以是4)

sizeof(b);  //4

sizeof(d);  //8

不管是double指针还是int指针都是一个地址,4字节

7.使用new来分配内存

指针的真正用武之地在于运行阶段分配未命名的内存以存储值。在这种情况下就只能用指针来访问内存。new运算符就是在运行时来分配未命名的内存的。程序员只要告诉new需要为什么样的数据类型分配内存,new就会找到一块长度正确的内存并返回这块内存的首地址,而程序员再把这块地址赋给一个指针(变量)

如:

int *a = new int; //  new int 告诉程序要适合存储int类型的内存地址,new返回一块地址的首地址赋给指针变量a

与普通指针作比较

int b;

int *a = &b;

下面这种情况除了可以用指针变量a拿到b的地址还可以用&b拿到这块内存地址,除了可以用*a拿到这块地址里存储的值,还可以直接用b拿到,而上面的情况只能用a拿到指向的内存地址,*a拿到指向地址存储的值。

注:new分配的内存块与普通变量声明分配的内存块是不一样的。普通变量存储在栈中,而new是从堆或者自由存储区的内存区域分配内存。

8.使用delect释放内存

8.1delect和new要配对使用,且delect只能释放new分配的内存(如果没有配对使用,将发生内存泄漏,即分配出去的内存将再也无法使用)

int *a = new int;

int *b =a;

delect b; 

首先new分配一块内存区域,a指针指向这块内存区域,int *b = a; 声明一个指针变量b,而我们知道指针变量a其实是一个地址,将一个地址赋给指针变量b,就是让b指针也指向这块区域,使用指针a,b都指向同一块内存区域,delect b;回收这块区域,因为delect能释放new分配的内存,只要这块内存是new分配的就可以回收,使用delect b没有问题。

8.2 int * ps = new int;

      delete ps;

delete释放了ps指向的内存,但是不会删除指针ps,ps还是可以重新指定一块内存区域。

9.使用new创建动态数组以及使用指针访问数组元素

9.1使用new创建动态数组

int * a = new int [10];

new返回第一个元素的地址,再把地址赋给a

同样也要配对使用delect释放这一块内存

delect [] a; 

[]告诉程序要释放整个数组,而不单单只释放a指针指向的元素。

9.2操作动态数组

int *a = new int[3];

创建指针a指向包含10个int值的内存的第一个元素

这时指针就想到于一根手指。int占4个字节,a+1,表示指针移动到第二个元素,而从a到a+1所指的内存要走的就是一个int的长度,我们可以使用*a拿到第一个元素的值,*(a+1)那到第二个元素的值,*(a+2)拿到第三个元素的值。

还有另一种就是类似数组的访问方式,a[0]访问第一个元素相当于*a,a[1]访问第二个元素相当于*(a+1),a[2]访问第三个元素相当于*(a+2)

a[0] = 1;

*(a+1) = 2;

这时数组就变成了{1,2,任意值},因为第三个元素没有赋值,所以为任意值

注:*(a+1)和*a+1的区别

*的优先级高于+,*(a+1),是先把指针a向正确方向移动一个类型的长度(这里是int类型,就是4字节),到达第二个元素,再*访问该地址存储的值。而*a+1,由于优先级*a先执行,读取出当前第一个元素的值,再把值+1。

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章