关于 C 语言中解引用运算符 ("*") 的困惑

Confusion about dereference operator ("*") in C

据我所知,解引用运算符 * returns 存储在指针地址中的值。我感到困惑的是运算符与数组指针一起使用时的行为。例如,

int a[4][2];

然后a被内部转换为2个整数的4个元素数组的第一个元素的指针。那么*areturn是哪个值呢?我真的很困惑!

a的类型是int[4][2],所以*a(或等效的a[0])的类型是int[2]

a[0][0]相同。如果你这样做:

int a[4][2];
printf("%d\n",*a);

编译器会告诉你:

warning: format ‘%d’ expects type ‘int’, but argument 2 has type ‘int *’

由于数组(在本例中为 int [2] 类型之一)被传递给函数,它会衰减为指向此上下文中第一个元素的指针。

如果另一方面您有 **a,则相当于 a[0][0] 并且类型为 int.

这个:

int a[4][2];

定义了a一个包含4个元素的数组,每个元素都是一个包含2个int个元素的数组。 (二维数组不过是数组的数组。)

在大多数上下文中,数组表达式隐式转换为指向数组对象的初始(第零个)元素的指针。 (请注意假设有一个数组 object;这引起了一些焦虑,但它与这里无关。)

数组表达式转换为指针的情况是:

  • 当是sizeof的操作数时;
  • 当为一元操作数时&;和
  • 当它是用于初始化数组对象的初始化程序中的字符串文字时。

(特定于编译器的扩展,如 gcc 的 typeof 可能会产生更多异常。)

所以在表达式*a中,子表达式aint[4][2]类型)被隐式转换为int(*)[2]类型的指针(指向数组的指针2 int 秒)。应用一元 * 取消引用该指针,为我们提供类型 int[2].

的表达式

但我们还没有完全*a也是一个数组类型的表达式,也就是说,根据使用的不同,它可能又会被转为指针,这次是[=24]类型=].

如果我们写sizeof *a,子表达式aint[4][2]转换为int(*)[2],但是子表达式*a notint[2] 转换为 int*,因此表达式产生 int[2].

类型的大小

如果我们写 **a,转换 发生。 *aint[2]类型,转换为int*;解引用产生 int.

类型的表达式

请注意,尽管我们可以合法地引用 **a,使用两个指针取消引用操作,但没有指针 对象 a是一个数组对象,完全由8个int对象组成。隐式转换产生指针 values.

隐式数组到指针的转换规则在 N1570 节 6.3.2.1 第 3 段。(该段错误地将 _Alignof 作为第四个例外,但 _Alignof 不能应用于表达式。已发布的 C11 标准更正了错误。)

推荐阅读:comp.lang.c FAQ.

的第6节