目录
[2.1 if 语句](#2.1 if 语句)
[单分支 if](#单分支 if)
[双分支 if-else](#双分支 if-else)
[多分支 if-else if](#多分支 if-else if)
[2.2 switch 语句](#2.2 switch 语句)
[3.1 for 循环](#3.1 for 循环)
[3.2 while 循环](#3.2 while 循环)
[3.3 do-while 循环](#3.3 do-while 循环)
[3.4 for vs while 对比](#3.4 for vs while 对比)
[4.1 统计范围内能被6和8整除的数](#4.1 统计范围内能被6和8整除的数)
[4.2 整数反转](#4.2 整数反转)
[4.3 判断整数是否为回文数](#4.3 判断整数是否为回文数)
[4.4 判断字符串是否为回文](#4.4 判断字符串是否为回文)
[4.5 用循环实现乘除法](#4.5 用循环实现乘除法)
[5.1 打印图形](#5.1 打印图形)
[5.2 九九乘法表](#5.2 九九乘法表)
[5.3 统计质数(1-100)](#5.3 统计质数(1-100))
[5.4 计算 1¹ + 2² + 3³ + ... + 10¹⁰](#5.4 计算 1¹ + 2² + 3³ + ... + 10¹⁰)
[6、跳出循环与 goto](#6、跳出循环与 goto)
[6.1 break 和 continue](#6.1 break 和 continue)
[6.2 goto 语句](#6.2 goto 语句)
[7.1 水仙花数(三位数)](#7.1 水仙花数(三位数))
[7.2 完数](#7.2 完数)
1、顺序结构
定义:程序从上往下依次执行,是程序默认的执行方式。
cpp
// 示例
int a = 10;
int b = 20;
int sum = a + b;
printf("%d\n", sum); // 按顺序依次执行
2、分支结构
程序执行过程中根据条件选择不同的执行路径。
2.1 if 语句
单分支 if
cpp
if (关系表达式) {
语句体;
}
// 关系表达式成立(为真)时执行语句体
双分支 if-else
cpp
if (关系表达式) {
语句体A;
} else {
语句体B;
}
// 关系表达式成立执行A,否则执行B
多分支 if-else if
cpp
if (关系表达式1) {
语句体A;
} else if (关系表达式2) {
语句体B;
} else if (关系表达式3) {
语句体C;
} else {
语句体N;
}
⚠️ 注意:
- 不加花括号时,
else会匹配最近一个同级的if - 建议始终使用花括号,避免歧义
cpp
// ❌ 容易出错的写法
if (a > 0)
if (b > 0)
printf("1");
else // 这个else匹配的是内层if,不是外层if
printf("2");
// ✅ 推荐写法
if (a > 0) {
if (b > 0) {
printf("1");
}
} else {
printf("2");
}
2.2 switch 语句
cpp
switch (表达式) {
case 值1:
语句体1;
break;
case 值2:
语句体2;
break;
...
default:
语句体n;
break; // default后的break可省略(通常在最后)
}
执行流程:
- 计算表达式的值
- 依次与
case后的值比较,匹配则执行相应语句 - 遇到
break结束switch,否则继续执行后续case(case穿透) - 所有
case都不匹配时,执行default
⚠️ 注意事项:
switch表达式只能是整数类型(int、char、enum等)case后的值必须是常量表达式- 每个
case后建议加break,避免意外穿透
cpp
// case穿透示例(有意为之)
switch (month) {
case 1: case 3: case 5: case 7: case 8: case 10: case 12:
days = 31;
break;
case 4: case 6: case 9: case 11:
days = 30;
break;
case 2:
days = 28;
break;
}
3、循环结构
重复执行某段代码,直到满足结束条件。
3.1 for 循环
cpp
for (初始化语句; 条件判断语句; 条件控制语句) {
循环体语句;
}
| 部分 | 说明 | 执行时机 |
|---|---|---|
| 初始化语句 | 设置循环初始状态 | 循环开始前执行一次 |
| 条件判断语句 | 循环继续的条件 | 每次循环前判断 |
| 条件控制语句 | 更新循环变量 | 每次循环体执行后 |
| 循环体语句 | 要重复执行的代码 | 条件为真时执行 |
执行流程:
cpp
初始化 → 条件判断 → (真)循环体 → 条件控制 → 条件判断 → ...
↓
(假)结束
灵活写法:
cpp
// 方式一:初始化在外部
int i = 1;
for (; i <= 100; i++) {
printf("hello world\n");
}
// 方式二:标准写法
for (int i = 1; i <= 100; i++) {
printf("hello world\n");
}
// 方式三:省略部分(无限循环)
for (;;) {
// 需要手动break退出
}
3.2 while 循环
cpp
初始化语句;
while (条件判断语句) {
循环体语句;
条件控制语句;
}
适用场景:不知道循环次数,只知道结束条件
3.3 do-while 循环
cpp
初始化语句;
do {
循环体语句;
条件控制语句;
} while (条件判断语句);
执行流程:
初始化 → 循环体 → 条件控制 → 条件判断 → (真)循环体 → ...
↓
(假)结束
⚠️ 注意 :do-while 至少执行一次循环体
3.4 for vs while 对比
| 特性 | for 循环 | while 循环 |
|---|---|---|
| 适用场景 | 已知循环次数或范围 | 未知循环次数,只知结束条件 |
| 结构 | 三部分集中声明 | 分散声明 |
| 运行规则 | 相同 | 相同 |
4、循环应用示例
4.1 统计范围内能被6和8整除的数
cpp
// 1. 键盘录入两个数字
int num1, num2;
printf("请录入两个整数:\n");
scanf("%d %d", &num1, &num2);
// 2. 确定范围(处理大小顺序)
int min = num1 < num2 ? num1 : num2;
int max = num1 > num2 ? num1 : num2;
// 3. 统计个数
int count = 0;
for (int i = min; i <= max; i++) {
if (i % 6 == 0 && i % 8 == 0) { // 等价于 i % 24 == 0
count++;
}
}
// 4. 打印结果
printf("在这个范围当中,既能被6整除又能被8整除的数字一共有%d个\n", count);
4.2 整数反转
cpp
int number = 123;
int rev = 0;
// 循环结束条件:number == 0
while (number != 0) {
int temp = number % 10; // 获取最后一位
number = number / 10; // 去掉最后一位
rev = rev * 10 + temp; // 拼接到rev
}
printf("%d\n", rev); // 输出:321
执行过程追踪(以456为例):
| 轮次 | temp | number | rev |
|---|---|---|---|
| 1 | 6 | 45 | 6 |
| 2 | 5 | 4 | 6×10+5=65 |
| 3 | 4 | 0 | 65×10+4=654 |
4.3 判断整数是否为回文数
cpp
#include <stdio.h>
int main() {
int num, original, reversed = 0, remainder;
printf("请输入一个整数:");
scanf("%d", &num);
original = num; // 保存原始值
// 反转数字
while (num != 0) {
remainder = num % 10; // 获取最后一位
reversed = reversed * 10 + remainder; // 构建反转数
num /= 10; // 去掉最后一位
}
// 判断是否回文
if (original == reversed) {
printf("%d 是回文数。\n", original);
} else {
printf("%d 不是回文数。\n", original);
}
return 0;
}
4.4 判断字符串是否为回文
cpp
#include <stdio.h>
#include <string.h>
int main() {
char str[100];
int i, length;
int isPalindrome = 1; // 假设是回文
printf("请输入一个字符串:");
scanf("%s", str);
length = strlen(str);
// 从两端向中间比较字符
for (i = 0; i < length / 2; i++) {
if (str[i] != str[length - i - 1]) {
isPalindrome = 0; // 发现不同,不是回文
break;
}
}
if (isPalindrome) {
printf("%s 是回文字符串。\n", str);
} else {
printf("%s 不是回文字符串。\n", str);
}
return 0;
}
4.5 用循环实现乘除法
cpp
// 乘法:a × b = a + a + ... + a(共b次)
int multiply(int a, int b) {
int result = 0;
for (int i = 0; i < b; i++) {
result += a;
}
return result;
}
// 除法:a ÷ b,通过不断减b计算商和余数
int divide(int a, int b, int *remainder) {
int quotient = 0;
while (a >= b) {
a -= b;
quotient++;
}
*remainder = a;
return quotient;
}
// 示例:11 ÷ 3
// 11 - 3 = 8 → 第1次
// 8 - 3 = 5 → 第2次
// 5 - 3 = 2 → 第3次
// 结果:商 = 3,余数 = 2
5、嵌套循环
5.1 打印图形
cpp
// 倒三角
for (int i = 1; i <= 5; i++) {
for (int j = i; j <= 5; j++) { // 每行(6-i)个*
printf("*");
}
printf("\n");
}
/* 输出:
*****
****
***
**
*
*/
// 正三角
for (int i = 1; i <= 5; i++) {
for (int j = 1; j <= i; j++) { // 每行i个*
printf("*");
}
printf("\n");
}
/* 输出:
*
**
***
****
*****
*/
5.2 九九乘法表
cpp
for (int i = 1; i <= 9; i++) {
for (int j = 1; j <= i; j++) {
printf("%d × %d = %d\t", j, i, i * j);
}
printf("\n");
}
5.3 统计质数(1-100)
cpp
// 质数:大于1的自然数,除了1和它本身外没有其他因数
int count = 0;
for (int i = 2; i <= 100; i++) {
int isPrime = 1; // 假设是质数
// 优化:只需判断到 sqrt(i)
for (int j = 2; j * j <= i; j++) {
if (i % j == 0) {
isPrime = 0; // 找到因子,不是质数
break;
}
}
if (isPrime) {
count++;
}
}
printf("1-100共有%d个质数\n", count); // 输出:25
5.4 计算 1¹ + 2² + 3³ + ... + 10¹⁰
cpp
long long res = 0;
for (int i = 1; i <= 10; i++) {
long long pow = 1;
for (int j = 1; j <= i; j++) {
pow = pow * i;
}
res = res + pow;
}
printf("%lld\n", res);
6、跳出循环与 goto
6.1 break 和 continue
| 关键字 | 作用 | 适用 |
|---|---|---|
break |
跳出当前循环 | for/while/do-while/switch |
continue |
跳过本次循环,进入下一次 | for/while/do-while |
6.2 goto 语句
cpp
// 标号定义
label_name:
语句;
// 跳转使用
goto label_name;
⚠️ 注意 :goto 会破坏代码结构
cpp
// 跳出多层循环的替代方案(推荐用标志位)
int found = 0;
for (int i = 0; i < 10 && !found; i++) {
for (int j = 0; j < 10 && !found; j++) {
if (condition) {
found = 1;
}
}
}
7、枚举思想
定义:列举问题的所有可能性,逐一检查是否符合要求。
7.1 水仙花数(三位数)
各位数字的立方和等于该数本身(如 153 = 1³ + 5³ + 3³)
方法一:单循环拆位
cpp
#include <stdio.h>
int main() {
printf("所有水仙花数:\n");
for (int num = 100; num <= 999; num++) {
int a = num / 100; // 百位
int b = (num / 10) % 10; // 十位
int c = num % 10; // 个位
if (num == a*a*a + b*b*b + c*c*c) {
printf("%d ", num);
}
}
return 0;
}
方法二:三重循环枚举
cpp
for (int a = 1; a <= 9; a++) { // 百位:1-9
for (int b = 0; b <= 9; b++) { // 十位:0-9
for (int c = 0; c <= 9; c++) { // 个位:0-9
int num = 100*a + 10*b + c;
if (num == a*a*a + b*b*b + c*c*c) {
printf("%d\n", num);
}
}
}
}
7.2 完数
定义:一个正整数,它除了自身之外的所有正因数(真因数)之和等于它本身。
- 例如:6 = 1 + 2 + 3,28 = 1 + 2 + 4 + 7 + 14
基础版本:
cpp
#include <stdio.h>
int main() {
int n;
printf("请输入一个正整数:");
scanf("%d", &n);
printf("%d以内的完数有:", n);
int count = 0;
for (int i = 1; i <= n; i++) {
int sum = 0;
// 找出所有真因数
for (int j = 1; j < i; j++) {
if (i % j == 0) {
sum += j;
}
}
if (sum == i) {
printf("%d ", i);
count++;
}
}
if (count == 0) {
printf("没有完数");
}
printf("\n");
return 0;
}
优化版本:
cpp
#include <stdio.h>
int main() {
int n;
printf("请输入一个正整数:");
scanf("%d", &n);
printf("%d以内的完数有:", n);
int count = 0;
// 1不是完数,从2开始
for (int i = 2; i <= n; i++) {
int sum = 1; // 1一定是真因数
// 优化:只需遍历到 i/2
for (int j = 2; j <= i / 2; j++) {
if (i % j == 0) {
sum += j;
}
}
if (sum == i) {
printf("%d ", i);
count++;
}
}
if (count == 0) {
printf("没有完数");
}
printf("\n");
return 0;
}