Linux C:构造数据类型
目录
一、结构体(struct)
1.1类型定义
1.2 结构体变量定义
1.3 结构体元素初始化
1.4 结构体成员访问
1.5 结构体的存储(内存对齐)
1.6 结构体传参
本文主要记录了C语言中构造数据类型部分的内容,今天暂时只写了结构体的内容,关于结构体的定义、变量定义、初始化、访问、存储和传参问题,很好理解,后续共用体(联合体)和枚举问题将于明天进行更新。
一、结构体(struct)
结构体是一种自定义的复合数据类型,用于将不同类型的数据组合成一个整体,方便对相关数据进行统一管理和操作。
1.1类型定义
struct 结构体名 {
数据类型1 成员变量1;
数据类型2 成员变量2;
数据类型3 成员变量3;
...
};struct date {
int year;
int mon;
int day;
};struct time {
int hour;
int min;
int sec;
};struct student {
char name[32];
char sex;
int age;
int score;
};
基本格式:使用struct
关键字,后跟结构体名,大括号内包含多个成员变量(成员可以是基本数据类型、其他结构体类型等),最后以分号结尾。
- 说明:定义的是结构体类型,并非变量,就像
int
是类型,不是具体变量一样。
1.2 结构体变量定义
定义:存储类型 + 结构体类型 + 变量名。
struct student stu1; //
(定义一个struct student
类型的变量stu1
)
注意:存储类型可省略,默认是自动存储类型(auto)。
1.3 结构体元素初始化
- 全部初始化:按成员顺序依次赋值。
struct student stu = {"zhangsan", 'm', 18, 90};
- 局部初始化:可指定部分成员赋值,未赋值的成员自动为 0(数值型)、空字符(字符型)等默认值。
struct student stu = {.name = "zhangsan", // 指定name成员赋值.score = 90 // 指定score成员赋值 };
1.4 结构体成员访问
- 结构体变量访问成员:使用
.
运算符,格式为 “结构体变量名 . 成员名” - 结构体指针访问成员:使用
->
运算符,格式为 “结构体指针名 -> 成员名”
. :结构体变量类型访问成员变量 .
-> :结构体指针类型访问成员变量 ->结构体访问成员变量最终的类型由成员变量的类型决定
1.5 结构体的存储(内存对齐)
- 结构体成员必须存放在内存地址为自身类型长度整数倍的内存单元中。例如
int
类型成员(占 4 字节)的地址必须是 4 的倍数。 - 结构体的总大小必须为自身最大成员类型长度的整数倍。
-
struct student {char name[32];char sex;int age;int score; };
作用:内存对齐是为了提高 CPU 对内存的访问效率,硬件层面更易读取对齐的地址。
1.6 结构体传参
1.传值方式:函数参数是结构体变量,实参将整个结构体的内容拷贝给形参,缺点是当结构体较大时,拷贝开销大。
void fun(struct student tmp);
2.传地址方式:函数参数是结构体指针,实参将结构体的地址传递给形参,仅拷贝 8 字节(64 位系统指针大小),效率更高,且可通过指针修改原结构体内容。
void fun(struct student *ptmp);
建议:优先使用传地址方式,尤其对于大型结构体;
传地址更好,因为实参将8字节拷贝给形参,避免结构体大空间的拷贝;
二. 共用体(union,联合体)
共用体与结构体的核心区别是所有成员共享同一块内存空间,空间大小等于最大成员的大小,适用于 “同一空间存储不同类型数据” 的场景(如节省内存、判断内存大小端)。
(1)定义与特性
- 定义格式:
union 共用体名 {成员列表};
union Data {int i; // 占4字节float f; // 占4字节char c; // 占1字节 }; // 总大小为4字节(最大成员int和float均为4字节)
- 特性:任一时刻只有一个成员有效,修改一个成员会覆盖其他成员的值。
(2)应用:判断内存大小端
内存大小端是指多字节数据在内存中的存储顺序:
- 小端存储:低地址存储数据的低字节(如 0x12345678,低地址存 0x78);
- 大端存储:低地址存储数据的高字节(如 0x12345678,低地址存 0x12)。
利用共用体判断:
#include <stdio.h>
union CheckEndian {int num; // 4字节char c; // 1字节(共享num的低地址空间)
};int main() {union CheckEndian u;u.num = 0x12345678;if (u.c == 0x78) {printf("小端存储\n"); // 低地址存低字节0x78} else if (u.c == 0x12) {printf("大端存储\n"); // 低地址存高字节0x12}return 0;
}
三. 枚举(enum)
枚举用于定义一组命名的常量,使代码更具可读性,适用于表示 “有限的状态或选项”(如颜色、星期、错误码等)
(1)定义与特性
- 定义格式:
enum 枚举名 {常量1, 常量2, ...};
enum Weekday {MON, // 默认为0TUE, // 默认为1(前一个+1)WED = 5, // 手动赋值为5THU // 自动为6(5+1) };
- 特性:所有枚举常量均为 int 类型,不能直接赋值给其他类型(需强制转换)。
(2)应用场景
- 状态标识:如
enum Status {SUCCESS, ERROR, PENDING};
,比直接用 0、1、2 更易读。 - 限制变量取值:
enum Color {RED, GREEN, BLUE} c; c = RED;
(只能取枚举中的值)。