Skip to content

1.2 数据的存储与运算

计算机程序设计 · C语言 · 1.2 数据的存储与运算(运算符与表达式)

数据的存储与运算

🎯 一句话秒杀:数据类型决定了数据在内存中占多少空间、怎么存、能做什么运算;运算符则是告诉计算机"这些数据要怎么算"的指令符号。


① 📊【历年真题考情】

本章(运算符与表达式)在广东专升本计算机统考中的位置:

项目结论
出题频次★★★★☆(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。

学完能解决什么问题?

  1. 看懂真题选择题里"这个表达式值是多少"——直接白拿 3~6 分
  2. 写程序时正确地让计算机算数(判断、循环、累加都离不开它)
  3. 避开最大的坑:知道什么时候"算出来的答案是骗人的"(未定义行为)——2026 真题专门考了这个

💡 记住:C 语言里一切都是"表达式",表达式的最终结果是"一个值"。本章就是教你:拿到一串符号,怎么一步步算出那个"值"。


③ 📖【正式核心知识点讲解】

本章知识点 = 考纲要求 + 历年真题实际考过的内容。真题从未考察、考纲不作要求的内容已剔除(如位运算的复杂应用仅保留了解级)。

3.1 数据类型全家福(先认识"食材")

C数据类型
├── 基本类型
│   ├── 整型:int, short, long, long long
│   ├── 字符型:char(本质是整型)
│   ├── 浮点型:float, double
│   └── 布尔型:_Bool(C99新增)
├── 构造类型
│   ├── 数组
│   ├── 结构体 struct
│   ├── 共用体 union
│   └── 枚举 enum
├── 指针类型:*
└── 空类型:void

3.2 整型数据(重点)

整型分类

类型关键字字节数(32位)取值范围
基本整型int42312311
短整型short23276832767
长整型long42312311
长长整型long long82632631
无符号整型unsigned int402321

🚨 红牌警告

sizeof(int) 在不同的编译器中可能不同——16位系统是2字节,32/64位系统是4字节 但考试默认:int占4字节,short占2字节

有符号 vs 无符号

c
signed int a = -10;   // 可以存负数(最高位表示符号)
unsigned int b = 10;  // 只能存正数(最高位参与数值)

存储方式:

  • 正数:原码直接存储
  • 负数:补码存储(原码→取反→加1)
数值原码反码补码
+50000 01010000 01010000 0101
-51000 01011111 10101111 1011

🔑 秒杀秘籍

为什么负数用补码存储? 因为可以让加减法用同一套电路实现! 例:3+(2)=0000 0011+1111 1110=1 0000 0001 → 溢出舍去→ 0000 0001 = 1

3.3 字符型数据

c
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 浮点型数据

类型字节有效位数取值范围
float46~7位±3.4×10383.4×1038
double815~16位±1.7×103081.7×10308

🚨 红牌警告

浮点数不能直接用 == 比较相等! 因为浮点运算有精度误差 ✅ 正确做法: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(最低)= += -= 等赋值右→左
mermaid
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 真题双考 · 必拿分)

两个整数相除,结果直接丢掉小数部分(截断,不四舍五入)

c
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,余 1
  • 7 % 2:取余数 → 1
  • 所以 7 / 2 + 7 % 2 = 3 + 1 = 4 ✅(2026 真题原题

🚨 关键区别:如果有一个数是小数(如 7.0 / 2),结果是 3.5——只有两个都是整数时才截断

3.5.3 自增自减(高频考点!)

c
int a = 5, b;
b = a++;   // 先用a的值:b=5,然后a自增:a=6
b = ++a;   // a先自增:a=6,然后用a的值:b=6
表达式等价于先做什么
a++a; a+=1先用后加
++aa+=1; a先加后用

逐变量推演(真题必考写法)

c
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)

同一个完整表达式中,同一个变量被多次修改,结果是"未定义行为"——不要手推!

c
int x = 2;
x += x++ + 1;   // ⚠️ x 在同一个表达式里被改了两次,结果未定义

2026 真题答案:选 D(结果未定义)。这类题的正确做法不是硬算,而是直接识别"同一个变量在同一表达式里被修改多次 → 未定义行为"

❌ 错误示范(旧版讲义曾这样教,请勿模仿):"假设从左到右,x++=2,x变3,再+1……算出 5"——这是错的! 不同编译器结果可能不同,广东真题的标准答案是"未定义"。

3.5.4 关系/逻辑表达式真值(2024 单选4 必考)

C 语言中,关系表达式(== != < > <= >=)和逻辑表达式(&& || !)的结果只有两个值:真 = 1,假 = 0

c
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 逻辑短路(考点拆分自测考过)

&&(与)和 ||(或)有"短路"特性:能确定结果时,后面的表达式不再计算

c
int a = 0;
printf("%d\n", a && (a = 5));  // a=0 为假,&& 短路,后面的 (a=5) 不执行
                               // 结果 0,且 a 仍是 0!
c
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 必考)

逗号表达式:从左到右依次计算每个子表达式,整个表达式的值是最后一个子表达式的值

c
int a = 1, b = 206, c;
c = (a, b);     // 先算 a(值1,丢弃),再算 b → 整个表达式值为 b,即 206
printf("%d\n", c);   // 输出 206

🚨 2024 真题(a, b) 的值是 b(最后一个),不是 a!真题选项专门放了一个"取第一个值"的陷阱。

真题变形(三变量交换)

c
int x = 1, y = 2, t;
t = x, x = y, y = t;   // 逗号表达式,从左到右依次执行三条赋值
// 结果:x=2, y=1(完成交换)

3.5.7 复合赋值运算符

c
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 是函数(算"有多少个字符")——两者结果常常不同!

c
#include <string.h>
char s[] = "Guangdong";   // 9个可见字符 + 末尾 '\0' = 共10个字节
printf("%d\n", sizeof(s));   // 10(含末尾的 '\0')
printf("%d\n", strlen(s));   // 9(只数可见字符,不含 '\0')

🚨 2026 真题单选3strlen("Guangdong") = 9;若问 sizeof 则 = 10。一字之差,答案不同!

3.5.9 % 的实际应用:数位分离(2024 计算题)

/% 可以把一个整数的各位拆开——编程大题必备技能

c
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:入门基础题(先热热身)

c
int a = 5, b = 2;
printf("%d\n", a / b);
printf("%d\n", a % b);

逐变量推演:

  1. a / b = 5 / 2:两个整数相除,5 里装下 2 个完整的 2(2×2=4),剩 5-4=1 → 商 2
  2. a % b = 5 % 2:取余数 → 1
  3. 输出:
    2
    1

例题 2:2026 真题改编(单选)

c
int x = 7, y = 2;
printf("%d", x / y + x % y);

逐变量推演:

  1. x / y = 7 / 2:整数除法截断,7 里装下 3 个完整的 2(3×2=6),剩 7-6=1 → 3
  2. x % y = 7 % 2:取余数 → 1
  3. 3 + 1 = 4
  4. 输出:4

✅ 对应 2026 真题单选1,答案 C(4)。陷阱选项 B(3.5)就是给"忘了整数除法截断"的同学准备的。

例题 3:2024 真题改编(单选 · 逗号 + 真值)

c
int a = 10, b = 9;
printf("%d\n", a != b);     // ①
printf("%d\n", (a, b));     // ②

逐变量推演:

  1. 表达式① a != b = 10 != 9:10 不等于 9,关系表达式为真 → C 语言规定真值恒为 1
  2. 表达式② (a, b):逗号表达式,从左到右:先算 a(值10,丢弃)→ 再算 b → 整个值取最后一个 = b = 9
  3. 输出:
    1
    9

✅ 对应 2024 真题单选4(答案 1)和单选7(答案 b)。两个考点合在一题,考的就是"真值=1"和"逗号取末值"。


⑤ ⚠️【历年真题高频扣分坑】

#陷阱错误做法正确做法出处
1整数除法截断7/2 算成 3.5两个整数相除直接截断 → 32026 单选1
2真值误选"非0"10!=9 选 D"非0"C 语言关系/逻辑真值恒为 12024 单选4
3未定义行为硬算x+=x+++1 手推算出 5/6/7识别"同表达式多改同一变量"→ 直接选"未定义"2026 单选2
4逗号取首值(a,b) 选 a逗号表达式取最后一个表达式的值2024 单选7
5sizeofstrlensizeof("ab") 当成 2sizeof 含 '\0' = 3;strlen = 22026 单选3
6复合赋值展开错a*=b+ca*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 分):

c
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 的值是(  )

c
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. 判断:浮点数可以用 == 直接比较是否相等
👆 点击展开答案(未定义行为题已按真题口径修正)
  1. 4, 1, 4(32位系统,64位也是4)
  2. 65, 97
  3. ⚠️ 未定义行为a++ + ++a + a-- 在同一表达式里多次修改 a,结果未定义,不要手推)——2026 真题口径:直接判定未定义,与旧版"推演出19"的教法不同
  4. B. a = a * (b + c) ← 复合赋值右边整体加括号
  5. ❌ 错误——浮点数有精度误差,要用 fabs(a-b) < 1e-6

📖 教材习题对照

教材习题知识点难度
习题2.1~2.3数据类型、原反补⭐⭐
习题2.4运算符表达式⭐⭐
习题3.2自增自减运算⭐⭐⭐
习题3.4~3.5复合赋值、类型转换⭐⭐

对应教材:谭浩强《C程序设计》第5版 → 第2章 + 第3章 对应考试大纲:考点2 — 数据的存储与运算

📺 配套视频

复习到本考点 → 先看视频补讲,再刷上面「闭卷挑战」。

仅供个人学习 · 考生回忆版 · 非考试院原卷