多级指针和数组指针

1.*()和[]
定义几个不同级别的指针类型的数据
char* p1;    
char** p2;    
char*** p3;    
char**** p4;    
char***** p5;    
char****** p6;    
char******* p7;    
 
1)*运算
代码:
printf("%d",*p1);
反汇编:
结论:
    *运算的本质是取指针变量的值,利用这个值作为地址来寻址获取结果;
 
代码:
printf("%d",*(p1+0));
分析:
    根据指针类型的特性,p1+0所得的类型还是char*类型,
    并且所得的值要加上为去掉一个*后的类型的宽度乘以所加的数,而char的宽度是1,结果还是和原来一样;
反汇编和*P1没有区别:
结论:*(p1) ==*(p1+0)
 
2)[]运算
*(p1+0)可以用另一种写法:p1[0]
printf("%d",p1[0]);
反汇编:
分析:
    *(p1+0)和p1[0]生成的反汇编代码完全一样;
结论:
    *(p1+0) == p1[0]
 
代码:
printf("%d",*(p1+2));
printf("%d",p1[2]);
反汇编:
分析:
    *(p1+2)是用p1+2所得的值来寻址:p1+(char*去掉一个*后的类型的宽度也就是char=1)x2;
    *(p1+2)的反汇编和p1[2]完全一样;
结论:
    *(p1+2) == p1[2]
 
3)多级指针
p2的类型是char**,也就是二级指针;
凡是带*的类型的变量都可以进行*运算;
*运算后的类型为原来的类型去掉一个*;
代码:
printf("%d",*(*(p2)));
反汇编:
分析:
    取p2的值,利用p2的值寻址,利用地址处的值为地址再次寻址;
 
代码:
printf("%d",*(*(p2+0)+0));
反汇编:
分析:
    *(p2+0) == *p2,经过*计算后类型变化:char**    ->char*;
    *(*p2+0) == *(*p2),因为*p2位char*类型,而char*类型的特性,加上一个整数等于加上去掉一个*后的类型的宽度乘以整数,也就是0,结果还是*p2;
结论:
    *(*(p2+0)+0) == *(*p2)
    
代码:
    printf("%d",*(*(p2+1)+2));
    printf("%d",p2[1][2]);
反汇编:
分析:
    p2是char**类型,根据指针类型的特性,p2+1相当于加上去掉一个*的类型的宽度乘以1;
    也就是char*的宽度乘以1,又因为所有带*的类型宽度都是4,因此生成的反汇编寻址时为[eax+4];
    同理,第二次寻址时的反汇编是[ecx+2];
    *(*(p2+1)+2)生成的反汇编和p2[1][2]完全一样;
结论:
    *(*(p2+1)+2) == p2[1][2];
 
4)总结:                
                
*(p+i) = p[i]                
*(*(p+i)+k) = p[i][k]                
*(*(*(p+i)+k)+m) = p[i][k][m]                
*(*(*(*(*(p+i)+k)+m)+w)+t) = p[i][k][m][w][t]                
                
*() 与 []可以相互转换    
 
2.实例
    char** p;
 
    printf("%d",*(p+1)[2]);
    printf("%d",*(*(p+1)+2));
反汇编:
分析:
    *(p+1)[2] != *(*(p+1)+2)
    因为[]的运算优先级要高于*,先计算p+1移动4个字节;
    然后计算(p+1)[2],相当于以p+1指向的地址作为首地址的数组,移动2*4=8个字节,所以为[eax+c];
    最后做*运算;
 
3.数组指针
结构体指针    ->存了一个地址,该地址指向一个结构体;
指针的指针    ->存了一个地址,该地址指向一个指针;
数组指针    ->存了一个地址,该地址指向一个数组;   
 
1)数组指针的特性
和普通指针的特性差不多:
    宽度为4;
    可以++、--;
    可以加减一个整数;
 
2)使用数组指针
 
利用指针数组遍历:
 
3)数组指针和指针数组的区别
int *p[5] 与 int (*p)[5]  有什么区别?
原因:
    [] 的优先级高于*  所以先组合成p[5]数组 再由int *说明 数组存储的类型 == int* p[5];
    () 的优先级高于[] 所以*先p先组合成指针 再由int[5]说明数组的宽度
 
 
 

猜你喜欢

转载自www.cnblogs.com/ShiningArmor/p/11673159.html
今日推荐