比较通俗易懂的c指针笔记(二)
指针的操作:
1.赋值。可以把一个地址赋值给指针。一般使用数组名或(取地址运算符+变量名)读指针进行赋值。需要注意的是,指针也是有类型的,例如不能把double型地址赋值给指向int型的指针。地址应该和指针类型兼容。
2.取值。利用*来取指针指向地址中存储的数值。这里需要注意的是不能对未初始化的指针取值。这个错误很严重!!需注意。
3.取指针地址。指针也是一个变量,他也有自己的一块存储空间,里面存放着一段地址。例如:int *p; 指针p有自己的一块存储空间,这块存储空间存放的数值是地址,p是这块存储空间的名字。这块存储空间也是有地址的,于是就有指向指针的指针。
4.增加和减少指针的值。(一)中已经解释指针如何运算的。其自加自减同样是这么运算的。
5.求差值.通常对分别指向同一数组内两个元素的指针求差值,差值的单位是相应类型的大小。如果p2-p1的值是2,其中的2是指p2和p1间的距离,用2个int数值表示,2不是字节。!!!
这里有个注意:c保证指向数组元素的指针和指向数组后的第一个地址的指针都是有效的。!!!
指针和多维数组:
多维数组:其数组中包含数组。例如:int zippo[4][2]={{2,4},{6,8},{1,3},{5,7}};
学过线性代数的可以看出,数组很像矩阵.其中zippo[0]在这里表示一个地址而不是一个数值。*zippo[0]=2; 其中zippo[0]是一个地址,指向{2,4},*取zippo[0]的值即2。这里zippo是一个地址指向数组首元素的地址,这个首元素的地址就是zippo[0],zippo[0]是一个地址指向{2,4}这个数组首元素的地址。则*zippo[0]就是2。不难理解,就好像int a[2]={2,4};*a=2;一样。
这里数组zippo是一个包含两个int的数组。zippo+1加的是两个int,以两个int为一个单元。zippo[0]包含一个int的一维数组,其数组元素是{2,4},容易误解的是这里{2,4}表示的是数组名为zippo[0]的一维数组的两个元素,而不是两个int。zippo[0]+1 其地址加的是四个字节。而zippo+1 其地址加的是8个字节。
例:
#include<stdio.h>
int main(void)
{
int a[2]={2,4};
int zippo[4][2]={{2,4},{6,8},{1,3},{5,7}};
printf("*a=%d\n",*a);
printf("zippo=%p, zippo+1=%p\n",zippo,zippo+1);
printf("zippo[0]=%p, zippo[0]+1=%p\n",zippo[0],zippo[0]+1);
printf("*zippo=%p, *zippo+1=%p\n",*zippo,*zippo+1);
printf("zipoo[0][0]=%d\n",zippo[0][0]);
printf("*zippo[0]=%d\n",*zippo[0]);
printf("**zippo=%d\n",**zippo);
printf("zippo[2][1]=%d\n",zippo[2][1]);
printf("*(*(zippo+2)+1)=%d\n",*(*(zippo+2)+1));
return 0;
}
运行结果:这里的地址都是16进制。(0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F) zippo+1自己数够8位就正好进位。
*a=2
zippo=0012FF58, zippo+1=0012FF60
zippo[0]=0012FF58, zippo[0]+1=0012FF5C
*zippo=0012FF58, *zippo+1=0012FF5C
zipoo[0][0]=2
*zippo[0]=2
**zippo=2
zippo[2][1]=3
*(*(zippo+2)+1)=3
Press any key to continue
基本概念理解,其他即靠自己多练习。