C语言综述(一)
数据如何进入程序并参与计算?

从成绩分析问题理解变量、类型、输入输出与浮点运算

本次课的整体任务

设计一个班级成绩分析程序,并在三课时中逐步扩展。

输入成绩
→
计算平均分
→
判断区间
→
统计一组成绩
→
提取函数

为什么选“成绩分析”作为贯穿问题?

变量简单

主要变量为 a、b、s、sum、avg,减少英文词汇负担。

类型典型

原始成绩常用整数,平均分常用浮点数,适合解释 int 与 double。

分支典型

成绩有合法范围和等级区间,适合解释合理区间设计与边界测试。

第1课时学习目标

知识目标

  • 识别C程序基本结构
  • 理解变量定义与数据类型
  • 理解 scanf / printf 的基本用法
  • 区分整数运算与浮点运算

能力目标

  • 能从“输入—处理—输出”分析一个简单问题
  • 能预测表达式结果并用运行结果验证
  • 能借助AI解释运算过程,但不盲信结论
2.1 / 从一个输出程序开始
程序先要“站起来”:
结构、入口与输出
#includemainprintfreturn

V0:让程序输出一句提示


#include <stdio.h>
int main(void)
{
    printf("Enter two scores: ");
    return 0;
}
        

#include

引入标准输入输出相关信息。

main()

C程序开始执行的位置。

printf()

把文字显示到屏幕上。

一个C程序由哪些部分组成?

C语言程序结构解剖图
2.2 / 从常量到变量,再到交互
程序要处理数据:
从固定数值到动态输入
常量变量与赋值int / doublescanf / printf

从固定值到变量:给数据一个“容器”

① 直接输出固定数值


printf("score = 59\n");
                

数据直接硬编码在程序中,数值固定无法重复修改使用。

② 用变量保存数据


int a = 59;
printf("score = %d\n", a);
                

开辟一块内存空间命名为 a,把数据存入其中。

核心概念:变量是内存中一块有名字、有类型的存储单元;赋值(=)是把右侧的数据放入左侧的变量中。

两个变量与计算:表达式类型的演化

尝试 ①:直觉写法(整数除法)


int a = 59, b = 60;
int avg = (a + b) / 2;
printf("avg = %d\n", avg);
                

思考与讨论:119 / 2 的输出是多少?小数部分 .5 被直接丢弃(整数截断)。

过渡 ②:引入浮点数(浮点运算)


int a = 59, b = 60;
double avg = (a + b) / 2.0;
printf("avg = %.1f\n", avg);
                

解决方案:使用 2.0 提升表达式类型为浮点数,正确输出 59.5。

规律引出(表达式类型):C语言中“整数 ÷ 整数”结果仍为整数;只要除数变为浮点数(2.0),整个表达式就会按浮点运算保留小数。

类型辨析:为什么要区分 int 与 double?

int 整数类型

int a = 59;
  • 只保存整数(没有小数部分)
  • 场景:成绩、人数、计数、页码
  • 内存开销小,运算速度极快

double 双精度浮点型

double avg = 59.5;
  • 保存带小数连续变化的数据
  • 场景:平均分、身高、比率、测量值
  • 格式化输出:printf("%.1f", avg);

变量定义 = 告知编译器内存大小 + 赋予名字 + 制定解释规则

从固定赋值到动态输入:使用 scanf()

固定赋值(硬编码)


int a = 59, b = 60;
                

每次换成绩都要修改代码重新编译,缺乏通用性。

动态从键盘输入


int a, b;
scanf("%d%d", &a, &b);
                

程序运行时等待用户输入数据,通用性强!

对比辨析:
printf("...", a); 把变量 a 的值拿出来显示。
scanf("...", &a); 找到变量 a 的地址(&a),把键盘读入的数据放进去。

第一个完整版本:交互式成绩平均分计算


#include <stdio.h>

int main(void)
{
    int a, b;            // 1. 定义变量存储整数成绩
    double avg;          // 2. 定义变量存储浮点平均分
    scanf("%d%d", &a, &b); // 3. 读入用户输入的成绩
    avg = (a + b) / 2.0; // 4. 计算平均分(浮点运算)
    printf("average = %.1f\n", avg); // 5. 格式化输出结果
    return 0;
}
        

看懂这段程序:从“固定数据”到“输入-处理-输出”完整数据流!

2.3 / 深入原理与思维建立
现象背后的 C 语言原理:
类型、运算与思维碰撞
右值先求值类型自动提升隐式/显式转换程序设计思维

原理剖析①:为什么 `double avg` 依然输出 `59.0`?

认知陷阱:以为把变量定义为 double avg,计算就会自动按小数算。


double avg;
avg = (a + b) / 2;     // 结果是 59.0,而不是 59.5!
        

第一步:右侧表达式先求值

(59 + 60) / 2 → 119 / 2

两个 int 相除,在赋值前就已经被截断为整数 59!

第二步:结果再赋值给左值

avg = 59 → 转换为 double

将已截断的整数 59 存入 double 变量,变为 59.0。

核心原理:表达式求值先于赋值!左侧变量类型无法倒回去改变右侧表达式已完成的计算法则。

原理剖析②:C 语言类型提升与转换法则

规则一:同种类型相算

(59 + 60) / 2

int ÷ int → int

直接丢弃小数部分(截断)。

规则二:混合类型自动提升

(59 + 60) / 2.0

int ÷ double → double ÷ double → double

低精度自动提升为高精度,保留小数。看常量 2.0!

决定计算精度的三要素:变量类型、常量形式、表达式整体类型

思维建立:程序设计的 3 大重点提示

提示 ①:看表达式,不看左值

计算精度由表达式内部的数据类型决定,而不是由接收结果的变量决定。

提示 ②:警惕整数除法截断

只要涉及平均值、比例、百分比等场景,运算符两侧必须至少有一个浮点数。

提示 ③:用边界数据测试

不要凭直觉想象代码运行!必须用类似 59, 60 这种能触发奇数除法的边界数据真实验证。

写法 原理特征 建议等级
avg = (a + b) / 2; 整数截断,丢小数 避坑:不推荐
avg = (a + b) / 2.0; 常量触发自动提升 推荐:直观清晰
avg = (double)(a + b) / 2; 强制类型转换 进阶:显式转换

AI 协作学原理:让 AI 拆解运算过程

我正在学习 C 语言。请分析下面两条语句在 a=59, b=60 时的计算过程:
avg = (a + b) / 2; 和 avg = (a + b) / 2.0;
请逐步说明每一步参与运算的数据类型、中间结果与类型转换。不要直接给整段代码。

先依据原理预测

在纸上画出“右值计算 → 类型提升 → 左值赋值”的三个步骤。

再让 AI 拆解验证

核对 AI 的拆解是否符合“右值先算”原理,防范 AI 产生生成幻觉。

第1课时小结与知识图谱

  • 结构:C程序从 main 组织执行。
  • 变量:变量定义绑定了名字、内存大小与解释规则。
  • 输入输出:scanf 取地址存入,printf 格式化输出。
  • 运算原理:表达式求值先于赋值;低精度向高精度自动提升。
  • 思维习惯:警惕整数截断,用临界数据验证,善用 AI 拆解。