程序: 打印 Hello NJU
简单 C 程序的一般形式
注释
猜数字游戏
课堂挑战
#include <stdio.h>
int main(void)
{
printf("Hello, NJU!\n");
return 0;
}
#include: 预处理指令, 引入标准输入/输出库的头文件*stdio.h*
main函数: 主函数, 程序入口, 任何C程序都需要一个main函数
printf: 输出, \n为换行
return 0;: 程序正常结束, 向操作系统返回值0
代码存为 .c 文件 (假设文件名为hw.c)
编译: gcc hw.c 生成可执行程序a.out; gcc hw.c -o hw 指定生成hw
void 参数类型, 可省略
演示Hello NJU代码
一条 gcc hw.c 命令背后, 实际做了三件事:
预处理: 处理 # 开头的指令 (如 #include)
编译: 把 C 代码翻译成机器指令
链接: 把 printf 等库函数合到一起, 生成可执行程序
这三件事都交给 gcc, 我们只写代码
编译运行之后, 我们来解剖一下 C 程序长什么样:
指令
int main(void)
{
语句
}
C使用 \{ 和 \} 标识函数开始与结束
最简单的C程序包含三个关键的语言特性:
指令: 预处理指令
函数: 可执行代码块, main函数
语句: 程序执行时的命令
指令: 预处理指令, 在编译前修改程序内容的编辑命令, 示例:
#include <stdio.h>
以 # 开头, # 用于将C代码中的指令与其他代码区分开来
默认只占一行, 每条指令的结尾没有分号或者其他特殊标记
int main(void)
{
return 0;
}
main 是程序入口: 程序执行时, 系统自动调用main函数
main 函数是必须的, 不能写成Main或MAIN等
程序终止时向操作系统返回状态码: 0 表示正常终止 (没有 return 语句, 编译器会警告)
C程序是函数的集合, 函数由一系列语句构成
main 只是其中的一个函数, 由系统自动调用
printf 是库函数(library function): 由 C 语言实现提供, 由 #include 引入进来
程序员也可以自己编写函数, 给一段语句起名字; 函数调用 就是让函数执行分配给它的任务
术语函数源于数学: \(f(x) = x + 1\) 对应C代码 return x + 1;; 计算数值的函数用 return 语句来指定所返回的值
语句 是程序运行时要执行的命令, 示例:
printf("Hello, World!\n");
每条语句都以分号结尾 (复合语句例外; 指令通常只有一行且不以分号结尾)
printf 函数显示了一条字符串字面量(string literal)
显示结束, printf 函数不会自动跳转到下一行输出, 需要 \n 换行
程序是一串 token: 编译器认识的最小单位
printf("Height: %d\n", height); 可以拆成 7 个 token:
标识符 printf |
( |
字符串 "Height: %d\n" |
, |
标识符 height |
) |
; |
|---|
空白(空格、换行、制表符)只是分隔 token 的胶水
不能把 token 从中间拆开: fl oat 会报错
字符串字面量不能跨行
排版建议: 运算符两侧加空格、缩进显示嵌套、空行分隔逻辑单元
程序里还有写给人看的部分——注释:
/* hello.c: 我的第一个 C 程序
打印 Hello NJU
*/
#include <stdio.h> // 引入标准输入/输出库
int main(void)
{
printf("Hello, NJU!\n"); // 输出问候, \n 换行
return 0; // 程序正常结束
}
没有注释, 复杂的程序别人(包括一个月后的自己)很难看懂
注释: 写给人看的说明, 编译器会完全忽略
多行注释: /* 开头, */ 结尾, 可以跨行 (见代码顶部)
单行注释: // 开头, 行末结束 (见代码行尾)
忘记写 */ 会导致编译器忽略大片代码
小挑战: 猜猜这段程序的输出?
printf("My "); /* 忘记闭合这个注释
printf("cat ");
printf("has "); /* 注释在这里才结束 */
printf("fleas");
答案: 输出 My fleas——第一个 /* 把中间两行"吞"进注释, 直到遇到第一个 */
学了不少语法, 来见一个完整的程序——猜数字游戏:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main(void) {
int guess;
srand(time(NULL));
int answer = rand() % 100 + 1;
printf("猜一个数字(1-100):");
scanf("%d", &guess);
if (guess == answer)
printf("猜中啦!\n");
else if (guess < answer)
printf("太小了!\n");
else
printf("太大了!\n");
return 0;
}
程序在做什么:
三个 #include: stdio 提供 printf/scanf, stdlib 提供 rand/srand, time 提供 time
srand(time(...)): 用当前时间做随机种子
answer = rand() % 100 + 1: 悄悄生成 1~100 的随机答案
scanf 读你的猜测 → if/else 比较 → 猜中/小了/大了
想连续猜 7 次? 第 5 周学完循环自己改造!
今天学了很多——检验一下:
挑战: 打印你的名片
用 printf 输出一张个人名片, 至少包含:
比一比谁的名片最有个性!