前面咱们已经学过了基础数据类型以及数组和字符串,现在咱们来试试输入输出和控制流。
如果把写程序比作“教机器人办事”,那么数据类型只是它的记忆力(能记多少数),而输入输出是它的听说能力(能和你交流),控制流则是它的逻辑思考能力(能根据情况做决定)。
没有这两样,程序就是个只会死记硬背的傻瓜;有了它们,程序才有了灵魂。
C 语言的逻辑控制虽然比 Python 写起来繁琐一点(比如必须写括号 {}),但原理是完全通用的。如果你熟悉 Python 的 if 和 for,那 C 语言的控制流对你来说就是小菜一碟,只需要习惯一下分号 ; 和括号 {} 就行了。
一、输入输出(I/O):程序的口和耳
在 C 语言里,并没有内置的 print 或 input 关键字,所有的输入输出功能都是由标准库提供的,所以程序一开头都需要包含 stdio.h 头文件。
#include <stdio.h>
最常用的两个“大将”就是 printf(打印)和 scanf(扫描)。
1.1 说话的艺术:printf
printf 的名字是 "print formatted" 的缩写,意思是“格式化打印”。它不光能输出文字,还能像填空题一样,把变量填进句子里。
比如你经常能看到下面这样的代码:
printf("姓名: %s, 年龄: %d, 身高: %.2f米, 年级: %c\n", name, age, height, rank);
%s:填字符串(string)%d:填整数(decimal)%f:填浮点数(float)%c:填字符(character)
上面这些用户自定义的占位符,就像填空题里的空格,必须按顺序填上对应的数据。此外,你还可以通过“格式化指令”来控制输出的样式:比如用 %04d 给数字补零,用 %8d 调整对齐宽度,或者用 %.1f 精确控制小数点后的位数。具体的玩法,我们在后面的示例中会详细演示。
1.2 听话的技巧:scanf
scanf 是 printf 的逆操作,用来从键盘读取数据。但它有个初学者最大的坑:
注意: 除了字符串变量名本身就是地址外,读取其他基础类型变量时,必须在变量名前加 &(取地址符)!
比如 scanf("%d", &age),意思是你得告诉 scanf:“把读到的数存到 age 变量住的那个内存地址去”。如果你忘了加 &,程序可能会直接崩溃。
示例 1:基本的对话
#include <stdio.h>
int main() {
int age = 18;
double height = 1.75;
char name[20] = "张三";
char rank = 'A'; // 新增字符变量
// 1. 基本输出:printf
printf("=== 输出演示 ===\n");
// %c 用于输出单个字符
printf("姓名: %s, 年龄: %d, 身高: %.2f米, 成绩等级: %c\n", name, age, height, rank);
// 进阶:格式化控制
// %5d: 占5位宽度,右对齐
// %04d: 占4位宽度,不足补0
// %.1f: 保留1位小数
printf("\n=== 格式化控制演示 ===\n");
printf("编号: %04d (补零)\n", 7); // 输出: 0007
printf("存款: %8d (占位)\n", 100); // 输出: 100
printf("体重: %5.1f kg (精度)\n", 65.5); // 输出: 65.5
// 2. 基本输入:scanf
// 注意:
// - 除了字符串变量名本身就是地址外,其他变量前通常要加 & 取地址符
// - scanf 很“挑剔”,格式串里的空格、回车都要小心处理
int number;
printf("\n=== 输入演示 ===\n");
printf("请输入一个幸运数字: ");
// 尝试读取一个整数
// 返回值是成功读取的变量个数
if (scanf("%d", &number) == 1) {
printf("你输入的数字是: %d\n", number);
} else {
printf("输入格式错误,请确保输入的是数字!\n");
}
return 0;
}
运行结果:
=== 输出演示 ===
姓名: 张三, 年龄: 18, 身高: 1.75米, 成绩等级: A
=== 格式化控制演示 ===
编号: 0007 (补零)
存款: 100 (占位)
体重: 65.5 kg (精度)
=== 输入演示 ===
请输入一个幸运数字: 7
你输入的数字是: 7
二、控制流:程序的智慧
控制流决定了代码执行的顺序。就像交通指挥一样,有时需要直行(顺序执行),有时需要分岔(分支),有时需要转圈圈(循环)。
2.1 分支结构:岔路口的选择
最常用的分支就是 if-else,这和 Python 几乎一模一样,只是条件必须用 () 包起来,代码块必须用 {} 包起来。
示例 2:If-Else 条件判断
#include <stdio.h>
int main() {
int score;
printf("请输入考试成绩 (0-100): "); // 提示用户输入成绩
scanf("%d", &score); // 读取用户输入的成绩
printf("%d\n", score); // 输出用户输入的成绩
if (score >= 90) {
printf("优秀!保持住!\n");
} else if (score >= 75) {
printf("良好,继续加油。\n");
} else if (score >= 60) {
printf("及格,万岁!\n");
} else {
printf("不及格... 今晚别想看电视了。\n");
}
// 嵌套判断
if (score < 60) {
if (score >= 50) {
printf("(只差一点点,太可惜了)\n");
} else {
printf("(差距有点大,得好好补课了)\n");
}
}
return 0;
}
运行结果:
请输入考试成绩 (0-100): 85
良好,继续加油。
除了 if-else,C 语言还有一个 Python 没有的神器:switch-case。当你要针对一个变量的固定几个值做判断时(比如星期几、菜单选项),用 switch 会比一连串的 if-else 更清晰、更高效。
示例 3:Switch-Case 多选开关
#include <stdio.h>
int main() {
int day = 3; // 假设 1=周一, 7=周日
printf("今天是星期 %d\n", day);
printf("今天的安排是:");
switch (day) {
case 1:
printf("开周会,写周报。\n");
break; // 必须有 break,否则会“滑落”到下一层
case 2:
case 3:
case 4:
// 2,3,4 都会执行这里的代码
printf("努力搬砖写代码。\n");
break;
case 5:
printf("摸鱼,坐等下班。\n");
break;
case 6:
case 7:
printf("睡大觉!\n");
break;
default:
printf("输入错误,地球上没有星期%d!\n", day);
break;
}
return 0;
}
运行结果:
今天是星期 3
今天的安排是:努力搬砖写代码。
2.2 循环结构:不知疲倦的循环
计算机最擅长的就是重复劳动。C 语言提供了三种循环方式:
- for 循环:最常用,适合“知道要跑多少圈”的情况。
- while 循环:适合“不知道要跑多少圈,只知道什么时候停”的情况。
- do-while 循环:比较少见,特点是“先跑一圈再说”,保证循环体至少执行一次。
示例 4:三种循环对比
#include <stdio.h>
int main() {
// 1. for 循环:最适合已知次数的循环
printf("=== For 循环 (倒数3秒) ===\n");
for (int i = 3; i 0; i--) {
printf("%d...\n", i);
}
printf("发射!\n\n");
// 2. while 循环:适合条件未知、只知道什么时候停的循环
printf("=== While 循环 (存钱买房) ===\n");
int money = 0;
int goal = 20; // 目标20万
int year = 0;
while (money < goal) {
money += 5; // 每年存5万
year++;
printf("第 %d 年,存款 %d 万\n", year, money);
}
printf("终于买得起房子了!\n\n");
// 3. do-while 循环:先斩后奏,至少执行一次
printf("=== Do-While 循环 (尝试密码) ===\n");
int password;
int try_count = 0;
// 模拟用户输入:假设第三次才输对 (123456)
int mock_inputs[] = {111, 222, 123456};
do {
password = mock_inputs[try_count]; // 模拟输入
printf("尝试输入密码: %d -", password);
if (password == 123456) {
printf("解锁成功!\n");
} else {
printf("密码错误\n");
}
try_count++;
} while (password != 123456 && try_count < 3);
return 0;
}
运行结果:
=== For 循环 (倒数3秒) ===
3...
2...
1...
发射!
=== While 循环 (存钱买房) ===
第 1 年,存款 5 万
第 2 年,存款 10 万
第 3 年,存款 15 万
第 4 年,存款 20 万
终于买得起房子了!
=== Do-While 循环 (尝试密码) ===
尝试输入密码: 111 -密码错误
尝试输入密码: 222 -密码错误
尝试输入密码: 123456 -解锁成功!
2.3 循环控制:随时跳出
有时候我们需要在循环中途改变主意。这时候就需要用到 break(彻底跳出)和 continue(跳过本次),前者的意思是彻底不玩了,后者是跳过本次而开始玩下一次。
示例 5:Break 与 Continue
#include <stdio.h>
int main() {
printf("=== Break 与 Continue 演示 ===\n");
// 场景:吃馒头
// 一共10个馒头,第3个掉地上了(continue),吃到第8个吃撑了(break)
for (int i = 1; i <= 10; i++) {
if (i == 3) {
printf("第 %d 个馒头掉地上了,不吃,跳过!(continue)\n", i);
continue; // 直接进入下一次循环,后面代码不执行
}
if (i == 8) {
printf("吃到第 %d 个实在太撑了,不吃了!(break)\n", i);
break; // 直接跳出整个循环
}
printf("正在吃第 %d 个馒头... 真香。\n", i);
}
printf("循环结束,去散步消食。\n");
return 0;
}
运行结果:
=== Break 与 Continue 演示 ===
正在吃第 1 个馒头... 真香。
正在吃第 2 个馒头... 真香。
第 3 个馒头掉地上了,不吃,跳过!(continue)
正在吃第 4 个馒头... 真香。
正在吃第 5 个馒头... 真香。
正在吃第 6 个馒头... 真香。
正在吃第 7 个馒头... 真香。
吃到第 8 个实在太撑了,不吃了!(break)
循环结束,去散步消食。
总结
这次咱们介绍了输入输出和控制流的简单内容,具体来说包括下面的内容:
- 输入输出:用
printf说话,用scanf听话。记得scanf读非字符串变量时要加&。 - 分支:用
if-else处理一般判断,用switch处理多选一。 - 循环:用
for处理计数,用while处理条件。 - 跳转:用
break彻底出局,用continue跳过本次。
掌握了这些,你写的代码就应该能根据情况灵活应变了。接下来,可以尝试用这些积木搭建更复杂的逻辑,比如写一个文本的小游戏。
CycleUser