一 .构造数据类型
(一)基础定义与使用
结构体让我们能自定义复合数据类型,把多个不同类型(如 int
、char
数组等 )的变量 “打包” 成一个整体 。定义形式如下:
struct 结构体名 {
数据类型1 成员变量1;
数据类型2 成员变量2;
// 可继续扩展更多成员
};
像日期、时间、学生信息等场景都能用结构体描述,比如定义学生结构体:
struct student {
char name[32];
char sex;
int age;
int score;
};
(二)变量定义与初始化
-
全部初始化:按成员顺序赋值,如
struct student stu = {"zhangsan", 'm', 18, 90};
,一次性给所有成员设定初始值。 -
局部初始化:只给部分成员赋值,未赋值成员自动为 0(数值类型 )或空(字符数组等 ),示例:
struct student stu = {
.name = "zhangsan",
.score = 90
};
(三)成员访问与存储特性
访问方式:有两种常用方式,通过 .
访问结构体变量成员(如 stu.name
),通过 ->
访问结构体指针成员(如 p->name
,p
是结构体指针 )。 存储规则:结构体要考虑内存对齐,成员需存放在自身类型长度整数倍地址,结构体整体大小是最大成员类型长度的整数倍,这是为了提升 CPU 访问内存效率。
(四)传参与数组应用
传参:传结构体地址更高效,避免大结构体拷贝,函数参数可设为 struct student *prtp
;若传值,参数为 struct student tmp
,但数据量大时不推荐。
结构体数组:元素个数需是常量,用于批量存储同类型结构体数据,初始化可逐个元素赋值,也可指定成员初始化,比如:
struct student s[3] = {
{"zhangsan", 'm', 19, 100},
{"lisi", 'f', 18, 90},
{"wanger", 'm', 19, 60}
};
struct student s[3] = {
[1] = {
.name = "zhangsan",
.score = 90,
},
};
二、共用体:内存共享的灵活类型
(一)核心特性
共用体(联合)与结构体不同,它的成员变量共享同一块内存空间 。定义形式:
union 共用体名 {
数据类型1 成员变量1;
数据类型2 成员变量2;
// 其他成员
};
它常用于节省内存或函数多参数场景,比如判断内存大小端(小端:低地址存低数据位;大端:低地址存高数据位 ),利用共用体实现:
#include <stdio.h>
union s {
char a;
int b;
};
int main(void) {
union s s1;
s1.b = 1;
if(s1.a)
printf("小端存储\n");
else
printf("大端存储\n");
return 0;
}
(二)使用要点
由于成员共享内存,同一时刻只有一个成员数据有效,使用时要注意逻辑控制,避免数据混乱。
三、枚举:常量集合的简洁定义
(一)定义与特性
枚举用于定义一组命名常量,形式为:
enum 枚举类型名 {
常量1,
常量2,
// 更多常量
};
枚举常量默认是 int
类型,第一个常量默认值为 0,后续常量值是前一个常量值 +1 ,也可在定义时手动赋值修改,比如 enum Week {Mon=1, Tue, Wed};
,让 Mon
为 1 ,Tue
为 2 等,方便程序中用有意义的名称代替魔法数字(直接写的无意义数字 )。
(二)应用场景
在表示状态、选项等固定值集合场景好用,像表示星期、性别选项(不过性别用字符或布尔可能更直观 )、错误码分类等,让代码可读性更高,语义更清晰。
四、内存管理:合理分配与释放内存
(一)内存区域划分
C 程序运行时内存分不同区域,像全局变量、静态变量存全局 / 静态存储区,局部变量在栈区,动态分配内存(堆区 )等。堆区内存需要我们手动管理,合理申请和释放。
(二)动态内存函数
malloc
:申请堆区内存,参数是要申请的字节数,返回申请到的内存首地址(void*
类型 ),失败返回 NULL
,示例 int *p = (int*)malloc(10 * sizeof(int));
,申请能存 10 个 int
的空间。free
:释放 malloc
、calloc
等申请的堆内存,参数是要释放的内存地址,释放后指针要及时置 NULL
,避免野指针,如 free(p); p = NULL;
。
(三)内存泄漏问题
若只申请堆内存(用 malloc
等 ),使用完不释放(调用 free
),会导致内存泄漏,程序持续运行时可用内存越来越少,最终可能引发性能问题甚至程序崩溃,务必养成申请后及时释放的习惯。
五、位运算符:高效操作二进制位
(一)常用运算符及含义
&按位与:与0得0,| 按位或:或1置1
^异或:相同为0,相异为1
<<左移:让数据变大,等价于 * 2^n
>>右移:让数据缩小,等价于 / 2^n
^异或:可以实现不使用第三方变量完成两个数的交换
(二)优先级与应用场景
位运算符优先级低于算术、关系等运算符,使用时注意结合括号。在操作硬件寄存器(如设置某一位控制硬件功能 )、数据压缩存储、简单加密等场景常用,比如将一个数的第 n
位置 1 ,可 num |= (1 << n);
;将第 n
位清零,可 num &= ~(1 << n);
。
掌握这些知识,能让我们在 C 语言开发中更灵活处理复杂数据、合理管理内存,写出高效且结构清晰的代码。后续还可结合实际项目,不断深化对它们的运用,提升编程能力 。