#include<stdio.h>
int main(void) {
{
int a[3][3] = {
{
1, 2, 3}, {
4, 5, 6}, {
7, 8, 9}}; /*定义一个二维数组*/
int *ptr = (int *)(&a + 1); /*利用强制转换给指针赋值*/
printf("%p\n",a);
printf("%p\n",a+1);
printf("%p\n",&a);
printf("%p\n",&a+1);
printf("%p\n",ptr);
printf("%p\n",ptr-1);
printf("%lu %lu\n",sizeof(a),sizeof(ptr));
return 0;
}
运行结果如下:
名称 | 地址 | 差值(16进制下转为10进制) |
---|---|---|
a | 0xffffffdcc0c | a+1与a |
a+1 | 0x7fffffffdccc | cc-0c=36 |
&a | 0x7fffffffdcc0c | &a+1与&a |
&a+1 | 0x7fffffffdce4 | e4-0c=12 |
ptr | 0x7fffffffdce4 | prt-1与prt |
ptr-1 | 0x7fffffffdce0 | e0-e4=4 |
- 36 8(用sizeof算出的a与ptr的大小)
分析:
对于int a[3][3] (x,y属于0,1,2)
名称 | 代表 | 所占存储空间 |
---|---|---|
&a | 以整个数组为一个存储单元 | (3*4)*3=36字节 |
a | 以一个a[x](为一个存储单元,a代表&a[0] | 3*4=12字节 |
a[x] | 以一个a[x][y]为一个存储单元,a[0]代表&a[0][0] | 4字节 |
- 再来看看我们的指针ptr
- int *ptr = (int *)(&a + 1)
- 这里为什么要用(int *)强制转换呢?
- 看看上面的解析就知道&a的大小为36字节!,ptr为一个一维指针(一般都为8字节),字节数都不相同,肯定要转换呀!!
- 接下来就是ptr与ptr+k
- 注意:指针的加减运算是增加k个存储单元,所以移动量就应该是 4(int型)*k,而不是指针所占的8字节
现在我们分析分析指针:
对于a[3][3]
名称 | 代表 | 指针+1 |
---|---|---|
ptr | 一维指针 | 若prt指向a,prt+1移动4字节 |
*(ptr)[3] | 二维指针 | 若prt指向a,则prt移动4*3=12字节 |
综上所述:
对于那些一维指针,二维指针,一位数组,二维数组,乃至多维指针,多维数组本质上的差别便是在于所代表的的存储单元的字节数不同,所以在进行+1,-1等的加减运算时所每一次移动的字节数便不同(因为移动的字节数=所占的存储单元*移动次数(1,2,3……))