嵌软八股大全5 - C 结构体、联合体和枚举
结构体
1、基本概念
struct
是结构体,允许存储不同类型的数据项,大小等于所有成员大小的总和 + 填充字节
1.1、创建结构体
C 中结构体成员默认公有,权限不可修改
- struct 关键词 + 结构体标签 node + 参数列表 + 结构体变量 list_node
- 使用 typedef 定义结构体别名
#include <stdio.h>
/* 方法一 */
struct node
{
int data;
struct node* next;
}list_node;
/* 方法二 */
struct node
{
int data;
struct node* next;
};
/* 方法三 */
struct
{
int data;
struct node* next;
}list_node;
/* 方法四 */
typedef struct node
{
int data;
struct node* next;
}list_node;
int main(void)
{
/* 方法一、三 */
list_node.data=22;
/* 方法二 */
struct node a;
a.data = 33;
/* 方法四 */
list_node b;
b.data = 44;
}
结构体类型定义时不会为其分配内存,只有当执行 list_node b;
才会为其分配内存
1.2、求结构体所占字节数
- 成员变量需要满足
对齐数
- 结构体总大小为
最大对齐数
的整数倍
1.2.1、内存对齐
对齐数的概念
- 变量的对齐数决定了该变量在内存中的存放位置只能是对齐数的整数倍
计算结构体内每个变量的对齐数
- 普通变量对齐数 align_1 = min(默认对齐数,sizeof(变量)),默认对齐数一般为 8
- 嵌套结构体对齐数 align_2 = max(sizeof(变量1),sizeof(变量2),...,sizeof(变量n))
需要满足结构体总大小为最大对齐数的整数倍
- sizeof(struct name) = n * max(align_1, align_2),其中 n 为正整数
举几个例子
#include "stdio.h"
struct S1
{
char c1;
int i;
char c2;
};
int main(void)
{
printf("sizeof(struct S1): %llu\n", sizeof(struct S1));
return 0;
}
output:
sizeof(struct S1): 12
根据结构体 S1 定义得出以下信息:
- c1 对齐数为 1 ,i 对齐数为 4 ,c2 对齐数为 1 ,最大对齐数为 4
- sizeof(struct S1) = n * 4
#include "stdio.h"
struct S2
{
char c1;
char c2;
int i;
};
int main(void)
{
printf("sizeof(struct S2): %llu\n", sizeof(struct S2));
return 0;
}
output:
sizeof(struct S2): 8
根据结构体 S2 定义得出以下信息:
- c1 对齐数为 1,c2 对齐数为 1 ,i 对齐数为 4 ,最大对齐数为 4
- sizeof(struct S1) = n * 4
#include "stdio.h"
struct S3
{
double d;
char c;
int i;
};
struct S4
{
char c1;
struct S3 s3;
double d1;
};
int main(void)
{
printf("sizeof(struct S4): %llu\n", sizeof(struct S4));
return 0;
}
output:
sizeof(struct S4): 32
根据结构体 S3 和 S4 定义得出以下信息:
- c1 对齐数为 1,嵌套结构体 s3 对齐数为 8,d1 对齐数为 8,最大对齐数为 8
- sizeof(struct S1) = n * 8
1.2.2、为什么存在内存对齐?
- 平台问题:不是所有的硬件平台都能访问任意地址上的任意数据的
- 性能问题:内存对齐的数据,处理器取数据访问的次数要少,简单说是CPU 访问数据的效率问题
1.2.3、修改默认对齐数
使用如下预编译指令修改默认对齐数为 1
#pragma pack(1)
再次尝试 6.2.1 小节第 1 个例子,S1 结构体占内存字节数理论值应为 6
#include "stdio.h"
#pragma pack(1)
struct S1
{
char c1;
int i;
char c2;
};
int main(void)
{
printf("sizeof(struct S1):
剩余60%内容,订阅专栏后可继续查看/也可单篇购买
嵌入式软件名企笔/面试真题合集 文章被收录于专栏
欢迎来到我的专栏,在这里,我将整理并分享2024年各大企业的真实笔试/面试真题,同时还整理了嵌入式软件相关的八股知识。专栏内容涵盖C/C++基础、嵌软常见通信协议、ARM、FreeRTOS、Linux OS相关问题汇总,希望能帮助求职者了解考试趋势和嵌入式常见考点。无论你是准备面试,还是希望提升自己的专业知识,这里都能为你提供宝贵的参考和学习资源。