早就听老前辈讲指针是C语言的灵魂,指针就是这么个神奇的东西,当你以为自己指针掌握的还不错的时候,下一秒可能就被它的一个变形难住,最近在看一本Kenneth A.Reek写的《C与指针》,感叹以前对指针的理解还是太过肤浅,以下是我的一些小总结。
在我看来,理解一个指针无非是要知道三个问题
①我是谁
②我在哪
③我指向谁
举个例子,假如:
char p='a' //假设声明了p后,p在内存的0x01处,则&p=0x01(&为取变量首地址)
char * p1=&p //则p1= 0x01,*p1=p=' a',p1就和p关联了;假设p1被放在0xa1处
char ** p2=&p1 //则p2= 0xa1,*p2=p1=&p= 0x01,**p2=&p1=p='a'
【一】
①const char *ptr: 不能用ptr来修改所指向的内容
②char const *ptr: 效果同①
③char *const ptr: 不能修改ptr所存放的地址值
【二】
char str[] = "hello";
char *p = str;
p[i]中存放的是变量,
p+i 是一个指针,
所以p[i] =*(p+i) p+i中存放的是p[i]的地址
【三】
一维数组
int num[5] = {1,2,3,4,5};
int *ap = num + 2; ap --------> num[2](第三个元素)
对等表达式,表格中每一行表示的意义相同
printf("%d",*((int*)(&num+1)-1)); 打印结果:5
&num+1:指向下一行的行首(当然此处不存在)
(int*)(&num+1)-1:向前移一个int大小,即指向元素5的地址
num[subscript] 等价于 *(array + (subscript)),subscript可以是一个数,也可以是一个求值表达式
【四】
二维数组
int a[2][3] = {1,2,3,4,5,6};
*(*(a+1)+1)相当于a[1][1];
分析:
*(a+1) 等价 a[1] 等价 &a[1][0]
故*(a+1)+1相当于&a[1][1]
不同于一维数组,这里a并不是一个指向整型的指针,而是一个指向整数数组的指针
可以把二维数组看成一维数组,int a[2][3] <------>int xxx[] = {★1,★2,★3}
只是这个一维数组每一个元素★都是一个入口地址,★2表示一维数组{ a[1][0],a[1][1],a[1][2] }的入口地址,即★2 = &a[1][0]
【五】
数组指针(是一个指针):
int (*p1)[2] p1指向一个内含两个int类型值的数组
指针数组(是一个数组):
int *p2[2] p2是一个内含两个指针元素的数组,每一个元素都是指向int类型的指针
关于二维数组指针表示,C语言指针引用二维数组详解