嵌入式学习14
·
C语言进阶:二维字符数组传参、指针数组传参、结构体/共用体/枚举(构造类型)详解
前言
今天系统学习了多行字符串两种存储结构的函数传参:二维字符数组、字符指针数组,同时完整梳理C语言三大构造数据类型结构体、共用体、枚举。这部分是C语言中指针与复合类型结合的高频难点,面试、笔试常考,本文整理核心知识点、使用规范、高频易错点,方便复习收藏。
一、二维字符数组传参(多行连续字符串)
1. 适用场景
需要固定每行字符串最大长度,允许修改每行字符,内存连续存储,例如存储学生姓名、固定长度文本。
定义示例:
// 5行字符串,每行最多32字节(包含\0结束符)
char str[5][32] = {"apple", "banana", "orange", "pear", "grape"};
2. 函数传参标准写法
二维数组传参列数不可省略,底层为数组指针 char (*p)[列数]:
// 数组指针标准形式
void PrintStrArr(char (*pstr)[32], int row_cnt);
// 等价语法糖写法
void PrintStrArr(char pstr[][32], int row_cnt);
调用直接传入数组名:
PrintStrArr(str, 5);
3. 底层原理
数组名str代表一整行的地址,str+1会一次性偏移32字节,跳转到下一行字符串;函数内访问元素pstr[i][j]和外部完全通用。
4. 踩坑提醒
- 不能使用
char**接收二维字符数组,类型不匹配,运行直接崩溃; - 传参必须写明列长度,否则编译器无法计算行偏移,编译报错。
二、指针数组传参(二级指针char**,字符串常量数组)
1. 适用场景
存储静态字符串常量,每行长度不统一,节省内存,多用于菜单、英文单词表、固定提示文本。
定义示例:
// 数组存储5个字符串指针,字符串存只读常量区
char *p_str[5] = {"Monday", "Tuesday", "Wednesday", "Thursday", "Friday"};
2. 函数传参标准写法
指针数组本质是一级指针数组,传参使用二级指针char**接收:
void PrintPointArr(char **ppstr, int len);
调用方式:
PrintPointArr(p_str, 5);
3. 两种字符串数组核心区分
| 存储方式 | 传参类型 | 字符可修改 | 内存特点 |
|---|---|---|---|
| char arr[N][M] | char (*)[M] | 支持修改每行字符 | 连续二维内存,固定行宽 |
| char *arr[N] | char** | 常量字符串不可修改 | 仅存储指针,字符串独立存放 |
4. 高频易错
指针数组指向"xxx"常量字符串时,禁止修改字符:p_str[0][0]='X'会访问只读内存,触发段错误。
三、C语言构造数据类型 struct / union / enum
3.1 结构体 struct(开发最常用)
结构体封装不同类型成员,用来描述一组关联属性,学生信息、日期、坐标都依赖结构体实现。
- 定义与初始化
// 定义学生结构体类型
struct Student {
char name[20];
int age;
float score;
};
// 指定成员初始化(推荐)
struct Student s = {.name = "WangWu", .age = 19, .score = 94};
- 成员访问规则
- 普通结构体变量:
.访问s.age = 20; - 结构体指针变量:
->访问struct Student *p = &s; p->score = 96;
- 内存对齐规则(笔试必考)
- 成员地址必须是自身类型字节整数倍;
- 结构体总大小 = 最大基础类型字节的整数倍;
#pragma pack(1)关闭对齐,按1字节紧凑存储。
- 函数传参规范
优先使用结构体指针地址传递,减少大内存拷贝开销,同时支持修改外部原始数据。 - 易错点
结构体指针误用.;递归结构体不能定义自身变量,只能定义自身指针;忽略内存对齐导致空间计算错误。
3.2 共用体 union
所有成员共享同一块内存,空间大小等于最大成员占用字节,同一时间仅一个成员有效,多用于硬件数据解析、类型转换。
union Temp {
int num;
char buf[4];
};
赋值num后,buf数组数据会被覆盖,反之同理。
3.3 枚举 enum
批量定义int类型常量,限制变量合法取值,可读性优于#define宏,自带类型校验。
enum Color {RED, GREEN, BLUE=10};
enum Color c = RED;
四、今日全部易错点总结
- 传参混淆二维字符数组(数组指针)与指针数组(二级指针),类型不匹配程序崩溃;
- 结构体指针使用
.访问成员,语法报错; - 字符串未预留
\0结束符,数组越界输出乱码; - 修改指针数组指向的常量字符串,触发段错误;
- 计算结构体大小时忽略内存对齐规则;
- 共用体同时读写多个成员,数据相互覆盖错乱;
- 二维数组传参省略列长度,编译直接报错。
五、学习总结
- 多行字符串分两种存储:二维字符数组(可修改、固定宽度)、字符指针数组(静态常量、省内存),对应两套不同传参方案,不能混用;
- 指针是数组传参核心难点,分清数组指针、指针数组、一级/二级指针的区别是关键;
- 构造类型中结构体是业务开发核心,共用体、枚举作为辅助工具;结构体指针传参、内存对齐是笔试面试高频考点;
- 所有字符串操作必须重视
\0结束符,数组访问严格控制边界,避免内存越界问题。
更多推荐
所有评论(0)