1. 二级指针存放一级指针的地址,一级指针存放变量的地址,变量存放数值。(只要是指针,均占4个字节!)
int a = 10;
int* p = NULL;
int** s = NULL;
s = &p; //s为二级指针,指向一级指针p的地址
*s = &a; //s=&p; *s=*&p=p=&a; p为一级指针,指向变量a的地址
**s = 100; //**s=*p=*&a=a=100; 变量赋值为100
2. 如图,问 s+1是加几个字节? *s+1是加几个字节? **s+1呢?
(1)int类型
s+1:s是二级指针,存放p0的地址。s+1后其存放p1的地址。(相当于加了4个字节(指针),加后的结果仍为int**)
*s+1:*s为p0本身,p0为一级指针,存放a0的地址。(*s+1相当于加了4个字节(整型),加后的结果仍为int*)
**s+1:**s为a0本身,**s+1即a0的值加1,加后结果为整型。
(2)将变量a0,a1,a2,a3、一级指针p0,p1,p2,p3、二级指针s定义的类型全改为double类型呢?
s+1:相当于加了4个字节(指针类型),加后的结果仍为double**
*s+1:*s+1相当于加了8个字节(double类型),加后的结果仍为double*
**s+1:**s为a0本身,**s+1即a0的值加1,加后结果为double类型。
(3)将变量a0,a1,a2,a3、一级指针p0,p1,p2,p3、二级指针s定义的类型全改为char类型呢?
s+1:相当于加了4个字节(指针类型),加后的结果仍为char**
*s+1:*s+1相当于加了1个字节(char类型),加后的结果仍为char*
**s+1:**s为a0本身,**s+1即a0的值加1,加后结果为char类型。
总结(取决于指向): 若定义有typename **p; 则p+1=>p+sizeof(*p)*1;*p+1=>*p+sizeof(**p)*1;(指针永远占4个字节!)
3. 二级指针与数组
(1)若有定义int ar[4]; 只有两种情况下数组名代表整个数组:sizeof(ar)和&ar(ar代表数组ar首元素地址,&ar代表整个数组首地址。故ar+1代表加到数组第二个元素ar[1]的地址,&ar+1代表加到下一个数组首地址)ar与&ar的值相同,但代表的意义不同!
若有定义int* p=&ar; 则*p即*&ar=ar; (ar、*&ar、&ar值相同,ar和*&ar意义相同)
(2)如图:定义int (*s)[4]; 令s=&ar0; 现在想给ar2[3]赋值为100,用s该如何操作?
解析: s=&ar0 -> s+1=&ar1(加一个数组的大小) -> s+2=&ar2 -> *(s+2)=*&ar2=ar2=&ar2[0](数组首元素地址)-> ar2+1=&ar2[1] -> ar2+3=&ar2[3]=*(s+2)+3 -> *(*(s+2)+3)=ar2[3] -> 赋值即可:*(*(s+2)+3)=ar2[3]=100;
接下来对*(*(s+2)+3)=ar2[3]=100进行转换(指针表示转换为数组下标表示):*(s+2)=s[2],故原式可以转换为*(s[2]+3),进一步转换为:*(s[2]+3)=s[2][3],故赋值表达式可以变为:s[2][3]=100;