简体   繁体   English

为什么结构名称不是 C 中的指针?

[英]Why Struct name is not a pointer in C?

An array name is a pointer and a function name is also a pointer but a Struct name is not a pointer.数组名称是指针,function 名称也是指针,但结构名称不是指针。 I am trying to understand if there is some logical reasoning behind this difference or it is just a random syntax of C language?我试图了解这种差异背后是否有一些逻辑推理,或者它只是 C 语言的随机语法?

There is one and only one instance of array or function, so we can point to them.数组或 function 的实例只有一个,所以我们可以指向它们。 However, there can be many instances of the structure, so we cannot point to the structure, but we can point to the structure instances.但是,结构可以有很多实例,所以我们不能指向结构,但可以指向结构实例。

Arrays are weird. Arrays 很奇怪。 They do not behave like other types.它们的行为与其他类型不同。

C was derived from an earlier language named B 1 , which maintained a separate pointer to the first element of an array. C 派生自一种名为 B 1的早期语言,它维护一个指向数组第一个元素的单独指针。 Given the declaration鉴于声明

auto a[10];

you'd get something like the following in memory:你会在 memory 中得到如下内容:

   +–––+
a: |   | ––+
   +–––+   |
    ...    |
     +–––––+
     |
     v
   +–––+
   |   | a[0]
   +–––+
   |   | a[1]
   +–––+
    ...
   +–––+
   |   | a[9]
   +–––+

The array subscript operation a[i] was defined as *(a+i) - given the starting address stored in a , offset i elements ( not bytes ) from that address and dereference the result.数组下标操作a[i]被定义为*(a+i) - 给定存储在a中的起始地址,从该地址偏移i个元素(不是字节)并取消引用结果。

When designing C, Ritchie wanted to keep B's array semantics, but he didn't want to keep the separate pointer to the first element, so he got rid of it - instead, he created the rule which eventually got standardized as follows:在设计 C 时,Ritchie 想保留 B 的数组语义,但他不想保留指向第一个元素的单独指针,所以他去掉了它 - 相反,他创建了最终标准化的规则如下:

6.3.2.1 Lvalues, arrays, and function designators 6.3.2.1 左值、arrays 和 function 指示符
... ...
3 Except when it is the operand of the sizeof operator, the _Alignof operator, or the unary & operator, or is a string literal used to initialize an array, an expression that has type ''array of type '' is converted to an expression with type ''pointer to type '' that points to the initial element of the array object and is not an lvalue. 3 除非它是sizeof运算符、 _Alignof运算符或一元&运算符的操作数,或者是用于初始化数组的字符串文字,否则类型为 ''array of type '' 的表达式将转换为表达式类型“指向类型”的指针指向数组 object 的初始元素,并且不是左值。 If the array object has register storage class, the behavior is undefined. 如果数组 object 具有register存储 class,则行为未定义。
C 2011 Online Draft C 2011年在线草案

When you declare an array in C like当您在 C 中声明一个数组时

int a[10];

you get this in memory:你在 memory 中得到这个:

 +---+ a: | | a[0] +---+ | | a[1] +---+... +---+ | | a[9] +---+

No space for a separate pointer object has been allocated.没有为单独的指针 object 分配空间。 The subscript operation a[i] is still defined as *(a + i) , it's just in this case the expression a is converted from array type to pointer type as part of the computation.下标操作a[i]仍然定义为*(a + i) ,只是在这种情况下,表达式a作为计算的一部分从数组类型转换为指针类型。

This is important - the array name a is not a pointer .这很重要——数组名a不是指针 Instead, the expression a is converted from array type to pointer type as necessary.相反,表达式a根据需要从数组类型转换为指针类型。

There's a similar rule for functions:函数也有类似的规则:

4 A function designator is an expression that has function type. 4 function 指示符是具有 function 类型的表达式。 Except when it is the operand of the sizeof operator, the _Alignof operator, 65) or the unary & operator, a function designator with type ''function returning type '' is converted to an expression that has type ''pointer to function returning type ''. 除非它是sizeof运算符、 _Alignof运算符65)或一元&运算符的操作数,否则类型为“函数返回类型”的 function 指示符将转换为类型为“指向 function 返回类型的指针”的表达式''。
65) Because this conversion does not occur, the operand of the sizeof or _Alignof operator remains a function designator and violates the constraints in 6.5.3.4. 65) 由于没有发生这种转换,sizeof 或 _Alignof 运算符的操作数仍然是 function 指示符,违反了 6.5.3.4 中的约束。
ibid. 同上。

Struct types don't work like arrays - members aren't accessed based on a numerical offset from a base address.结构类型不像 arrays 那样工作 - 不会根据与基地址的数字偏移量来访问成员。 There's a completely different mechanism at work, so a struct foo expression doesn't "decay" to a pointer type the same way as an array expression or a function designator.有一种完全不同的机制在起作用,因此struct foo表达式不会像数组表达式或 function 指示符那样“衰减”为指针类型。


  1. If you're really interested, you can read Ritchie's own account of developing C in this article .如果你真的有兴趣,可以阅读这篇文章里奇自己开发C的记述。

I think that the main reason is that objects of structure (and union) types opposite to arrays have the assignment operator.我认为主要原因是与 arrays 相对的结构(和联合)类型的对象具有赋值运算符。

So for example you may write所以例如你可以写

struct A a1;
struct A a2;
a1 = a2;

If an object of a structure type would decay to a pointer then this assignment would not have a sense.如果结构类型的 object 将衰减为指针,则此分配将没有意义。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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