综合

struct是什么意思

时间:2010-12-5 17:23:32  作者:百科   来源:百科  查看:  评论:0
内容摘要:写C代码的人迟早会撞上struct。它不复杂,但教科书的讲法常常让人绕远路。先看一段真实的代码: struct Point { int x; int y; }; struct Point p1; p1

写C代码的什意思人迟早会撞上struct。它不复杂,什意思但教科书的什意思讲法常常让人绕远路。先看一段真实的什意思代码:

struct Point {  int x; int y; }; struct Point p1; p1.x = 3; p1.y = 7; 

这就是struct最朴素的样子。它把几个变量捆在一起,什意思给这捆东西起个名字叫Point。什意思之后你可以用p1.x、什意思p1.y来访问里面的什意思成员。没有魔法,什意思没有运行时开销,什意思编译器只是什意思帮你算好偏移量——x在地址+0的位置,y在地址+4的什意思位置(假设int是4字节)。

很多人第一次学struct的什意思时候会问:这跟数组有什么区别?数组要求所有元素类型相同,struct不要求。什意思数组用下标访问,什意思struct用名字访问。更关键的是,数组的语义是“一堆同样的东西”,struct的语义是“一个东西的几个组成部分”。Point是一个点,它有x和y两个坐标,而不是“两个int组成的列表”。这个区别听起来像文字游戏,但它决定了你什么时候该用哪个。

C语言里的struct有个让初学者困惑的地方:声明和定义是分开的。

struct Point; // 声明,告诉编译器有这么个东西 struct Point {  int x; int y; }; // 定义,告诉编译器它长什么样 

你可以先声明一个struct,在别的地方再定义它。这跟函数的前向声明是一个道理。实际写代码的时候,struct的定义通常放在头文件里,因为多个.c文件都需要知道它的布局。

还有一个经典坑:typedef。

typedef struct {  int x; int y; } Point; 

这样写之后,你可以直接用Point p1;,不用每次写struct Point p1;。C++里struct默认就带了这个效果,所以C++程序员转回C的时候经常忘记加struct关键字,然后被编译器骂。

内存对齐是struct里最容易被忽视的细节。看这个:

struct A {  char c; int i; }; 

sizeof(struct A)在大多数平台上不是5,而是8。因为编译器会在c后面塞3个字节的填充,让i的地址对齐到4的倍数。你可以用#pragma pack或者__attribute__((packed))来关掉对齐,但那样访问速度会变慢,某些架构上甚至直接崩溃。我见过有人写网络协议解析的时候忘了这回事,结构体发出去对方收到的字节全错位了。

struct可以嵌套。一个struct的成员可以是另一个struct:

struct Rectangle {  struct Point topLeft; struct Point bottomRight; }; 

访问的时候就是rect.topLeft.x。层级深了会很难看,所以C程序员经常用指针来简化——rect->topLeft.x,或者干脆把常用的字段提出来。

指针和struct搭配是C里最常见的组合。链表、树、图,这些数据结构全靠struct里放一个指向自身类型的指针来实现:

struct Node {  int value; struct Node *next; }; 

注意这里struct Node *next是合法的,虽然Node还没定义完。编译器只需要知道struct Node是个类型名,指针的大小是固定的,具体布局可以稍后再说。这是C语言设计里比较聪明的一处。

位域是struct的另一个用法,虽然日常写业务代码不太碰:

struct Flags {  unsigned int a : 1; unsigned int b : 2; unsigned int c : 5; }; 

冒号后面的数字表示这个成员占几个bit。整个struct可能只占一个字节。嵌入式开发里读写硬件寄存器的时候经常这么干。但位域的布局依赖编译器和平台,跨平台代码里最好别用。

最后说一个实际观察:很多C项目里struct的定义位置很讲究。如果某个struct只在单个.c文件里用,就放在那个文件的顶部。如果多个文件共享,就放头文件。头文件里的struct定义要尽量小,因为每个包含它的.c文件都会看到完整定义。有人喜欢用不透明指针——头文件里只写typedef struct Foo Foo;,具体定义藏在.c里。这样修改struct的成员不需要重新编译所有依赖它的文件。代价是别人不能直接访问成员,得通过函数。值不值得,看项目规模。

struct说到底就是内存布局的描述。你告诉编译器“这块内存里,前4个字节是x,后4个字节是y”,编译器就按这个规则帮你生成访问代码。没有继承,没有虚函数,没有访问控制。简单,但够用。

最近更新
热门排行
copyright © 2026 powered by 烟消火灭网   sitemap