顺序结构

官方信息技术老师·12 页·深入(追求细节与边界)·0 次浏览·3 天前
程序流程执行时序语句拆解底层细节

顺序结构

拆解每条语句的执行时序与隐藏细节,看穿程序的线性骨架

按 空格/→ 演示下一步

1 / 12 页

全部页面点击任意一页,跳回舞台从这页播放

程序流程执行时序语句拆解底层细节

顺序结构

拆解每条语句的执行时序与隐藏细节,看穿程序的线性骨架

1第 1 页 · 顺序结构

语句与表达式

上页我们说顺序结构是一句接一句往下执行——那句到底是什么?程序里最小颗粒其实是两类东西:语句和表达式。这页把它们拆开讲。

表达式
由变量、运算符、函数调用等组合而成,求值后产出一个值
语句
完整的执行单元,常常不直接产值,用来组织流程或完成动作
表达式语句
单独一个表达式加个分号,就成为一行语句,但求值结果当场被丢弃
副作用
语句真正发力靠赋值、I/O、状态变更等副作用——这是语句动作的源头
菜谱配料比与操作步骤对应 →表达式与语句

配料比算出数值,步骤完成动作;一行只写30克糖既是值也是动作,对应表达式语句

2第 2 页 · 语句与表达式

算术运算

上一节把表达式拆成「操作数 + 操作符 + 操作数」。这一页聚焦操作符里的算术运算——计算机拿到 '3 + 4 * 2' 先算什么不是随意的,有严格的优先级规则在管。

Python 七种算术操作符
+、-、*、/、//、%、**,分别对应加减、乘除、整除、取模、幂
优先级
** 最高;* / // % 同级;+ - 最低;同级从左到右结合
类型与隐式提升
int 与 float 混合时自动提升为 float;纯整数用 // 才强制整除
常见陷阱
除零报错、整除截断(7//2=3)、负数取模符号跟随除数
厨房按菜谱下锅对应 →算术运算优先级

菜谱写「先炒肉再放盐」,你不能倒过来——优先级就是这种「哪步先做」的硬规则

  >  ×  /  //  %  >  +  **\;>\;\times\;/\;//\;\%\;>\;+\;-
3第 3 页 · 算术运算

赋值运算

算术运算算出了结果,这些结果得有个地方放——赋值就是负责把值存进变量的动作。

基本赋值
右侧表达式求值后存入左侧变量,方向严格从右到左
复合赋值
+=、-=、*= 把运算与赋值合并为一条语句
链式赋值
形如 a = b = c = 5,多变量共享同一个值
赋值非等式
= 是动作不是数学关系,左边必须是可写位置
快递柜贴标签对应 →变量赋值

柜子是变量名,包裹是值,赋值就是把新包裹放进标签下的柜子

4第 4 页 · 赋值运算

位运算

赋值运算让变量拥有了一个整数值——而这个值的底层其实是 0 和 1 排成的比特串。直接在比特层面操作的运算,就是位运算。

定义
直接对整数二进制位进行操作的运算,按位独立、互不干扰
六大运算符
&(与) |(或) ^(异或) ~(取反) <<(左移) >>(右移)
核心特性
按位独立计算,无进位无借位;除移位外全部可逆
典型应用
标志位、位掩码、快速乘除 2 的幂、奇偶判断、加密校验
一排灯开关对应 →位运算

每个开关独立控制一盏灯:&要求全开才亮,|只要一个开就亮,^是状态翻转

nkn×2knkn/2kn \ll k \equiv n \times 2^k \qquad n \gg k \equiv \lfloor n / 2^k \rfloor
5第 5 页 · 位运算

增量运算和逗号运算

排队叫号时,你既可能想知道'当前叫到几号'(旧值),也可能想知道'下一个该几号'(新值)。增量运算和逗号运算就是 C 语言里处理这类'顺手做一件事'的小工具。

前/后缀自增
++i 先加再用,i++ 先用再加;两者的表达式值不同,但变量最终都 +1
副作用与序列点
自增会改写变量;同一变量在两个序列点间被多次修改,行为未定义
逗号运算符
用 , 把若干表达式串起来,从左到右求值,整体取值是最后一个
优先级最低
a=(1,2,3) 中 a=3;而 a=1,2,3 解析成 (a=1),2,3,a 只得 1
排队叫号对应 →前/后缀自增

显示当前号=后缀(取旧值);显示下一号=前缀(取新值);号本身都已变化

6第 6 页 · 增量运算和逗号运算

数据输出

你算出一组数据想给别人看——总不能把内存地址念出来吧?需要一位「翻译官」,把二进制翻译成人类能读的数字、文字。这件事在 C 里靠 printf 完成。

printf 函数
把数据写到标准输出(stdout),最常用的输出方式
格式说明符
%d、%f、%c、%s 等占位符,按类型填入数据
转义字符
\n 换行、\t 制表、\\ 反斜杠,控制输出样式
格式控制
控制宽度、对齐、小数位数,让输出对齐美观
返回值
返回成功输出的字符个数,可用于检查输出是否完成
餐厅点餐小票对应 →printf 的格式化输出

模板格式固定(菜名/单价/数量各占一列),实际内容随订单填入

7第 7 页 · 数据输出

数据输入

上一页讲了数据输出,是把变量里的值「发出去」。反过来,要让程序处理数据,首先得把数据「收进来」——这一步就靠数据输入。

scanf函数
通过格式字符串指定读取类型,再把解析后的值写入指定地址的变量
&取地址符
变量名前加&取内存地址,scanf需要的是「存放位置」而非「值本身」
输入缓冲区
键盘输入先暂存在缓冲区,scanf按需从中取走,未取走的内容会留下影响下次读取
返回值检查
scanf返回成功赋值的项数;不等于预期时应清空输入流再重试
快递分拣中心对应 →scanf输入机制

包裹(输入)按快递单(格式串)分拣到货架(变量地址),货架上必须有位置(&)

8第 8 页 · 数据输入

二级C考点解析之运算符及

做数学题我们默认先乘除后加减,但 C 表达式里混着算术、关系、逻辑、赋值多种运算符时,谁先算、按什么方向算,直接决定结果。本页把决定运算顺序的'交通规则'一次讲透。

优先级
不同运算符碰面,优先级高的先结合,相当于数学里'先乘除后加减'的规则
结合性
同优先级时规定方向:大部分从左到右,赋值类则从右到左
类型转换
不同类型混合运算,自动向'更宽'的类型靠拢,如 int + double 自动转 double
左值要求
赋值、自增等运算符左侧必须是可修改的左值,常量或表达式不能放左边
求值副作用
i++、赋值等会修改变量,C 不保证子表达式求值顺序,结果属实现定义
数学运算规则与阅读方向对应 →C 运算符的优先级与结合性

先乘除后加减≈优先级;从左读到右≈大部分运算的结合方向;赋值反向写所以从右往左

a=b=ca=(b=c)(赋值运算符右结合)a = b = c \Rightarrow a = (b = c)(赋值运算符右结合)
9第 9 页 · 二级C考点解析之运算符及

二级C考点解析之数据输入

上一页把 scanf 的基本骨架过了一遍。这页专攻二级 C 笔试和上机里最爱设套的几个坑——& 加不加、%c 的回车去哪了、返回值到底返回的是什么。

scanf 返回值
返回成功匹配的项数(int),遇非法输入或文件尾返回 EOF(-1)
& 取地址
除数组名外必须加 &;数组名本身就是地址,不能再加 &
格式符严区分
scanf 中读 double 必须用 %lf,printf 中 double 可用 %f——是常考点
%c 与回车
%c 不跳过空白,连续读时残留的 \n 会被吞掉;可在 %c 前加空格跳过
快递员按地址送货对应 →scanf 写入变量

格式串是货品清单,&变量是门牌号,scanf 按清单把对应类型的数据送到指定房间

10第 10 页 · 二级C考点解析之数据输入

本节要点

  • 顺序结构是默认执行模型,所有控制结构都建立在此之上
  • 表达式求值三要素:优先级、结合性、副作用顺序
  • 位运算仅适用于整型,有符号数右移是实现定义行为
  • scanf返回值用于检测匹配失败,是健壮输入的关键
  • 考点高频陷阱:赋值与比较混淆、i++与++i、逗号表达式值
延伸主题:分支结构:if与switch的判断选择循环结构:三种循环语句对比运算符优先级完整速查表
11第 11 页 · 本节要点

课后思考

先盖住答案,自己想 30 秒再看。三个问题对应三种深度:精确理解、边界踩坑、概念辨析。

1为什么'按书写顺序逐句执行'并不足以精确描述顺序结构?运算符优先级如何在这条线上制造了执行时间差?

参考答案提示路径:先区分'语句间顺序'与'表达式内部求值顺序'。顺序结构保证前者(控制流无跳转),后者由运算符优先级决定。`2+3*4` 中 `*` 优先级高,`+` 写在前面也无效——这就是时间差的来源。

2`x = x++ + ++x;` 在不同编译器下可能得出不同结果,这是否说明顺序结构并不保证执行确定性?

参考答案提示:这不是顺序结构的问题,而是表达式求值的灰色地带。C 标准未规定同一变量在同一表达式中多次修改的求值顺序——属于未定义行为(UB)。语句间顺序依然确定,问题出在表达式内副作用的交织。

3逗号表达式 `(a=1, b=2, c=3)` 与三条独立赋值语句在语义上完全等价吗?差异点可能藏在哪里?

参考答案思考方向:逗号表达式是一个表达式,从左到右严格求值并返回最后一项;三条独立语句仅保证语句间顺序。颗粒度不同——逗号是表达式内子句,语句是顶层颗粒。涉及副作用时行为可能分裂。

12第 12 页 · 课后思考