# 5.6 Struct

今天我想讨论的最后一个话题是struct，stuct非常重要并且在课程的实验中会经常出现。我会稍微介绍一下struct在内存中的结构是怎样。基本上来说，struct在内存中是一段连续的地址，如果我们有一个struct，并且有f1，f2，f3三个字段。

![](https://1977542228-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MHZoT2b_bcLghjAOPsJ%2F-MM4GlTfQa57FRIbUhP2%2F-MM8LCRNuvyydmmGuXOR%2Fimage.png?alt=media\&token=42519273-f9f6-4e61-8800-4e10a67a992a)

当我们创建这样一个struct时，内存中相应的字段会彼此相邻。你可以认为struct像是一个数组，但是里面的不同字段的类型可以不一样。（注，这应该是这一节中最有用的一句话了。。。）

我们可以将struct作为参数传递给函数。

![](https://1977542228-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MHZoT2b_bcLghjAOPsJ%2F-MM4GlTfQa57FRIbUhP2%2F-MM8LYQZbzmPyj44rlOO%2Fimage.png?alt=media\&token=babfc0e6-9414-4d55-a70c-814b8a9d8ae8)

这里有一个名字是Person的struct，它有两个字段。我将这个struct作为参数传递给printPerson并打印相关的信息。我们在printPerson中设置一个断点，当程序运行到函数内部时打印当前的Stack Frame。

![](https://1977542228-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MHZoT2b_bcLghjAOPsJ%2F-MM4GlTfQa57FRIbUhP2%2F-MM8MLjSn1BwV8ZJJCik%2Fimage.png?alt=media\&token=b9ef627e-6f3a-4d2d-93fe-4d31405052cb)

我们可以看到当前函数有一个参数p。打印p可以看到这是struct Person的指针，打印p的反引用可以看到struct的具体内容。

![](https://1977542228-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MHZoT2b_bcLghjAOPsJ%2F-MM4GlTfQa57FRIbUhP2%2F-MM8Mpx3qmdIFbBbEtwS%2Fimage.png?alt=media\&token=5306899d-49c8-4d49-9d21-ea2b5b790ae3)

> 学生提问：是谁创建了编译器来将C代码转换成各种各样的汇编代码，是不同的指令集创建者，还是第三方？
>
> TA：我认为不是指令集的创建者，通常是第三方创建的。你们常见的两大编译器，一个是gcc，这是由GNU基金会维护的；一个是llvm，这个是开源的，你可以查到相应的代码。当一个新的指令集，例如RISC-V，发布之后，我认为会指令集的创建者和编译器的设计者之间会有一些高度合作。简单来说我认为是第三方配合指令集的创建者完成的编译器。RISC-V或许是个例外，因为它是来自于一个研究项目，相应的团队或许自己写了编译器，但是我不认为Intel对于gcc或者llvm有任何输入。
