引言:生成式AI时代
怎样学程序设计?

中医药人工智能学院 · 浙江中医药大学

第0章之后,第1章还要解决什么?

①

AI时代
怎样学习程序设计?

②

程序和程序语言
到底是什么?

③

一个C程序
怎样产生并运行?

第1章内容组织

模块 内容 作用
1.1 AI时代的程序设计学习观 建立学习方式
1.2 程序、指令与虚拟计算机 认识程序本质
1.3 语言功能、语法、控制结构 建立语言整体框架
1.4 第一个C程序、阶乘程序、Python/C比较 进入C程序阅读
1.5 编译运行、错误、AI Debug 衔接上机实验
1.6 问题求解、算法描述、偶数求和 形成问题求解闭环
1.7 AI协作规则、实验衔接、任务0 形成第一次课闭环
1.1 / AI时代的程序设计学习观
AI会写代码,
我们怎样真正学会程序设计?
学习观AI协作问题求解判断与验证

开场问题

如果期末给你一个题目,
你把它完整交给AI生成代码——
这算不算“会程序设计”?

A 算B 不算C 要看情况

演示:让AI“秒写”一个C程序

任务:输入3名学生的成绩,输出平均成绩和最高成绩。

#include <stdio.h>
int main(void) {
    double a, b, c;
    scanf("%lf%lf%lf", &a, &b, &c);
    double avg = (a + b + c) / 3.0;
    double max = a;
    if (b > max) max = b;
    if (c > max) max = c;
    printf("Average: %.2f\n", avg);
    printf("Max: %.2f\n", max);
    return 0;
}
        

AI可以很快生成代码,任务结束了吗?

代码生成 ≠ 问题解决

继续追问

  • 输入负数怎么办?
  • 如果输入字符怎么办?
  • 如果有100名学生呢?
  • 为什么选 double?
  • 有没有其他写法?
  • 你怎么证明结果正确?

人必须负责

理解目标

明确约束

判断方案

验证结果

承担责任

程序设计真正学什么?

现实问题
→
理解问题
→
确定输入/输出/约束
→
设计方法
→
表达成程序
→
运行测试
→
判断修改

AI特别擅长:解释、生成、补全、修改、提示

人必须负责:目标、判断、验证、选择、责任

本课程第一条原则:

程序设计的核心不是“记住多少语法”,而是分析问题、设计方法、表达算法、编写程序、测试和修改程序。
1.2 / 程序、指令与程序设计语言
程序不是一段神秘代码,
而是一组可执行的步骤
程序指令语言步骤

程序与程序设计语言

程序

人们为解决某种问题,用计算机可以识别的代码,编排的一系列加工步骤。

程序执行过程,本质上是对程序所表达的数据进行处理的过程。

程序设计语言

提供一种表达数据与处理数据的功能,要求程序员按照语言规范编程。

程序与指令

指令

计算机最基本的功能,例如实现一次加法运算,或实现一次大小判别。

指令系统

计算机所能实现的指令的集合。

程序

为完成某个任务而编写的一系列计算机指令的有序组合。

类比:菜谱也是一组有序步骤。

用“菜谱”理解程序

程序名:番茄炒蛋

指令1:拿出两个鸡蛋

指令2:将鸡蛋打入碗中并搅拌

指令3:切番茄

指令4:加热、翻炒、调味

计算机程序比菜谱更严格:每一步都必须精确。

虚拟计算机指令系统

例:编写程序,分别求和与乘积。约定字母表示内存单元,0、1 等数字表示常量;虚拟计算机定义7条指令:

  • Input X:将当前输入数据存储到内存 X 单元
  • Output X:将内存 X 单元的数据输出
  • Add X Y Z:将操作数 X 与 Y 的值相加,结果存储到内存 Z
  • Sub X Y Z:将操作数 X 与 Y 的值相减,结果存储到内存 Z
  • BranchEq X Y P:若操作数 X 与 Y 的值相等,跳转到 P 处执行
  • Jump Q:程序跳转到 Q 处执行
  • Set X Y:将操作数 X 的值存储到内存 Y

虚拟程序:输入A、B、C,求A+B+C


Input A;     输入第1个数据到A
Input B;     输入第2个数据到B
Input C;     输入第3个数据到C
Add A B D;   D = A + B
Add C D D;   D = C + D
Output D;    输出D
        

思考:如何求 A + B - C?

虚拟程序:输入A,求A+A+A

虚拟程序1


Input A;
Add A A D;
Add A D D;
Output D;
                

虚拟程序2


Input A;
Set 0 Z;
Add Z A Z;
Add Z A Z;
Add Z A Z;
Output Z;
                

同一个问题可以有不同程序,但都要表达清楚步骤。

虚拟程序:输入A和B,求A*B

先限定 B 为非负整数。此时 A*B = A + A + ... + A,相当于 B 个 A 相加。


Input A;
Input B;
Set 0 Z;
Add Z A Z;
Add Z A Z;
...
Add Z A Z;
Output Z;
        

这样的思路可行吗?关键问题在哪里?

引出循环:用重复加法求A*B

  • 分别输入 A、B
  • 设 X = 0,Z = 0
  • 当 X 不等于 B 时重复:
    Z = Z + A;X = X + 1
  • 输出 Z

Input A;
Input B;
Set 0 X;
Set 0 Z;
BranchEq X B 9;
Add Z A Z;
Add 1 X X;
Jump 5;
Output Z;
                

适用条件:B 为非负整数;若允许负数,还需要增加符号处理。

思考:如何求 (A+B)*C?

1.3 / 程序设计语言的功能与语法
程序设计语言提供什么?
语法又约束什么?
数据表达流程控制输入输出模块化

程序设计语言的功能

数据表达

表达要处理的数据类型

流程控制

表达数据处理流程

输入输出

表达数据进入和结果输出

模块化

把代码组织为独立模块

数据表达

数据类型

对某些具有共同特征的数据集合的总称。

例如整数集合:{..., -2, -1, 0, 1, 2, ...}

数据上的操作

不同数据类型可以进行不同运算,如:

+ - * / %

C语言中的数据类型

  • 基本数据类型:整型、实型/浮点型、字符型等
  • 构造类型:数组、结构体、联合体等
  • 其他类型:指针类型、枚举类型、空类型等
  • 常量:程序运行过程中值不变的数据
  • 变量:程序运行过程中可保存和改变数据的存储单元

结构化程序设计方法

  • 将复杂程序划分为若干相对独立的模块
  • 模块可以是一条语句、一段程序或一个函数
  • 强调单入口、单出口
  • 程序结构清晰,便于阅读、修改和调试
结构化程序设计

三种基本控制结构

任何程序都可以将模块通过三种基本控制结构组合实现。

顺序结构

顺序结构

分支结构

分支结构

循环结构

循环结构

程序设计语言的语法

程序必须符合语法规则,规定代码该怎么写。

字符
→
单词
→
表达式
→
语句
→
函数
→
程序

C语言的主要“单词”

  • 标识符:变量名、函数名等,由字母、数字、下划线组成,且第一个字符不能是数字
  • 保留字/关键字:C语言规定的特殊单词,如 int、for、return
  • 常量:如 123、12.34
  • 运算符:如 +、-、*、/、%、>
  • 分隔符:如 { }、( )、;
  • 注释:用于解释程序,编译器会忽略

C语言的主要语法单位

  • 表达式:运算符与运算对象组合形成表达式,如 2+3*4
  • 变量定义:定义变量时需要说明类型,如 int n;
  • 语句:程序最基本的执行单位
  • 函数的定义与调用:把程序组织成模块
1.4 / 从第一个C程序开始
从 Hello C 到教材例题,
先学会阅读程序
Hello Cmain函数printfPython/C比较

从第一个C程序开始


#include <stdio.h>

int main(void)
{
    printf("Hello, C!\n");
    return 0;
}
        

先问6个问题

程序从哪里开始执行?
main 是什么?
printf 做什么?
为什么需要 stdio.h?
return 0; 是什么意思?
如果让AI解释,它会怎么说?

AI也可以是“随时可问的助教”

推荐问法:
“请向一个第一次学习C语言、但有Python基础/没有编程语言基础的大学一年级学生解释这段程序。不要使用复杂术语;逐行解释;最后给我3个检查理解的问题。”

但:AI的解释也需要判断。

例如:“C程序从第一行开始执行”——对吗?

C程序的基本框架


#include <stdio.h>     // 预处理命令

int main(void)          // 主函数:程序入口
{
    // 函数体:写具体要执行的语句
    return 0;           // 程序正常结束
}
        

C程序由一个或多个函数组成,main 是主函数,有且只有一个。

例1-1:求阶乘问题

输入一个正整数 n,输出 n!。例如输入 4,输出 24。


#include <stdio.h>
int factorial(int n);

int main(void)
{
    int n, result;
    scanf("%d", &n);
    result = factorial(n);
    printf("%d\n", result);
    return 0;
}

int factorial(int n)
{
    int i, fact = 1;
    for(i = 1; i <= n; i++)
    {
        fact = fact * i;
    }
    return fact;
}
        

阶乘程序:先读懂,不急着写

  • 函数:C程序由函数组成,main 是入口,factorial 是自定义函数
  • 变量:int n, result; 在内存中准备空间保存整数
  • 函数声明:提前告诉 main 后面有一个 factorial 函数
  • 输入:scanf("%d", &n) 从键盘读取整数
  • 循环:for 反复执行乘法,实现 n!

Python 与 C:我们已经会什么,还缺什么?

Python


a = 10
print(a)
                

C


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

Python常常替你隐藏很多细节;C会逼着你理解这些细节。

Python → C:输入两个整数并求和

Python


a = int(input())
b = int(input())
print(a + b)
                

C


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

从比较中认识C语言

观察点 Python C
变量类型 通常不需显式声明 需要明确声明 int 等类型
语法 较简洁 分号、花括号等规则更严格
输入输出 input / print scanf / printf
程序结构 脚本式更常见 通常从 main 函数开始
底层细节 隐藏较多 暴露更多
1.5 / 编译运行与调试
一个 C 程序,
怎样变成可以运行的结果?
源程序编译链接调试

程序的编译与编程环境

  • 程序的编译:编译器分析源代码并将其翻译为汇编代码或目标代码
  • 链接:链接器把目标文件与所需库代码组合起来,生成可执行程序
  • 错误诊断:编译器能够发现并报告许多词法、语法和部分语义错误
  • 编程环境:包括编辑程序、编译、调试等工具和过程

C语言编译过程

C语言编译流程图
  • 预处理:处理头文件、宏、条件编译
  • 编译:语法检查,生成汇编代码
  • 汇编:生成目标文件
  • 链接:组合目标文件与所需库代码,生成可执行文件

编译命令:先了解即可


gcc -c test.c
gcc test.o -o test
gcc -o test test.c
gcc -Wall -save-temps test.c -o test
        

如果使用IDE,“运行”按钮背后也包含编辑、编译、链接和执行的过程。

从源代码到运行结果

hello.c
源程序
→
预处理 / 编译
→
汇编 / 链接
→
可执行程序
→
运行结果

故意让程序出错

错误1


printf("Hello C!")
                

少了什么?

错误2


pritnf("Hello C!");
                

发生了什么?

错误3


printf("Hello C!\n";
                

编译器会怎么提示?

错误信息不是失败,而是程序给你的反馈。

语法错误与逻辑错误

语法错误

程序不符合语言规则,通常由编译器发现。

例如:少分号、括号不匹配、函数名拼错。

逻辑错误

程序能运行,但结果不是想要的结果。

需要通过测试、观察和分析来发现。

C语言程序编译、链接、运行与调试

编辑
test.c
→
编译
→
链接
→
运行与测试
→
检查结果
编译或链接失败:根据错误信息返回编辑;程序可以运行但结果不正确:分析原因、调试修改,然后重新编译和测试。

第一次AI Debug

不推荐

“把正确代码给我。”

更推荐

“这段C程序编译失败。请先指出错误原因,并提示我应该检查哪里;先不要直接给完整正确程序。”

本课程第二条原则:

程序不是“写出来就结束”,而是经过运行 → 发现问题 → 判断原因 → 修改 → 再验证逐步形成的。
1.6 / 如何实现问题求解
从问题到算法,
再从算法到程序
问题分析算法流程图代码实现

问题求解示例

问题:求 1–100 之间所有偶数的和

先不要急着写代码,先分析问题。

问题分析与算法分析

  • 思路 → 算法:先有解决问题的思路,再形成明确步骤
  • 算法:一组明确的解决问题的步骤,它产生结果,并能在有限时间内终止
  • 算法描述:自然语言、伪代码、流程图

思路和算法

  • 明确问题:在范围 1–100 内,找到满足条件“偶数”的整数,并求累加和
  • 设置变量:用 sum 保存累加结果,初始值为 0
  • 重复检查:依次查看每个整数 i
  • 条件判断:如果 i 是偶数,就执行 sum = sum + i;

算法描述:流程图

偶数求和流程图

从算法到程序:先看整体


#include <stdio.h>

int main(void)
{
    int i, sum = 0;

    for(i = 1; i <= 100; i++)
    {
        if(i % 2 == 0)
        {
            sum = sum + i;
        }
    }

    printf("%d\n", sum);
    return 0;
}
        

第一次课只看清楚“输入/处理/输出”和“顺序/分支/循环”如何配合。

问题延伸:同一个结构可以解决更多问题

从固定范围到输入范围

把 1–100 改为 1–n,需要增加输入,并用 n 控制循环终点。

从偶数和到奇数和

把条件 i % 2 == 0 改为 i % 2 != 0。

思考:如何计算从 1 到 n 之间的奇数之和?

问题延伸:让AI帮助,但不替代思考

推荐问法:
“我已经知道如何求1到100之间偶数的和。现在想改成求1到n之间奇数的和。请不要直接给完整代码,先提示我需要修改哪些地方,并帮我设计3组测试数据。”

这比直接问“给我答案”更能帮助学习。

1.7 / AI协作与实验衔接
把课堂方法带到实验课:
先想、再问、运行、验证
AI协作六步法使用边界Pintia任务0

三种使用AI的学生

A:直接复制

“给我答案。”

复制 → 提交

B:用AI纠错

先自己写

发现错误 → 问AI原因 → 修改

C:用AI协作

先分析 → 再编码

让AI检查边界 → 自己测试与判断

谁真正学到了东西?

AI协作编程六步法

① 先想
→
② 再问
→
③ 看懂
→
④ 运行
→
⑤ 验证
→
⑥ 修改

本课程允许AI,但有边界

使用方式 态度
让AI解释概念、编译错误 鼓励
让AI给提示、检查自己的代码 强烈鼓励
让AI生成测试数据、比较方案 鼓励
AI生成代码后,自己分析、修改、验证 可以
复制自己无法解释的AI代码 不接受
把整个作业交给AI,自己不参与 不接受
不测试、不核验就提交AI结果 不接受

人与AI怎样分工?

人负责

  • 理解问题和目标
  • 决定采用什么方案
  • 判断结果是否可信
  • 设计测试并核验
  • 解释最终程序
  • 对提交结果负责

AI负责辅助

  • 解释知识
  • 给出思路和示例
  • 生成或补全代码
  • 提示错误原因
  • 提出测试建议
  • 比较不同实现方式

课堂任务:同一道题,做两次

输入长方形的长和宽,计算面积和周长。

第一轮:不用AI · 3分钟

只写三行:

输入:……

处理:……

输出:……

第二轮:允许AI

把自己的思路告诉AI,让AI辅助完成程序。

前提:你必须看懂并能解释。

推荐提示词模板

我正在第一次学习C语言。请根据下面的算法帮助我编写C程序。

1. 不要使用我还没有学习过的高级语法;
2. 程序只需要包含输入、计算和输出;
3. 请先解释你的实现思路,再给出代码;
4. 最后给出3组用于检查程序是否正确的测试数据。

我的算法:……

第一次实验衔接:五题开放,自主推进

环境检查
→
五题开放
→
按序完成
→
固定检查点
→
课后继续

允许教材、课件和手机AI助手;要求自己能看懂、能运行、能验证。

任务0:我的第一次AI协作编程

① 问题
例如:输入摄氏温度,转换为华氏温度。
② 我的思路
不超过100字,说明输入、处理和输出。
③ 给AI的问题
保留提示词。
④ AI给出的代码
保留初始版本。
⑤ 我的修改
说明改了什么、为什么改。
⑥ 测试
至少3组测试数据。
⑦ 一句话反思
AI帮助了我什么?哪一步仍必须由我完成?

本章要点总结

  • 程序:为解决问题而设计的一系列指令或步骤。
  • 程序设计语言:用于表达数据、处理过程、输入输出和模块化组织。
  • C程序框架:由一个或多个函数组成,必须有 main 主函数。
  • 结构化控制:顺序、分支、循环是程序组织的基本方式。
  • 编译运行:源程序需要经过编译、链接,才能形成可执行程序。
  • 问题求解:核心是先分析问题和设计算法,再编写、运行和验证程序。
  • AI协作:AI可以辅助,但不能替代理解、判断、测试和责任。

课后任务建议

教材阅读

  • 复习第1章程序、指令和语言功能
  • 阅读C程序基本结构
  • 理解编译、运行、调试基本流程

上机准备

  • 完成Pintia第一次实验五道入门题
  • 保留一次AI协作记录
  • 记录一个自己遇到并解决的错误
本章结束语:

AI可以帮你写代码,
但不能替你理解问题、判断结果、解释程序并为最终结果负责。