繁体   English   中英

关于C中的解引用运算符(“ *”)的困惑

[英]Confusion about dereference operator (“*”) in C

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

int a[4][2];

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

的类型的aint[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 ,则子表达式aint[4][2]int(*)[2] ,但是子表达式*a 没有int[2]转换为int* ,因此表达式产生int[2]类型的大小。

如果我们写**a确实发生了转换。 *aint[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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM