news 2026/5/23 17:57:30

嵌入式C语言阶段复习——核心基础

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
嵌入式C语言阶段复习——核心基础

一、宏定义(#define)

宏定义是预处理指令,用来给常量、表达式或代码片段起别名,预处理阶段会直接替换文本

1、常量宏 #define PI 3.1415926 #define MAX_NUM 100 2. 带参数的宏 #define ADD(a, b) ((a) + (b)) // 加括号避免优先级问题 #define SQUARE(x) ((x) * (x))

宏替换是 “文本替换”,比如SQUARE(3+2)会变成(3+2)*(3+2)(加括号才正确,否则会变成3+2*3+2

宏替换无类型检查,可能会导致出错(比如传非数值类型)

注意结尾不要加分号,否则会导致替换出来的值报错

二、结构体(struct)

结构体用来封装不同类型的数据(比如一个学生的姓名、年龄、成绩)

1、定义结构体类型 struct Student { char name[20]; // 姓名 int age; // 年龄 float score; // 成绩 }; 2、定义结构体变量并初始化 struct Student stu1 = {"张三",19,60.5}; 3. 访问结构体成员(用.操作符) printf("姓名:%s,年龄:%d,成绩:%.1f\n", stu1.name, stu1.age, stu1.score); 4. 修改成员 strcpy(stu1.name, "李四"); // 字符串赋值用strcpy,不能直接stu1.name="李四" stu1.score = 98.0; printf("修改后:%s,%d,%.1f\n", stu1.name, stu1.age, stu1.score); 5. 结构体指针(用->操作符) struct Student *p = &stu1; printf("通过指针访问:%s,%d\n", p->name, p->age);

结构体类型是(struct 结构体名),比如(struct Student),不能省略struct

结构体占用的内存是成员变量的内存之和(可能有内存对齐,比如 char [20]+int+float 通常占 28 字节)

结构体可以嵌套使用

三、共用体(union)

共用体和结构体用法类似,不同在于共用体是共享内存

1、定义共用体 union Data { int i; float f; char c; }; union Data d; printf("共用体大小:%zu 字节\n", sizeof(d)); // 输出4(取最大成员float的大小) 2、赋值int成员 d.i = 100; printf("d.i = %d\n", d.i); // 输出100 // 此时访问f/c会是乱码(内存被覆盖) printf("d.f = %f\n", d.f); // 输出无意义的浮点数 3、赋值float成员(覆盖之前的int内存) d.f = 3.14f; printf("d.f = %.2f\n", d.f); // 输出3.14 printf("d.i = %d\n", d.i); // 输出浮点数3.14对应的整数编码(乱码)

共用体大小 = 最大成员的大小

常用于 “异构数据” 场景(比如存储不同类型但不同时使用的数据),或解析二进制数据(比如拆分整型的字节)。

四、typedef

typedef 用来给已有类型起 “别名”,简化复杂类型的书写(比如结构体、指针、数组)

1、给基本类型起别名 typedef int MyInt; typedef float Score; 2、给结构体起别名(最常用) typedef struct { // 匿名结构体+typedef,直接定义别名 char name[20]; int age; } Student; // 别名是Student,无需写struct Student 3、给指针类型起别名 typedef int* IntPtr; MyInt a = 10; // 等价于int a=10 Score s = 95.5; // 等价于float s=95.5 Student stu = {"王五", 20}; // 直接用Student,不用struct printf("姓名:%s,年龄:%d\n", stu.name, stu.age); IntPtr p = &a; // 等价于int *p=&a printf("*p = %d\n", *p); // 输出10

typedef不创建新类型,只是给现有类型起别名

对比 #define:typedef 有类型检查,#define 只是文本替换

五、枚举(enum)

枚举用来定义一组有名字的常量(比如星期、颜色、状态码),增强代码可读性

1、定义枚举类型(默认从0开始,依次+1) enum Week { MON, // 0 TUE, // 1 WED, // 2 THU, // 3 FRI, // 4 SAT, // 5 SUN // 6 }; 2、自定义枚举值 enum Color { RED = 1, GREEN = 3, BLUE = 5 }; enum Week today = WED; printf("今天是周%d\n", today); // 输出2 enum Color c = GREEN; printf("绿色的枚举值:%d\n", c); // 输出3 if (today == 2) // 枚举本质是整型,可以赋值/比较 { printf("今天是周三\n"); }

枚举常量是整型,可直接用整数赋值(但不建议,失去枚举的意义)

常用于替代魔法数字(比如用SUCCESS=0ERROR=1代替直接写 0/1)

六、位操作

位操作直接操作二进制位,效率极高,常用于硬件控制、数据压缩、权限管理等场景。核心运算符:&(按位与)、|(按位或)、^(按位异或)、~(按位取反)、<<(左移)、>>(右移)

int a = 6; // 二进制:0110 int b = 3; // 二进制:0011 1、按位与(对应位都为1才为1) printf("a&b = %d\n", a & b); // 0010 → 2 2、按位或(对应位有一个1就为1) printf("a|b = %d\n", a | b); // 0111 → 7 3、按位异或(对应位不同为1) printf("a^b = %d\n", a ^ b); // 0101 → 5 4、按位取反(所有位取反,包括符号位) printf("~a = %d\n", ~a); // 补码运算,结果为-7 5、左移(乘以2^n) printf("a<<1 = %d\n", a << 1); // 1100 → 12 6、右移(除以2^n,符号位不变) printf("a>>1 = %d\n", a >> 1); // 0011 → 3

位操作只适用于整型(char、short、int、long)

左移 / 右移不要超出类型的位数(比如 int 是 32 位,左移 32 位未定义)

无符号数右移补 0,有符号数右移补符号位(正数补 0,负数补 1)

七、malloc(动态内存分配)

malloc 用来在堆区动态分配内存,使用后必须用free释放,否则内存泄漏

1、分配单个int的内存 int *p1 = (int*)malloc(sizeof(int)); if (p1 == NULL) { // 必须检查是否分配成功(内存不足时返回NULL) perror("malloc failed"); return 1; } *p1 = 100; printf("*p1 = %d\n", *p1); 2、分配数组内存(5个int) int *arr = (int*)malloc(5 * sizeof(int)); if (arr == NULL) { perror("malloc arr failed"); free(p1); // 先释放已分配的内存 return 1; } // 赋值并遍历 for (int i = 0; i < 5; i++) { arr[i] = i + 1; printf("%d ", arr[i]); // 输出1 2 3 4 5 } printf("\n"); 3、分配结构体内存 typedef struct { char name[20]; int age; } Stu; Stu *stu = (Stu*)malloc(sizeof(Stu)); if (stu == NULL) { perror("malloc stu failed"); free(p1); free(arr); return 1; } strcpy(stu->name, "赵六"); stu->age = 22; printf("姓名:%s,年龄:%d\n", stu->name, stu->age); 4、释放内存(必须释放,且只释放一次) free(p1); free(arr); free(stu); // 释放后指针置NULL,避免野指针 p1 = NULL; arr = NULL; stu = NULL;

malloc(size):参数是要分配的字节数,返回void*需强制类型转换

分配失败返回NULL,必须检查,否则会导致段错误

内存泄漏:分配的内存未释放,程序结束前一直占用堆空间(长期运行的程序会耗光内存)

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/5/21 8:25:04

MedGemma X-Ray实操教程:多语言支持下的中文提问与精准解剖结构识别演示

MedGemma X-Ray实操教程&#xff1a;多语言支持下的中文提问与精准解剖结构识别演示 1. 快速了解MedGemma X-Ray MedGemma X-Ray是一款基于先进大模型技术开发的医疗影像智能分析平台。它就像是给医生和医学生配备了一位AI助手&#xff0c;专门帮助解读胸部X光片。无论你是想…

作者头像 李华
网站建设 2026/5/16 12:05:03

Flowise镜像免配置:Flowise Docker镜像GPU资源限制配置详解

Flowise镜像免配置&#xff1a;Flowise Docker镜像GPU资源限制配置详解 1. 为什么需要GPU资源限制 如果你正在使用Flowise来搭建AI工作流&#xff0c;特别是基于vllm的本地模型推理&#xff0c;那么GPU资源管理就是一个必须面对的问题。想象一下这样的场景&#xff1a;你同时…

作者头像 李华
网站建设 2026/5/21 23:27:34

SenseVoice Small高校科研应用:学术讲座录音→结构化文本→笔记生成

SenseVoice Small高校科研应用&#xff1a;学术讲座录音→结构化文本→笔记生成 1. 项目核心&#xff1a;为科研场景打造的语音转文字利器 想象一下这个场景&#xff1a;你刚听完一场长达两小时的学术讲座&#xff0c;教授语速飞快&#xff0c;内容信息密度极高。你手忙脚乱地…

作者头像 李华
网站建设 2026/5/22 3:41:46

从 iOS 逆向工程方向来防逆向工程,解包、符号分析和资源关联

逆向工程并不是一个抽象概念。 在 iOS 场景里&#xff0c;它是从一个已经签名的 IPA 开始。 攻击者拿到 IPA 后&#xff0c;操作路径相对固定&#xff1a; 解包定位可执行文件提取符号与类信息分析资源与配置拼接业务逻辑 防逆向工程的设计&#xff0c;应当直接针对这些步骤。逆…

作者头像 李华
网站建设 2026/5/19 8:39:49

解锁Switch隐藏能力:从零开始的大气层探索之旅

解锁Switch隐藏能力&#xff1a;从零开始的大气层探索之旅 【免费下载链接】Atmosphere-stable 大气层整合包系统稳定版 项目地址: https://gitcode.com/gh_mirrors/at/Atmosphere-stable 一、认知突破&#xff1a;重新定义你的游戏设备 探索目标&#xff1a;理解自定义…

作者头像 李华
网站建设 2026/5/1 15:30:47

Meixiong Niannian画图引擎与PID控制结合:智能绘画过程优化

Meixiong Niannian画图引擎与PID控制结合&#xff1a;智能绘画过程优化 1. 引言&#xff1a;当AI绘画遇上智能控制 你有没有遇到过这样的情况&#xff1a;用AI画图工具生成图片时&#xff0c;效果时好时坏&#xff0c;参数调来调去就是达不到理想的效果&#xff1f;或者生成过…

作者头像 李华