指针数组和数组指针

来源:互联网 发布:tsp 遗传算法 java 编辑:程序博客网 时间:2024/04/30 13:00

对这两个兄弟,真是傻傻分不清楚,所以就写下这篇博客,其实从它们的英文名字就容易理解多了。


指针数组:  array of pointers,  即用于存储指针的数组,也就是数组元素都是指针

举例:

 int* a[4];      //数组a中的元素都是 int 型指针。

          //元素表示:*a[ i ],*(a[ i ])  是一样的,因为[ ] 优先级高于*

数组指针:a pointers to an array ,即指向数组的指针。

举例:

int(* a ) [ 4 ]  ;// 表示指向一个包含4个int类型数据的数组

//元素表示:( *a )[ i ]

思考题:

1、a与&a之间的区别

举例:

int main(){char a[5] = { 'A', 'B', 'C', 'D' };char(*p3)[5] = &a;char(*p4)[5] = a;return 0;}

p3和p4都是数组指针,指向整个数组。&a是整个数组的首地址,a是数组首元素的首地址,两者值相同但意义

不同。在C 语言里,赋值符号“=”号两边的数据类型必须是相同的,如果不同需要显示或隐式的类型转换。p3 这个定

义的“=”号两边的数据类型完全一致,而p4 这个定义的“=”号两边的数据类型就不一致了。左边的类型是指向整个数组

的指针,右边的数据类型是指向单个字符的指针。


编译上面程序时,会出现警告:“char (*)[5]”与“char *”的间接级别不同

分析:p3、p4都是指向整个数组的,p3+1 、p4+1 的值就是指向整个数组后面的一段地址空间


int main(){char a[5] = { 'A', 'B', 'C', 'D' };char(*p3)[3] = &a;char(*p4)[3] = a;return 0;}
上面的分析知道,此时 p3+1、p4+1是将指针右移3位 。


同样,下面p3+1 、p4+1 也很容易理解了

int main(){char a[5] = { 'A', 'B', 'C', 'D' };char(*p3)[10] = &a;char(*p4)[10] = a;return 0;}

2、地址的强制转换

举例:

struct Test{   int Num;   char *pcName;   short sDate;   char cha[2];   short sBa[4];}*p;

假设p的值为0x10000000,下面的表达式值为多少?

  p + 0x1 = 0x___ ?
   (unsigned long)p + 0x1 = 0x___?
   (unsigned int*)p + 0x1 = 0x___?

分析:

还记得前面我们的表达式“a+1”与“&a+1”之间的区别吗?其实这里也一样。指针变量与一个整数相加减并不是用

指针变量里的地址直接加减这个整数。这个整数的单位不是byte 而是元素的个数。所以:p + 0x1 的值为0x100000

+sizof(Test)*0x1。至于此结构体的大小为20byte,前面的章节已经详细讲解过。所以p +0x1 的值为:0x100014。

(unsigned long)p + 0x1 的值呢?这里涉及到强制转换,将指针变量p 保存的值强制转换成无符号的长整型数。任何

数值一旦被强制转换,其类型就改变了。所以这个表达式其实就是一个无符号的长整型数加上另一个整数。所以其值

为:0x100001。

(unsigned int*)p + 0x1 的值呢?这里的p 被强制转换成一个指向无符号整型的指针。所以其值为:0x100000+sizof

(unsigned int)*0x1,等于0x100004。


对于上面的问题,似乎没什么大的疑问,下面就加深点:

int main(){   int a[4]={1,2,3,4};   int *ptr1=(int *)(&a+1);   int *ptr2=(int *)((int)a+1);   printf("%x,%x",ptr1[-1],*ptr2);   return 0;}


分析:

ptr1:将&a+1 的值强制转换成int*类型,赋值给int* 类型的变量ptr,ptr1 肯定指到数组a 的下一个int 类型数据了。

ptr1[-1]被解析成*(ptr1-1),即ptr1 往后退4 个byte。所以其值为0x4。


ptr2:按照上面的讲解,(int)a+1 的值是元素a[0]的第二个字节的地址。然后把这个地址强制转换成int*类型的值赋给

ptr2,也就是说*ptr2 的值应该为元素a[0]的第二个字节开始的连续4 个byte 的内容。


布局如图:


    



这里ptr2指向的连续的4个字节是什么呢?

答:  这里要考虑系统的大小端问题。如果当前系统为大端模式,则 *ptr2的值为0x100 ; 若当前系统为小端系统,*ptr2的值 0x2000000 



0 0
原创粉丝点击