请解释C中指针的含糊不清?
#include main() { int x[3][5]={{1,2,10,4,5},{6,7,1,9,10},{11,12,13,14,15}}; printf("%d\n",x); printf("%d\n",*x); }
这里首先printf将打印第一个元素的地址。 那么为什么不是第二个printf在地址x处输出值,即第一个值。 要打印我需要写的值** x。
对于指针, x[0]
与*x
相同。 由此得出*x[0]
与**x
相同。
在*x[0]
:
x
是int[3][5]
,在表达式中使用时会转换为int(*)[5]
。 所以x [0]是int[5]
类型的左值(第一个5元素“row”),它再次转换为int*
,并且取消引用它的第一个元素。
*x
沿着相同的行进行计算,除了第一个取消引用是用星号(而不是索引)完成,并且没有第二个取消引用,所以我们最终得到类型为int[5]
左值,它被传递给printf
作为指向其第一个元素的指针。
当数组用作函数的参数时,它会衰减成指向数组第一个元素的指针。 话虽这么说, x
衰变的对象类型是指向第一个子数组的指针,第一个子数组是指向int
数组的指针,或者基本上是int (*)[5]
。 当你调用printf("%d\n",*x)
,你没有给printf
一个整数值,而是一个指向x
的第一个子数组的指针。 由于该子数组也将衰减为指向第一个子数组元素的指针,因此可以执行**x
取消引用后续指针并获取x
的第一个子数组的第一个元素。 这实际上与*x[0]
,它通过运算符优先级将索引到x
的第一个子数组,然后取消引用指向第一个子数组将衰减到的第一个子数组的元素。
因为*x
的类型是’指向5个整数的数组’。 因此,您还需要一个解引用才能获得第一个元素
PS:
#include #include typedef int arr[5]; // can't compile if put arr[4] here void foo(arr& x) { } int main() { int x[3][5]={{1,2,10,4,5},{6,7,1,9,10},{11,12,13,14,15}}; std::cout << typeid(*x).name() << std::endl;// output: int [5] foo(x[0]); return 0; }
将2-d数组视为指针数组,数组中的每个元素都指向另一个数组中的第一个元素。 当您取消引用x
,您将获得x指向的内存位置中的值…指向int
数组中第一个int
的指针。 当您取消引用该指针时,您将获得第一个元素。