当我在下面声明一个结构时
struct {
int a;
int b;
} x;
&x
是结构体的地址吧?但是在我看来,结构体就是数据的集合,所以不太明白&x
具体指向什么地址。当你有一个数组时,比方说,
char a[] = "This is a test";
*a
指向数组a[]
的第一个元素,即a[0]
。上面的案例呢?
在我看来,结构体就是数据的集合,所以我不太明白
具体指向什么地址&x
这个答案存在并且有自己的身份,但其中也包括上面的引文和你现在正在阅读的句子。同样,您的“数据集合”本身就是一个对象,包括其所有成员。程序中存在的每个此类对象在内存中都有一个表示,其中包含其成员的表示。
结构对象的地址是该表示的地址。为此,表示采用什么形式并不重要。一个结构、一个
int
、一个数组、一个联合——所有这些都是具有身份的对象,可以驻留在内存中,并且在这种情况下具有地址。 “数据集合”具有内部结构并不意味着它本身不是“数据”。
但是,C确实为结构的表示指定了一些规则。具体来说,结构的表示包含每个成员的表示,按照成员声明的顺序,可能在成员之间和/或最后一个成员之后使用未命名的填充。在第一个成员之前不允许填充,语言规范明确指出结构的地址,转换为正确的类型,指向该结构的第一个成员。
也许这个粗略的插图会有所帮助:
+---+--------------------+-+ :
| | x.a | | :
| x | | | a
| | | | d
| +--------------------+ | d
| [... optional ...] | r
| +--------------------+ | e
| | x.b | | s
| | | | s
| | | | :
| +--------------------+ | :
| [... optional ...] | V
+---+----------------------+
有一个很好的资源,https://google.com。让我为你谷歌。
我预计这个回应会被严重否决
当你花了足够多的时间思考这样的想法时,你最终会发现,在可执行文件中,没有
int
、char
、数组或 struct
。机器代码没有这些概念。
编译器解释源代码,发出机器指令来操作内存字节的值。
如果源代码没有提到
unsigned
,算术运算将识别负值。
如果源码中提到数组,会保留多个相邻的字节,根据数组是
char
还是int
还是double
等的数组来保留和寻址
如果源代码提到
struct
,同样,多个相邻字节将被保留。编译器为结构的每个成员的位置计算正确的偏移量(从头开始),并发出具有这些偏移量的机器代码。
机器码中没有
structs
;只有处理内存段的指令就好像它们是成员变量一样。
Array
s 和 struct
s 是用于编写源代码的抽象。
这也有助于理解为什么
sizeof
是 operator,而不是函数...编译器 knows 数组或结构的大小(以字节为单位)以及内置数据类型。 sizeof
运算符指示编译器在生成目标代码时在该点发出该数字。当一个程序正在执行时,sizeof
任何事情都无法确定...
在 C 中,结构成员按照它们在
struct
声明中出现的顺序排列,偏移量递增。第一个成员的偏移量为零,这意味着指向该结构的指针指向第一个成员。