有意思的c语言指针
前言
今天看到了一个c语言指针题目,觉得还是很有针对性的,想借此来总结一下关于指针的内容,话不多说,请诸位看官看题
题目
#include<stdio.h>
int main()
{
char *c[] = {"Zero","One","Two","Three"};
char **cp[] = {c+3,c+2,c+1,c};
char ***cpp = cp;
printf("%s\n",**++cpp);
printf("%s\n",*--*++cpp+3);
printf("%s\n",*cpp[-2]+3);
printf("%s\n",cpp[-1][-1]+1);
return 0;
}
供查阅
learging
浅薄的谈一下我的总结
指针
指针是c的精髓,c的意义就在于其直接对硬件的写入读出。
- 指针声明: 指针声明命名指针变量,并指定变量指向的对象的类型。 声明为指针的变量保存内存地址
- 指针变量的行为:寻址和运算
寻址
我们定义
int a[2], *p = &a
再来看p[1],p为int指针,1为指针偏移量,所以p[1]就是(p+1)
- 我们要明确数组名并不代表整个数组,只是代表数组首元素的地址,这一点在做指针运算时候尤为重要
指针运算
首先要牢记指针乘法和除法没有意义,因为你也不知道你算出了个什么鬼东西。狗头保命
- 指针加法,前面提到过,特别注意的是
*(p+1)=p+1*sizeof(void),void是什么类型取决于你定义什么类型的p。
提出这一点完全是为了注意多级指针的指针加法 - 指针减法 在将两个指针相减时,会通过将差值除以指针寻址的类型值的大小来将该差值转换为带符号的整数值。
In addition
看到指针请去思考:指针名是什么?这个指针的类型是什么?指针指的类型是什么?该指针指向了哪里?
题目分析
char *c[] = {"Zero","One","Two","Three"};
首先定义了指针数组c(c为长度为4的数组,数组存储了4个char*类型指针)
eg:c[0]="Zero";c[1]="First"char **cp[] = {c+3,c+2,c+1,c};
然后定义了指针数组cp(cp长度为4,存储了4个char**二级指针)
eg:*cp=c+3; **cp = *(c+3)="Three";char ***cpp = cp;
定义了一个指针cpp,类型为char***三级指针,指向cp
*cpp = *cp = c+3;
此时指针指向关系如下图

所以
- ++cpp的值为cp[1],再两次解引用得到“Two”(注意,cpp的值已经变为cp[1])
- ++cpp变为cp[2],*运算变为c+1,再自减为c (注意,--为c+1-1=c再赋值给cp[2],改变了指向关系)
关系如图(绿色)

- c做解引用*c为“Zero”的首地址,地址+3为“ro”
- cpp[-2] = *(cpp - 2),cpp 指向 cp[2],cpp - 2 指向 cp[0]= c+3
- 所以cpp[-2] = c[3] → "Three"。
- 再+3:"Three" + 3 → "ee"
关系如图(红色)

- cpp[-1] = *(cpp - 1)
- 又 cpp 指向 cp[2],cpp - 1 指向 cp[1],所以cpp[-1] = cp[1] = c+2。
- 再来一次,cpp[-1][-1] = *(cpp[-1] - 1),cpp[-1] 是 c+2,减 1 得 c+1(指向 c[1])。
- (c+1) = c[1] → "One"。
- 最后+1:"One" + 1 → "ne"
写在最后
指针是c语言的精髓,指针拥有寻址和变量的双重属性,寻址属性让指针指向另一个变量,变量属性让另一个多级指针可以指向该指针。知道一个变量存在哪里,指向什么,这是我觉得分析一个指针必不可少的过程。

浙公网安备 33010602011771号