求助:C语言二维数组指针问题
int **p = a;
printf("%d", *p);
1.在这个程序中,为什么这么定义**p=a?p指向哪里了?
2.按道理说不是应该*p=a,把指针a[0]的地址给p吗?为什么我在TC里不可以这么写,但是在VS2015却可以?
3.输出时候为什么间接引用一次就能输出a[0][0]?按道理说p指向a[0]不是应该间接引用两次吗?
4.a++是指的是从指针a[0]直接挪动到指针a[1],还是说和步长有关?
希望大神帮我解答一下,感激不尽!!! 展开
1.
对于int **p = a;
p类型和a是不同的。
p是指向一个指针(指向int类型的量)的指针,a则是指向一个一维数组(含2个int元素)的指针。
想要创建相同类型的指针应该用int (*p)[2]; 才行
3.
感觉p跟a就同级吧但类型不同
所以其实int **p=a; 两侧的指针的类型是不相同的,只是a的值赋给p而已
假设a[0][0]地址是0x99
神奇的是对数组而言,a、a[0]、*a的值是一样的,都是0x99!
你可能会想这不可能吧
但如果你使用*a操作,你会发现效果就是等价于a[0],不会直接取值(指向数组的指针的奇怪之处)
此时a的值是0x99
a赋给p的值是0x99
而对p来说就不一样(p不是指向数组的指针),*p真的是对那个地址的内存取值。
所以即使printf("%d", *p); 提示说类型不合适,但是p存的地址值就是a[0][0]的地址值,又有%d限制读取数据的长度为int类型,所以可以成功间接取值(但会有警告哦)。
2.
用int *p=a; 就更不对了,二者类型差别更大了,都不是一个层次的了,前者指向一个int类型,后者指向一个int类型的数组。
4.
a是指针常量,不能用a++的。指针+1的话就是移动一个指向对象大小的位置,也就是说
如果a的值是2000,a+1就是2000+2*4(2个元素*4个字节)=2008
抱歉哈,还是有点理解困难。
对于*p=a的话,因为基类型不同所以是错误的,这么理解吧?
**p=a其实也是不正规的指向?
a指向a[0],a[0]指向a[0][0]吧?但是为何a、a[0]、*a的值是一样的呢?
谢谢大大了!!
int *p=a和int **p=a ;都存在类型不一致的问题,只有int (*p)[2]=a; 才是相同类型的赋值。
对数组而言,我个人理解是a[0]不能理解为一个指针变量那种形式,比如说
int e;
int *c=&e;
int **b=&c
这样b存储的是指针c的地址,指针b指向指针c,指针c存储的是e的地址,指针c指向e
b、c、e在内存中是有分配存储空间的变量
但对数组来说
int a[2][2] = { 1,2,3,4 };
一旦你这样初始化之后,a、a[x]、a[x][x]都可以使用了,a[x][x]是有分配存储空间的,地址可以用&a[x][x]查看。那么a[x]、a呢?你对它们取地址,你会发现它们的地址都跟a[0][0]的地址一样。如果你把它们认为是等同于上面那几个指针(b、c),因为a、a[0]、a[0][0]的地址一样,a存储的是a[0]的地址,a[0]存储的是a[0][0]的地址,a[0][0]存储了一个值,这三个值不可能存储在同一个地方。所以a、a[x]跟上面的b、c是不一样的。
所以我觉得,对于指向数组的指针应该都有这么一个规则:指针的值 和 指针指向的数组的数组名的值相等。即a=a[0]=*a(数值上相等)