[英]Confusion about dereference operator (“*”) in C
据我所知,解引用运算符*
返回存储在指针地址中的值。 我感到困惑的是,运算符与数组的指针一起使用时的行为。 例如,
int a[4][2];
然后a
在内部转换为2个整数的4个元素的数组的第一个元素的指针。 那么*a
返回哪个值? 我真的很困惑!
的类型的a
是int[4][2]
所以类型*a
(或等价a[0]
是int[2]
它是不一样的a[0][0]
。 如果您这样做:
int a[4][2];
printf("%d\n",*a);
编译器将告诉您以下内容:
警告:格式'%d'期望类型为'int',但是参数2的类型为'int *'
由于数组(在这种情况下是int [2]
类型的数组)被传递给函数,因此在此上下文中它会衰减为指向第一个元素的指针。
另一方面,如果您具有**a
,那么它等效于a[0][0]
并具有int
类型。
这个:
int a[4][2];
定义a
一个由4个元素组成的数组,每个元素都是2个int
元素组成的数组。 (二维数组只不过是数组的数组而已。)
在大多数情况下,数组表达式都会隐式转换为指向数组对象的初始(第零个)元素的指针。 (请注意,存在一个数组对象的假设;这引起了一定的焦虑,但这与此处无关。)
数组表达式不转换为指针的情况是:
sizeof
的操作数时; &
;的操作数时 和 (像gcc的typeof
这样的编译器特定扩展可能会创建更多异常。)
因此,在表达式*a
,子表达式a
(类型为int[4][2]
)隐式转换为类型为int(*)[2]
指针(指向2个int
s的数组的指针)。 应用一元*
取消引用该指针,使我们得到int[2]
类型的表达式。
但我们尚未大功告成。 *a
也是数组类型的表达式,这意味着根据其使用方式,这次可能会再次转换为指针,类型为int*
。
如果我们写sizeof *a
,则子表达式a
从int[4][2]
为int(*)[2]
,但是子表达式*a
没有从int[2]
转换为int*
,因此表达式产生int[2]
类型的大小。
如果我们写**a
, 确实发生了转换。 *a
是int[2]
类型,将转换为int*
; 解引用会产生int
类型的表达式。
请注意,尽管事实上我们可以使用两个指针取消引用操作合法地引用**a
,但没有指针对象 。 a
是一个数组对象,完全由8个int
对象组成。 隐式转换产生指针值 。
隐式的数组到指针转换规则在N1570第6.3.2.1节第3节中。(该段错误地将_Alignof
作为第四例外,但是_Alignof
无法应用于表达式。已发布的C11标准更正了该错误。)
推荐阅读: comp.lang.c FAQ的第6节。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.