请解释C中指针的含糊不清?

时间:2011-09-08 16:23:08

标签: c pointers

#include<stdio.h>
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。

4 个答案:

答案 0 :(得分:27)

对于指针,x[0]*x相同。由此得出*x[0]**x相同。

*x[0]

xint[3][5],在表达式中使用时会转换为int(*)[5]。所以x [0]是int[5]类型的左值(第一个5元素“行”),它再次转换为int*,并取消引用它的第一个元素。

*x沿着相同的行进行评估,除了第一个取消引用用星号(而不是索引)完成,并且没有第二个取消引用,所以我们最终得到类型为{{1}的左值},作为指向其第一个元素的指针传递给int[5]

答案 1 :(得分:5)

当用作函数的参数时,数组会衰减为指向数组第一个元素的指针。话虽这么说,x衰变的对象类型是指向第一个子数组的指针,第一个子数组是指向int数组的指针,或者基本上是int (*)[5]。当您调用printf("%d\n",*x)时,您没有向printf提供整数值,而是指向x的第一个子数组的指针。由于该子数组也将衰减为指向第一个子数组元素的指针,因此您可以**x取消引用该后续指针并获取x第一个子数组的第一个元素。这实际上与*x[0]相同,它由运算符优先级将索引到x的第一个子数组,然后取消引用指向第一个子数组的第一个子数组的元素将腐烂。

答案 2 :(得分:0)

因为*x的类型是'指向5个整数的数组'。因此,您还需要一个解引用才能获得第一个元素

PS:

#include <typeinfo>
#include <iostream>

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;
}

答案 3 :(得分:-1)

将2-d数组视为指针数组,数组中的每个元素都指向另一个数组中的第一个元素。取消引用x时,您将获得x指向的内存位置中的值...指向int数组中第一个int的指针。当您取消引用该指针时,您将获得第一个元素。