一、选择结构典型应用场景
1. 语法回顾
- 基础分支 :
if...else...→ 二选一逻辑 - 链式多分支 :
if...else if...else...→ 多区间判断 - 多值匹配分支 :
switch...case→ 固定值匹配,需break防止穿透
2. 场景 1:成绩等级划分
讲解 :根据分数区间划分等级,是if...else if...的典型应用。
#include <stdio.h>
int main() {
int score;
printf("请输入成绩:");
scanf("%d", &score);
if (score >= 90 && score <= 95)
printf("等级A\n");
else if (score >= 85 && score <= 89)
printf("等级B\n");
else if (score < 85)
printf("等级C\n");
else
printf("成绩输入无效\n");
return 0;
}
3. 场景 2:简易计算器
讲解 :用switch根据运算符执行不同运算,适合固定值分支。
#include <stdio.h>
int main() {
char op;
double a, b;
printf("输入表达式(如 3+5):");
scanf("%lf%c%lf", &a, &op, &b);
switch(op) {
case '+': printf("=%.2lf\n", a+b); break;
case '-': printf("=%.2lf\n", a-b); break;
case '*': printf("=%.2lf\n", a*b); break;
case '/':
if(b!=0) printf("=%.2lf\n", a/b);
else printf("除数不能为0\n");
break;
default: printf("运算符无效\n");
}
return 0;
}
二、循环结构核心题型
1. 数字特征类
(1)水仙花数(3 位数)
讲解:遍历 100~999,拆分各位数字,验证立方和是否等于自身。
#include <stdio.h>
int main() {
int i, g, s, b;
for(i=100; i<=999; i++) {
g = i%10; // 个位
s = i/10%10; // 十位
b = i/100; // 百位
if(g*g*g + s*s*s + b*b*b == i)
printf("%d 是水仙花数\n", i);
}
return 0;
}
(2)素数判断
讲解 :素数只能被 1 和自身整除,只需遍历到sqrt(n)即可优化效率。
#include <stdio.h>
#include <math.h>
int isPrime(int n) {
if(n<2) return 0;
int i;
for(i=2; i<=sqrt(n); i++)
if(n%i == 0) return 0;
return 1;
}
int main() {
int n;
printf("输入一个数:");
scanf("%d", &n);
if(isPrime(n))
printf("%d 是素数\n", n);
else
printf("%d 不是素数\n", n);
return 0;
}
2. 数列与求和类
(1)1+2+...+n 累加
讲解:循环累加或用公式,是最基础的循环求和。
#include <stdio.h>
int main() {
int n, i, sum=0;
printf("输入n:");
scanf("%d", &n);
for(i=1; i<=n; i++)
sum += i;
printf("1+2+...+%d = %d\n", n, sum);
return 0;
}
(2)交错级数(π/4 近似)
讲解 :正负交替,用sign变量切换符号,实现1 - 1/3 + 1/5 - 1/7...。
#include <stdio.h>
int main() {
int i, sign=1;
double pi=0;
for(i=1; i<=10000; i+=2) {
pi += sign * 1.0/i;
sign = -sign;
}
printf("π ≈ %.4lf\n", pi*4);
return 0;
}
(3)最大公约数 & 最小公倍数
讲解:辗转相除法求最大公约数,再用公式求最小公倍数
#include <stdio.h>
// 最大公约数(辗转相除法)
int gcd(int a, int b) {
while(b != 0) {
int temp = a%b;
a = b;
b = temp;
}
return a;
}
int main() {
int a, b;
printf("输入两个数:");
scanf("%d%d", &a, &b);
int g = gcd(a,b);
int lcm = a*b/g;
printf("最大公约数:%d\n最小公倍数:%d\n", g, lcm);
return 0;
}
3. 经典趣味算法
(1)循环打印图形(直角三角形)
讲解:双层循环,外层控制行数,内层控制每行字符数。
#include <stdio.h>
int main() {
int i, j;
for(i=1; i<=5; i++) { // 5行
for(j=1; j<=i; j++) // 第i行打印i个*
printf("*");
printf("\n");
}
return 0;
}
(2)鸡兔同笼
讲解:枚举法遍历鸡的数量,验证头数和脚数约束。
#include <stdio.h>
int main() {
int heads=35, legs=94; // 总头数、总脚数
int chicken, rabbit;
for(chicken=0; chicken<=heads; chicken++) {
rabbit = heads - chicken;
if(2*chicken + 4*rabbit == legs)
printf("鸡:%d只,兔:%d只\n", chicken, rabbit);
}
return 0;
}
(3)爬楼梯问题(变形斐波那契)
讲解:每次可爬 1 或 2 阶,第 n 阶的方法数 = 第 n-1 阶 + 第 n-2 阶。
#include <stdio.h>
int climbStairs(int n) {
if(n<=2) return n;
int a=1, b=2, c, i;
for(i=3; i<=n; i++) {
c = a + b;
a = b;
b = c;
}
return b;
}
int main() {
int n;
printf("输入台阶数:");
scanf("%d", &n);
printf("爬法数:%d\n", climbStairs(n));
return 0;
}
三、函数核心知识点
1. 函数结构
讲解 :函数由函数首部 (返回值类型 + 函数名 + 参数)和函数体(逻辑实现)组成,实现代码复用。
返回值类型 函数名(参数列表) {
// 函数体:变量定义、逻辑处理
return 返回值; // 无返回值用void,省略return
}
2. 参数传递方式
-
传值调用:函数内修改形参,不影响实参(适合不需要修改原变量的场景)
-
传址调用:传递变量地址,函数内可直接修改实参(适合需要修改原变量或传递大数据的场景)
#include <stdio.h>
// 传值调用:交换失败,因为只修改了形参
void swapByValue(int a, int b) {
int temp = a;
a = b;
b = temp;
}
// 传址调用:交换成功,通过指针修改实参
void swapByAddress(int *a, int *b) {
int temp = *a;
*a = *b;
*b = temp;
}
int main() {
int x=3, y=5;
swapByValue(x,y);
printf("传值后:x=%d, y=%d\n", x,y); // 仍为3,5
swapByAddress(&x,&y);
printf("传址后:x=%d, y=%d\n", x,y); // 变为5,3
return 0;
}