引言
在 C语言 中,0 表示假,非0 表示真。 了解这一点很重要,因为很多变量出现在分支和循环的判断框中。常见的有 if 和 while.
#include <stdio.h> int main() { int a = -3; if (a) { printf("aaa\n"); } else { printf("bbb\n"); } return 0; }
输出结果:
一、if 语句
1. 场景1
程序清单:if - else
#include <stdio.h> int main() { int a = -3; if (a) { printf("aaa\n"); }else{ printf("bbb\n"); } return 0; } // 输出结果:aaa
2. 场景2
程序清单:if - else if… - else
#include <stdio.h> int main() { int a = 99; if (a >= 0 && a <= 9) { printf("个\n"); } else if(a >= 10 && a <= 99) { printf("十\n"); } else if(a >= 100 && a <= 999) { printf("百\n"); } else { printf("其他\n"); } return 0; } // 输出结果:十
3. 场景3
程序清单:if - return
#include <stdio.h> int test() { int a = 0; if (a) { return 1; } return -1; } int main() { int ret = test(); printf("%d\n", ret); } // 输出结果:-1
4. 场景4
#include <stdio.h> int main() { int a = 0; int b = 2; if (a == 1) if (b == 2) printf("hehe\n"); else printf("haha\n"); return 0; } // 输出结果:无结果
上面的程序显然是代码编写的问题,才导致的歧义。实际上,在我们日常写代码的时候,一个 if 就对应着一个 else. 但在大学考试的时候,可能就会碰到这种无聊的题目,那么我们就应该明白:else 是和它离的最近的 if 匹配的。
二、switch 语句
程序清单:
#include <stdio.h> int main() { int day = 0; scanf("%d", &day); switch (day) { case 1: printf("星期一\n"); case 2: printf("星期二\n"); case 3: printf("星期三\n"); case 4: printf("星期四\n"); case 5: printf("星期五\n"); case 6: printf("星期六\n"); case 7: printf("星期七\n"); default: printf("输入错误!\n"); } return 0; }
输出结果:
程序清单:
#include <stdio.h> int main() { int day = 0; scanf("%d", &day); switch (day) { case 1: printf("星期一\n"); break; case 2: printf("星期二\n"); break; case 3: printf("星期三\n"); break; case 4: printf("星期四\n"); break; case 5: printf("星期五\n"); break; case 6: printf("星期六\n"); break; case 7: printf("星期七\n"); break; default: printf("输入错误!\n"); break; } return 0; }
总结语法:
switch(整型表达式) { case 整型常量表达式: { 语句; } case 整型常量表达式: { 语句; } case 整型常量表达式: { 语句; } ... }
注意事项:
① switch 括号内、case 后 必须是整型类型的数据,否则就会报错。
② default 表示不匹配所有的 case 标签,通常放在 switch 语句最后。default 可根据场景自己设定,可不加。
③ case 决定 switch 语句的入口,break 决定 switch 语句的出口。
三、while 语句
1. 场景1
while 循环搭配 break 关键字 ( break 用于跳过整个循环 )
#include <stdio.h> int main() { int n = 0; while (n < 10) { n++; if (n == 5) { break; } printf("%d ", n); } return 0; } // 输出结果:1 2 3 4
2. 场景2
while 循环搭配 continue 关键字 ( continue 用于跳过本次循环 )
#include <stdio.h> int main() { int n = 0; while (n < 10) { n++; if (n == 5) { continue; } printf("%d ", n); } return 0; } // 输出结果:1 2 3 4 6 7 8 9 10
3. 场景3
getchar 循环输入 ( getchar 返回类型是 int,每次读取一个字符,如果未读到字符,就返回 EOF,即 -1. )
#include <stdio.h> int main() { int ch = 0; while ( (ch = getchar()) != EOF ) { putchar(ch); } return 0; }
测试结果:( Ctrl + Z 停止循环输入 )
scanf 循环输入 ( getchar 返回值是 int,如果读到一个字段数据,就返回1;读到两个字段数据,就返回2;如果未读到字符,就返回 EOF,即 -1. )
```c #include <stdio.h> int main() { int ch = 0; while (scanf("%d", &ch) != EOF) { printf("%d\n", ch); } return 0; }
测试结果同上,不展示。
4. while 循环清空缓冲区数据
程序清单:
#include <stdio.h> int main() { char password[20] = { 0 }; printf("请输入密码:"); scanf("%s", password); printf("请确认密码:"); int ch = getchar(); if ('y' == ch) { printf("确认成功\n"); } else { printf("确认失败\n"); } return 0; }
程序清单:
#include <stdio.h> int main() { char password[20] = { 0 }; printf("请输入密码:"); scanf("%s", password); int tmp = 0; while ( (tmp = getchar()) != '\n') { ; } printf("请确认密码:"); int ch = getchar(); if ('y' == ch) { printf("确认成功\n"); } else { printf("确认失败\n"); } return 0; }
输出结果:
对比两个程序我们发现,第一个程序没有提示我们 " 确认密码 ",就直接输出了确认失败,这显然是因为 getchar 函数直接将我们的回车也读进去了。因为我们每次使用 scanf 函数的时候 ,最后都要点击键盘上的回车键,才能使 scanf 真正的输入。那么这是为什么呢?
其实,在程序和键盘之间,还有一个东西:缓冲区。 scanf 每次都是从缓冲区读取数据的,并且 getchar 也是如此。所以只要 getchar 在 scanf 读取后,再次从缓冲区读数据,就可能会读到缓冲区的 " 残留数据 \n 字符 "。
解决方案:所以后来,我们在第二个程序中加上了如下代码,即可以让 getchar 把缓冲区的所有字符读取完之后,程序就可以读取到真正由键盘键入的数据了。
int tmp = 0; while ( (tmp = getchar()) != '\n') { ; }
四、for 循环
for 循环和 while 循环大同小异,这里就一笔带过了。
#include <stdio.h> int main() { for (int i = 1; i <= 10; i++) { if (i == 5) { break; } printf("%d ", i); } return 0; } // 输出结果:1 2 3 4
注意事项:
① 在下面的 for 循环中," int i = 1 " 称为【初始化】,只会执行一次;" i<=10 " 称为【判断】;" i++ " 称为【调整】。
② 本质上,for 循环就是上面所说的三个核心要素,然而它们都可以省略,但最好不要这么做,因为当 for 循环嵌套使用的时候,就会容易出错。
for (int i = 1; i <= 10; i++) { }
五、do…while 循环
do…while 循环的应用场景较少,它的循环至少执行一次。
#include <stdio.h> int main() { int i = 1; do { if (i == 5) { break; } printf("%d ", i); i++; } while (i <= 10); return 0; } // 输出结果:1 2 3 4
二分查找
/* 二分查找 */ int find(int arr[], int size, int k) { int left = 0; int right = size - 1; while (left <= right) { int mid = (left + right) / 2; if (k == arr[mid]) { return mid; } else if (k > arr[mid]) { left = mid + 1; } else { right = mid - 1; } } return -1; } int main() { int arr[] = { 0,5,7,8,13,21,24,55,77,85,93,94,95,97 }; int size = sizeof(arr) / sizeof(arr[0]); // 计算数组长度 int k = 85; int ret = find(arr, size, k); if (ret == -1) { printf("参数出错\n"); }else { printf("数组下标:%d\n", ret); } } // 输出结果:【数组下标:9】
注意事项:
① 二分查找只能针对于有序数组 (升序 / 倒序)
② 关于求平均值,也可以采取下面的方式。
int mid = left + (right - left) / 2;