news 2026/7/15 18:41:26

C语言基础回顾(2026/7/15)

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
C语言基础回顾(2026/7/15)

目录

第一阶段:C 基础

<一>:数据类型

1:基础架构及变量输出

2:变量定义及初始化

3:变量输入scanf

4:常量const

5:浮点数float/double

①:认识浮点数

②:浮点数的运算

③:格式化输出

6:字符变量char

<二>:运算符

1. 算术运算符

2. 关系运算符

3. 逻辑运算符

4. 赋值运算符

5. 条件运算符(三元)

6. 自增自减

7. 运算符优先级

<三>:输入输出

①:printf — 格式化输出

②:scanf — 格式化输入

③:getchar / putchar — 单字符输入输出

<四>:控制流结构

①:if-else

②:else if

③:switch-case

④:for 循环

⑤:while 循环

⑥:do-while循环

⑦:break 和 continue

⑧:goto


第一阶段:C 基础

<一>:数据类型

1:基础架构及变量输出

#include <stdio.h> int main() { printf("Hello, World!\n"); }

2:变量定义及初始化

#include <stdio.h> int main(void) { int a = 10; int b = 20; int c = a + b; printf("a = %d\n", a); printf("b = %d\n", b); printf("c = %d\n", c); return 0; }

3:变量输入scanf

#include <stdio.h> int main(void) { int a; int b; int c; printf("请输入两个整数:"); scanf("%d %d", &a, &b); c = a + b; printf("a = %d\n", a); printf("b = %d\n", b); printf("c = %d\n", c); return 0; }

scanf()的格式字符串决定了它如何解析输入,你写什么格式,它就按照什么规则去匹配。

scanf("%d %d", &a, &b); 这里的占位符%d %d,中间没有任何符号隔开,

很多初学者误认为:必须输入一个空格,其实不是,它代表跳过所有空白字符,

因此空格,Tab,或者换行输入数值,均可运行。

scanf("%d ,%d", &a, &b); 这里的占位符%d %d,中间用了一个逗号隔开,

因此输入数值时,需要输入,比如10,随后用逗号隔开,再输入另外一个数值,比如20

即 10,20

4:常量const

const int a; 和int const a; 是两种不同的写法,第二种写法少见,但第一个等价

在指针后面会遇到,不过初学基础用法,学习const int a即可。

5:浮点数float/double

①:认识浮点数

②:浮点数的运算

③:格式化输出

举个例子:
printf("%5.4f\n", a);

数值3.1415,要求保留 4位小数,3.1415的字符:3.1415,一共 6​ 个字符

printf("%5.4f\n", a);你要求的总宽度是5。但是内容本身已经占了6​ 个位置(比5大)。

规则触发:当要求的宽度 < 实际内容的宽度时,宽度限制失效,内容完整输出。

结果3.1415(前面没有空格)。

printf("%8.4f\n", a);你要求的总宽度是8。但是内容本身已经占了6​ 个位置(比8小)。

结果␣␣3.1415(前面有两个空格)。

6:字符变量char



<二>:运算符

1. 算术运算符

+ - * / %

/要注意的东西之前说过了:整数/整数 = 整数(截断)。%只能用于整数。

嵌入式里几乎全是整数运算,浮点运算要么避免、要么用硬件 FPU。

2. 关系运算符

> < >= <= == !=

==(等于)和=(赋值)是最容易写错的:

if (x == 5) // 判断 if (x = 5) // 赋值!= 5,非 0 就是 true,条件永远成立

一个防御写法:常量放左边if (5 == x),写错成if (5 = x)编译器直接报错。不过现在编译器对if (x = 5)一般也会警告。

3. 逻辑运算符

&& // 与:两边都为真才为真 || // 或:一边为真就为真 ! // 非:取反

短路求值&&左边为假,右边就不算了;||左边为真,右边就不算了。

if (ptr != NULL && ptr->value == 10) // ptr 为空时不会去访问 ptr->value

嵌入式里也常用!翻转一个标志位:

flag = !flag; // 0 变 1,1 变 0

4. 赋值运算符

= += -= *= /= %=

这几个我比较会

&= |= ^= <<= >>=

这几个不知道啥意思


&=:按位与赋值,a = a & b,清零某些位 / 保留特定位

|=:按位或赋值,a = a | b,清零某些位 / 保留特定位

^=是按位异或,a ^= b,等价于a = a ^ b,翻转寄存器的某一位

<<=: 左移赋值,a = a << b,a <<= 2;// a 左移2位

>>=:右移赋值,a = a >> b,a >>= 1;// a 右移1位
~:按位取非

复合赋值就一个意思:x += 5等价于x = x + 5。嵌入式里位运算的复合赋值极为常用:

REG |= (1 << 3); // 置位 REG &= ~(1 << 3); // 清零

举例:a=0000 0001左移3位0000 1000得0x08,第3位(bit3)为1,其余位为0

~是按位取反,~a表示每一位反过来得11110111,除了bit3是0,其他位都是1

5. 条件运算符(三元)

max = (a > b) ? a : b; // 条件 ? 真值 : 假值

if (state) { PORTA |= (1 << 3); // 置位 } else { PORTA &= ~(1 << 3); // 清位 }
PORTA = state ? (PORTA | (1 << 3)) : (PORTA & ~(1 << 3));

嵌套可读性会崩,不建议套娃。

6. 自增自减

int a = 5; int b = a++; // b = 5, a = 6 (先用后加) int c = ++a; // c = 7, a = 7 (先加后用)

单独写一条语句时(i++;)没区别。但和别的运算混在一起时要注意,嵌入式里常见的坑:

7. 运算符优先级

不需要全背,记住三条:

优先级运算符
最高()[]->.
中间*/%>+-><<>>> 比较 > 逻辑
最低=

不确定就加括号。嵌入式代码可靠性第一,多写一对括号不丢人:

if ((a & MASK) == VALUE) // & 优先级比 == 低,不加括号是 if (a & (MASK == VALUE))

<三>:输入输出

①:printf— 格式化输出

格式符含义嵌入式场景
%d有符号十进制 int普通数值
%u无符号十进制计数器、时间戳(unsigned 是嵌入式常态)
%x/%X十六进制(小写/大写)查看寄存器值、地址,嵌入式最常用
%c单个字符命令解析
%s字符串日志输出
%ffloat / double传感器数值
%p指针地址调试时查看指针值
%%打印一个%

修饰符回顾(上次讲的):

printf("%08x\n", reg); // 08 = 总宽 8,不够前面补 0 → 0000a3f1 printf("0x%02X\n", val); // 0xA3 这种格式,嵌入式打印寄存器非常常用

②:scanf— 格式化输入

int n; scanf("%d", &n); // 一定要加 &(取地址) scanf("%x", &n); // 按十六进制读 char c; scanf(" %c", &c); // %c 前面空格很重要!跳过上次留下的 \n

嵌入式里scanf用得不多,更常见的是从串口中断读字符自己拼。但学 C 阶段知道就行。

③:getchar/putchar— 单字符输入输出

char c = getchar(); // 读一个字符 putchar(c); // 写一个字符

嵌入式里这俩通常被重定向到串口:

// 重定向 putchar 后,printf 就可以走串口输出了 int fputc(int ch, FILE *f) { while (!(USART1->SR & USART_SR_TXE)); // 等发送缓冲区空 USART1->DR = ch; return ch; }

<四>:控制流结构

①:if-else

if (条件) { ... } else if (条件) { ... } else { ... }

嵌入式应用:轮询标志位、判断状态。

if (USART1->SR & USART_SR_RXNE) { // 接收非空 = 来数据了 data = USART1->DR; }

②:else if

你想要的逻辑是"互斥"的——满足一个就不再往下看。这时候就需要else if

只是不断缩进太难看了,所以把else { if ... }的括号和缩进去掉,写成else if,C 语言里所有人都这么写。

执行逻辑:从上到下,找到一个满足的就执行,然后跳过后面所有的else ifelse

③:switch-case

多个条件比较同一个值时,比写一堆if-else更清晰:

switch (cmd) { case 0x01: led_on(); break; // 忘记 break 会"穿透"到下一个 case case 0x02: led_off(); break; default: // 没匹配到时走这里 send_error(); break; }

嵌入式里的典型用法:命令解析、状态机。

switch (state) { case STATE_IDLE: if (start_condition) state = STATE_RUNNING; break; case STATE_RUNNING: do_work(); if (done) state = STATE_DONE; break; case STATE_DONE: cleanup(); state = STATE_IDLE; break; }

注意:case后面的值必须是整数常量。字符串不能直接放case

④:for循环

for (初始化; 条件; 每次循环后执行) { ... }
for (int i = 0; i < 10; i++) { printf("%d\n", i); }

三个部分都可以省略(极端简化):

for (;;) { // 等价于 while(1),嵌入式主循环标配 ... }

实际上大多数嵌入式main函数长这样:

int main(void) { hardware_init(); while (1) { // 或 for(;;) read_sensors(); process_data(); update_outputs(); } }

for循环执行次数详解

⑤:while循环

while (条件) { ... } // 条件为假时一次都不执行

嵌入式里等待硬件就绪:

while (!(USART1->SR & USART_SR_TC)) { ; // 空循环,等待发送完成。注意要加 volatile! }

⑥:do-while循环

do { ... } while (条件); // 无论如何至少跑一次

用得比while少,多用在宏定义里(保证宏像一条语句一样安全):

#define LED_TOGGLE() do { LED_ON(); delay(100); LED_OFF(); } while(0)

⑦:breakcontinue

break; // 直接跳出当前循环 continue; // 跳过本次循环剩下的部分,开始下一次

break也用于switch里跳出(不要混淆——break只跳出最内层的一层循环或 switch)。

⑧:goto

唯一合理的用法:统一出错处理,避免到处写重复的清理代码。

void process(void) { if (init_step1() != OK) goto error; if (init_step2() != OK) goto error; if (init_step3() != OK) goto error; do_work(); return; error: cleanup_all(); set_error_flag(); }

规则:只往前跳、跳到一个统一的出口标签。不要往回跳,不要乱飞——那样确实会写出意大利面条代码。

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

YOLOv12改进策略【卷积层】| arXiv 2025 YOLO-Master中的稀疏混合专家ES-MoE 动态路由提适配 + 稀疏激活降延迟,突破精度-效率权衡

一、本文介绍 本文记录的是利用ES-MoE 模块改进 YOLOv12 的骨干网络特征提取部分。 ES-MoE(Efficient Sparse Mixture-of-Experts)通过多尺度专家组与分阶段动态路由机制结合,实现YOLOv12对不同复杂度场景的自适应计算资源分配。本文利用ES-MoE模块,通过多尺度专家组(不…

作者头像 李华
网站建设 2026/7/15 18:39:34

【小程序课程设计/毕业设计】基于 SpringBoot + 微信小程序的游记分享互动平台 基于微信小程序的热门旅游目的地推荐系统的设计与实现【附源码、数据库、万字文档】

博主介绍&#xff1a;✌️码农一枚 &#xff0c;专注于大学生项目实战开发、讲解和毕业&#x1f6a2;文撰写修改等。全栈领域优质创作者&#xff0c;博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战 ✌️技术范围&#xff1a;&am…

作者头像 李华
网站建设 2026/7/15 18:39:23

mba研究生论文应该怎么写

mba研究生论文应该怎么写 深夜11点&#xff0c;你对着电脑屏幕&#xff0c;第N次修改论文框架。导师那句“选题太泛&#xff0c;缺乏管理深度”的批注像根刺&#xff0c;扎在心上。白天要处理KPI&#xff0c;晚上要哄睡孩子&#xff0c;留给论文的时间被挤压得只剩碎片——这大…

作者头像 李华
网站建设 2026/7/15 18:36:48

ROS2组件化实战:进程内模块化部署与热更新

ROS2 的组件化&#xff08;Componentization&#xff09;机制&#xff0c;是它区别于 ROS1 最显著、也最实用的架构升级之一。很多刚从 ROS1 转过来的朋友&#xff0c;第一反应是&#xff1a;“节点不就是进程吗&#xff1f;为什么还要搞‘组件’&#xff1f;”——这恰恰是理解…

作者头像 李华
网站建设 2026/7/15 18:35:32

2026小程序开发公司排行:靠谱开发企业榜单参考

小程序开发公司排行最容易看偏的地方&#xff0c;是把不同路线的服务商放在同一张表里直接比较。SaaS 平台、低代码工具、定制开发、电商系统和网站工具解决的问题并不完全一样&#xff0c;单看名气或报价很难判断是否适合。更稳妥的判断方式&#xff0c;是先看企业当前处在哪类…

作者头像 李华