数据的存储与运算
🎯 一句话秒杀:数据类型决定了数据在内存中占多少空间、怎么存、能做什么运算;运算符则是告诉计算机"这些数据要怎么算"的指令符号。
① 📊【历年真题考情】
本章(运算符与表达式)在广东专升本计算机统考中的位置:
| 项目 | 结论 |
|---|---|
| 出题频次 | ★★★★☆(3/4 年必出,C语言基础模块内高频稳定考点) |
| 常考题型 | 单选(2024 单选4/5/7、2026 单选1/2)、判断(2023 判断3)、填空(关联)、计算题(/ % 数位分离) |
| 预估分值 | 5~15 分 / 200 分(约 3%~8%),C语言基础模块合计约 40-45 分 |
| 考纲归属 | 2026 考纲「C 语言基础」模块(程序结构、数据类型、运算符、输入输出) |
考场真实出现过的高频题:
- 2026 单选1:
7 / 2 + 7 % 2的值 → 整数除法截断 + 取余 - 2026 单选2:
x += x++ + 1→ 未定义行为 - 2024 单选4:
10 != 9的值 → 关系表达式真值恒为 1 - 2024 单选5:值为 3 的表达式 → 整数除法 + 取余
- 2024 单选7:
(a, b)逗号表达式 → 取末值 - 2023 判断3:
if 表达式只能是逻辑表达式→ 错
🎯 学习目标:学完本章,你能手算任何运算符表达式的值(含自增自减、逗号、逻辑短路),并能识别"未定义行为"陷阱——这正是广东真题的丢分重灾区。
② 🗣️【零基础大白话引入】
运算符是什么? 想象你是一个厨师,数据就是食材(土豆、牛肉、鸡蛋),而运算符就是厨房里的工具(菜刀、锅、搅拌器)。没有工具,食材只能堆着;有了工具,你才能"切"(运算)、"煮"(运算)、"炒"(运算),最终做出一道菜(表达式的值)。
举个例子:
3 + 5:+就是"加法工具",把 3 和 5 两个数字"炒"在一起,出锅一盘8。7 / 2:/是"除法工具"。注意!在 C 语言厨房里,两个整数相除,锅会直接丢掉小数部分——7 / 2出来的是3,不是3.5!这就像做"整数份"的菜,7 个苹果 2 人分,每人只能拿 3 个整的,剩下的 1 个就是7 % 2(取余)——% 就是"分剩几个"的工具。a++:++是"计数器工具",每次用完食材后自动把"库存数"加 1。
学完能解决什么问题?
- 看懂真题选择题里"这个表达式值是多少"——直接白拿 3~6 分
- 写程序时正确地让计算机算数(判断、循环、累加都离不开它)
- 避开最大的坑:知道什么时候"算出来的答案是骗人的"(未定义行为)——2026 真题专门考了这个
💡 记住:C 语言里一切都是"表达式",表达式的最终结果是"一个值"。本章就是教你:拿到一串符号,怎么一步步算出那个"值"。
③ 📖【正式核心知识点讲解】
本章知识点 = 考纲要求 + 历年真题实际考过的内容。真题从未考察、考纲不作要求的内容已剔除(如位运算的复杂应用仅保留了解级)。
3.1 数据类型全家福(先认识"食材")
C数据类型
├── 基本类型
│ ├── 整型:int, short, long, long long
│ ├── 字符型:char(本质是整型)
│ ├── 浮点型:float, double
│ └── 布尔型:_Bool(C99新增)
├── 构造类型
│ ├── 数组
│ ├── 结构体 struct
│ ├── 共用体 union
│ └── 枚举 enum
├── 指针类型:*
└── 空类型:void3.2 整型数据(重点)
整型分类
| 类型 | 关键字 | 字节数(32位) | 取值范围 |
|---|---|---|---|
| 基本整型 | int | 4 | |
| 短整型 | short | 2 | |
| 长整型 | long | 4 | |
| 长长整型 | long long | 8 | |
| 无符号整型 | unsigned int | 4 |
🚨 红牌警告
sizeof(int)在不同的编译器中可能不同——16位系统是2字节,32/64位系统是4字节 但考试默认:int占4字节,short占2字节
有符号 vs 无符号
signed int a = -10; // 可以存负数(最高位表示符号)
unsigned int b = 10; // 只能存正数(最高位参与数值)存储方式:
- 正数:原码直接存储
- 负数:补码存储(原码→取反→加1)
| 数值 | 原码 | 反码 | 补码 |
|---|---|---|---|
| +5 | 0000 0101 | 0000 0101 | 0000 0101 |
| -5 | 1000 0101 | 1111 1010 | 1111 1011 |
🔑 秒杀秘籍
为什么负数用补码存储? 因为可以让加减法用同一套电路实现! 例:
→ 溢出舍去→ 0000 0001 = 1✅
3.3 字符型数据
char ch = 'A'; // 字符用单引号
printf("%c", ch); // 输出字符 → A
printf("%d", ch); // 输出ASCII码 → 65常见ASCII码(必须背!)
| 字符 | ASCII码(十进制) |
|---|---|
'0' | 48 |
'A' | 65 |
'a' | 97 |
'\n' | 10(换行) |
'\0' | 0(字符串结束标志) |
🚨 红牌警告
'0'≠ 0 ≠'\0''0'= ASCII 48,0= 整型0,'\0'= ASCII 0(字符串结束符) 大小写转换:'A' + 32 = 'a'✅
3.4 浮点型数据
| 类型 | 字节 | 有效位数 | 取值范围 |
|---|---|---|---|
float | 4 | 6~7位 | |
double | 8 | 15~16位 |
🚨 红牌警告
浮点数不能直接用
==比较相等! 因为浮点运算有精度误差 ✅ 正确做法:if (fabs(a - b) < 1e-6)
3.5 运算符与表达式(本章核心 · 必考)
3.5.1 运算符优先级(必考!)
| 优先级 | 运算符 | 结合性 |
|---|---|---|
| 1(最高) | () [] . -> | 左→右 |
| 2 | ! ~ ++ -- +(正) -(负) *(指针) &(取址) sizeof | 右→左 |
| 3 | * / % | 左→右 |
| 4 | + - | 左→右 |
| 5 | << >> | 左→右 |
| 6 | < <= > >= | 左→右 |
| 7 | == != | 左→右 |
| 8 | & (按位与) | 左→右 |
| 9 | ^ (按位异或) | 左→右 |
| 10 | | (按位或) | 左→右 |
| 11 | && (逻辑与) | 左→右 |
| 12 | || (逻辑或) | 左→右 |
| 13(最低) | = += -= 等赋值 | 右→左 |
flowchart TD
A["① 最高:() [] . -><br/>括号/数组/成员"]
B["② 单目:! ~ ++ -- sizeof<br/>右结合"]
C["③ 乘除模:* / %"]
D["④ 加减:+ -"]
E["⑤ 关系:< <= > >="]
F["⑥ 相等:== !="]
G["⑦ 逻辑:&& → ||"]
H["⑧ 最低:= += -= 赋值<br/>右结合"]
A --> B --> C --> D --> E --> F --> G --> H
style A fill:#2F6B9E,color:#fff
style B fill:#C0392B,color:#fff
style C fill:#E67E22,color:#fff
style D fill:#E67E22,color:#fff
style G fill:#27AE60,color:#fff
style H fill:#8E44AD,color:#fff📌 只需记 4 个:①
()最高 ② 单目 ③* / %>+ -④ 赋值=最低。
🔑 秒杀秘籍
记口诀:单目右结合,赋值右结合,其他左结合 单目运算符(
!~++--sizeof)是从右到左结合 赋值运算符(=+=等)也是从右到左零基础先只记 4 个最重要的:①
()最高 ② 单目! ++ -- sizeof次高 ③* / %高于+ -④ 赋值=最低
3.5.2 整数除法截断(2026/2024 真题双考 · 必拿分)
两个整数相除,结果直接丢掉小数部分(截断,不四舍五入)
int a = 7, b = 2;
printf("%d\n", a / b); // 输出 3(不是 3.5!)
printf("%d\n", a % b); // 输出 1(7 ÷ 2 = 3 余 1)推理过程:
7 / 2:7 里能装下 3 个完整的 2(3×2=6),剩 7-6=1 → 商 3,余 17 % 2:取余数 → 1- 所以
7 / 2 + 7 % 2 = 3 + 1 = 4✅(2026 真题原题)
🚨 关键区别:如果有一个数是小数(如
7.0 / 2),结果是3.5——只有两个都是整数时才截断。
3.5.3 自增自减(高频考点!)
int a = 5, b;
b = a++; // 先用a的值:b=5,然后a自增:a=6
b = ++a; // a先自增:a=6,然后用a的值:b=6| 表达式 | 等价于 | 先做什么 |
|---|---|---|
a++ | a; a+=1 | 先用后加 |
++a | a+=1; a | 先加后用 |
逐变量推演(真题必考写法):
int a = 5, b;
b = a++; // 第1步:把a当前值5给b → b=5
// 第2步:a自增 → a=6
b = ++a; // 第1步:a先自增 → a=7
// 第2步:把a当前值7给b → b=7
// 最终:a=7, b=7记忆口诀:
++在左边 = 先干活再汇报;++在右边 = 先汇报再干活
🚨 红牌警告(未定义行为 · 2026 真题单选2)
同一个完整表达式中,同一个变量被多次修改,结果是"未定义行为"——不要手推!
int x = 2;
x += x++ + 1; // ⚠️ x 在同一个表达式里被改了两次,结果未定义2026 真题答案:选 D(结果未定义)。这类题的正确做法不是硬算,而是直接识别"同一个变量在同一表达式里被修改多次 → 未定义行为"。
❌ 错误示范(旧版讲义曾这样教,请勿模仿):"假设从左到右,x++=2,x变3,再+1……算出 5"——这是错的! 不同编译器结果可能不同,广东真题的标准答案是"未定义"。
3.5.4 关系/逻辑表达式真值(2024 单选4 必考)
C 语言中,关系表达式(
== != < > <= >=)和逻辑表达式(&& || !)的结果只有两个值:真 = 1,假 = 0
printf("%d\n", 10 != 9); // 10 不等于 9,为真 → 输出 1
printf("%d\n", 3 > 5); // 3 大于 5?假 → 输出 0🚨 2024 真题陷阱:
10 != 9的值是 1(不是"任意非0数",C 语言规定真值恒为 1)——选项 D"非 0"是专门设的陷阱!
3.5.5 逻辑短路(考点拆分自测考过)
&&(与)和||(或)有"短路"特性:能确定结果时,后面的表达式不再计算
int a = 0;
printf("%d\n", a && (a = 5)); // a=0 为假,&& 短路,后面的 (a=5) 不执行
// 结果 0,且 a 仍是 0!int a = 1;
printf("%d\n", a || (a = 9)); // a=1 为真,|| 短路,后面的 (a=9) 不执行
// 结果 1,且 a 仍是 1!考点拆分自测原题:printf("%d", 5 && 0 || 2); → 先算 5 && 0 = 0,再算 0 || 2,2 是真值 → 输出 1
3.5.6 逗号表达式(2024 单选7 必考)
逗号表达式:从左到右依次计算每个子表达式,整个表达式的值是最后一个子表达式的值
int a = 1, b = 206, c;
c = (a, b); // 先算 a(值1,丢弃),再算 b → 整个表达式值为 b,即 206
printf("%d\n", c); // 输出 206🚨 2024 真题:
(a, b)的值是 b(最后一个),不是 a!真题选项专门放了一个"取第一个值"的陷阱。
真题变形(三变量交换):
int x = 1, y = 2, t;
t = x, x = y, y = t; // 逗号表达式,从左到右依次执行三条赋值
// 结果:x=2, y=1(完成交换)3.5.7 复合赋值运算符
a += 3; // a = a + 3
a *= b+2; // a = a * (b+2) ← 注意:先算右边整体🔑 秒杀秘籍
a *= b + 2⚡ 等价于a = a * (b + 2)不是a = a * b + 2复合赋值运算符的右边是一个整体表达式!
3.5.8 sizeof 与 strlen 区分(2026 单选3 / 2024)
sizeof是运算符(算"占多少字节"),strlen是函数(算"有多少个字符")——两者结果常常不同!
#include <string.h>
char s[] = "Guangdong"; // 9个可见字符 + 末尾 '\0' = 共10个字节
printf("%d\n", sizeof(s)); // 10(含末尾的 '\0')
printf("%d\n", strlen(s)); // 9(只数可见字符,不含 '\0')🚨 2026 真题单选3:
strlen("Guangdong")= 9;若问sizeof则 = 10。一字之差,答案不同!
3.5.9 % 的实际应用:数位分离(2024 计算题)
用
/和%可以把一个整数的各位拆开——编程大题必备技能
int n = 153;
int ge = n % 10; // 个位:153 % 10 = 3
int shi = n / 10 % 10; // 十位:153/10=15,15%10=5
int bai = n / 100; // 百位:153/100=1
// 结果:bai=1, shi=5, ge=3④ 🧪【真题同源例题】
例题 1:入门基础题(先热热身)
int a = 5, b = 2;
printf("%d\n", a / b);
printf("%d\n", a % b);逐变量推演:
a / b=5 / 2:两个整数相除,5 里装下 2 个完整的 2(2×2=4),剩 5-4=1 → 商 2a % b=5 % 2:取余数 → 1- 输出:
2 1
例题 2:2026 真题改编(单选)
int x = 7, y = 2;
printf("%d", x / y + x % y);逐变量推演:
x / y=7 / 2:整数除法截断,7 里装下 3 个完整的 2(3×2=6),剩 7-6=1 → 3x % y=7 % 2:取余数 → 13 + 1= 4- 输出:
4
✅ 对应 2026 真题单选1,答案 C(4)。陷阱选项 B(3.5)就是给"忘了整数除法截断"的同学准备的。
例题 3:2024 真题改编(单选 · 逗号 + 真值)
int a = 10, b = 9;
printf("%d\n", a != b); // ①
printf("%d\n", (a, b)); // ②逐变量推演:
- 表达式①
a != b=10 != 9:10 不等于 9,关系表达式为真 → C 语言规定真值恒为 1 - 表达式②
(a, b):逗号表达式,从左到右:先算a(值10,丢弃)→ 再算b→ 整个值取最后一个 =b= 9 - 输出:
1 9
✅ 对应 2024 真题单选4(答案 1)和单选7(答案 b)。两个考点合在一题,考的就是"真值=1"和"逗号取末值"。
⑤ ⚠️【历年真题高频扣分坑】
| # | 陷阱 | 错误做法 | 正确做法 | 出处 |
|---|---|---|---|---|
| 1 | 整数除法截断 | 7/2 算成 3.5 | 两个整数相除直接截断 → 3 | 2026 单选1 |
| 2 | 真值误选"非0" | 10!=9 选 D"非0" | C 语言关系/逻辑真值恒为 1 | 2024 单选4 |
| 3 | 未定义行为硬算 | x+=x+++1 手推算出 5/6/7 | 识别"同表达式多改同一变量"→ 直接选"未定义" | 2026 单选2 |
| 4 | 逗号取首值 | (a,b) 选 a | 逗号表达式取最后一个表达式的值 | 2024 单选7 |
| 5 | sizeof 混 strlen | sizeof("ab") 当成 2 | sizeof 含 '\0' = 3;strlen = 2 | 2026 单选3 |
| 6 | 复合赋值展开错 | a*=b+c 当 a*b+c | 右端是整体 → a*(b+c) | 经典 |
| 7 | = 与 == 混淆 | if(a=5) 以为是判断 | = 赋值(恒真);== 才比较 | 经典 |
| 8 | 自增自减方向反 | a++ 以为是"先加后用" | a++ 先用后加;++a 先加后用 | 2024 单选8 |
| 9 | 短路误判 | 0 && (x=5) 以为 x 变成 5 | 短路后 (x=5) 不执行,x 不变 | 考点拆分自测 |
| 10 | 浮点直接 == | if(a==b) 比较浮点 | 用 fabs(a-b) < 1e-6 | 经典 |
📌 最值钱的一条:第 3 条(未定义行为)是 2026 年改革后新增的高频考点,看到"同一表达式里同一变量被改两次"直接判未定义,不要算——这是广东真题的明确口径。
⑥ 📝【课后自测练习题】
1. 写出下列表达式的结果(每题 3 分,共 12 分):
int a = 5, b = 2;
① a / b
② a % b
③ a++ (执行后 a 的值)
④ ++b (执行后 b 的值)2. (2026 真题风格)表达式 10 / 3 + 10 % 3 的值是( )
A. 4 B. 4.5 C. 5 D. 3
3. (2024 真题风格)已知 int a = 3, b = 4;,表达式 (a, b) 的值是( )
A. 3 B. 4 C. 7 D. 0
4. (2026 真题风格·综合)执行下面程序段后,x 的值是( )
int x = 2;
x += x++ + 1;A. 5 B. 6 C. 7 D. 结果未定义
👆 点击展开参考答案与解析
第1题:
- ①
5 / 2= 2(整数除法截断,5 装下 2 个完整 2) - ②
5 % 2= 1(余数) - ③
a++:先用后加 → 表达式值是 5,执行后 a = 6 - ④
++b:先加后用 → b 变 3,表达式值是 3
第2题:A(4)
10 / 3= 3(截断),10 % 3= 1,3 + 1 = 4- 陷阱:B(4.5)给"忘了整数除法"的同学
第3题:B(4)
- 逗号表达式取最后一个表达式的值 → b = 4
- 陷阱:A(3)给"取第一个值"的同学
第4题:D(结果未定义)
x在同一个表达式x += x++ + 1里被多次修改,求值顺序无保证 → 未定义行为- 不要手推!这正是 2026 真题单选2 的口径
📝 原有闭卷真题挑战(保留原内容)
(点击下方空白查看答案)
1. int占___字节,char占___字节,float占___字节
2. 'A'的ASCII码是___,'a'的ASCII码是___
3. 现有 int a=5; 则表达式 a++ + ++a + a-- 的值?
4. 以下哪个表达式等价于 a *= b + c ?
A. a = a * b + c B. a = a * (b + c) C. a = a * b + c
5. 判断:浮点数可以用 == 直接比较是否相等👆 点击展开答案(未定义行为题已按真题口径修正)
- 4, 1, 4(32位系统,64位也是4)
- 65, 97
- ⚠️ 未定义行为(
a++ + ++a + a--在同一表达式里多次修改 a,结果未定义,不要手推)——2026 真题口径:直接判定未定义,与旧版"推演出19"的教法不同 - B. a = a * (b + c) ← 复合赋值右边整体加括号
- ❌ 错误——浮点数有精度误差,要用
fabs(a-b) < 1e-6
📖 教材习题对照
| 教材习题 | 知识点 | 难度 |
|---|---|---|
| 习题2.1~2.3 | 数据类型、原反补 | ⭐⭐ |
| 习题2.4 | 运算符表达式 | ⭐⭐ |
| 习题3.2 | 自增自减运算 | ⭐⭐⭐ |
| 习题3.4~3.5 | 复合赋值、类型转换 | ⭐⭐ |
对应教材:谭浩强《C程序设计》第5版 → 第2章 + 第3章 对应考试大纲:考点2 — 数据的存储与运算
📺 配套视频
复习到本考点 → 先看视频补讲,再刷上面「闭卷挑战」。
- 强哥 P20~P70 数据类型/进制/运算符最全 · 整型实型溢出/进制
- 升本啦 P5 顺序程序设计