分支流控制
for循环
语法点:
- 循环头的标准语法是: for(表达式1 ; 表达式2 ; 表达式3)
- 表达式1一般用来初始化循环控制变量
- 表达式2一般用来作为循环判定条件,为真则进入循环,为假则跳出循环
- 表达式3一般用来更新循环控制变量
- 三个表达式均可以省略,但分号不能省略
for(;;)
死循环(相当于while(1))
示例:
// 循环输出一系列整数,直到100为止
int a;
for(a=30; a<=100; a++)
{
printf("%d\n", a);
}
练习九九乘法表:
#include <stdio.h>
int main(int argc, const char* argv[]) {
for ( int i = 1; i <= 9; i++ ) {
for ( int j = 1; j <= i; j++ ) {
printf("%d * %d = %d \t", i, j, i * j);
}
printf("\n");
}
return 0;
}
while 语句
语法: while(条件判别式) { 循环的代码块 }
练习: 输入一个数字, 计算他有多少位. 例: 1247 返回 4
int len = 0; // 数字的长度
while (num > 0)
{
num /= 10;
len++;
}
for( ; num > 0; num /= 10) {
len++;
}
while 与 for区别
- 一般情况下for循环和while循环区别在于,while更注重循环条件(次数不明确推荐使用while), for更注重循环的次数(次数明确推荐使用for),当然他们可以相互替换
- for(表达式1;表达式2;表达式3)的表达式1、2、3都可以省略,当2省略时默认为true就是死循环,while(表达式)语句表达式不能为空
练习: 输入两个数字num,pos分别表示长整数num和想要获取的的指定位数pos,打印num指定位pos的值是多少,
思路:将想要的数值移到个位上,在通过对 10 取余就可以获取个位上的数了,移动的次数和指定的次数是一致的。
for (int i = 1; i < pos; i++)
{
num /= 10;
}
printf("第%d的值为%d",pos, num % 10);
#include <stdio.h>
int main(int argc, const char* argv[]) {
int mun = 987654;
int n;
scanf("%d", &n);
int res;
while ( n ) {
res = mun % 10; // 获取到最后一位
mun /= 10; // 移除最后一位
printf(" res = %d , mun = %d \n", res, mun);
n--;
}
printf("%d \n", res);
return 0;
}
升级版
#include <stdio.h>
int main(int argc, const char* argv[]) {
int num = 987654;
printf("输入一个整数: \n");
// 确保输入的正确性
while ( scanf("%d", &num) == 0 ) {
printf("输入错误,重新输入\n");
// 清空那些错误输入,如果不清空 scanf 会一直获取到错误数据,导致死循环
while ( getchar() != '\n' ) { } // 注意这里的 '\n' 也会给 getchar() 接收
}
// 如果上面输入的是数字开头的数据,整数部分会被上面的 scanf 接收,多出出来的那一部分,还在缓冲区中,就会导致下一个scanf 获取到不合理的数据
while ( getchar() != '\n' ) { } // 注意这里的 '\n' 也会给 getchar() 接收
printf("输入一个位数: \n");
int pos;
while ( scanf("%d", &pos) == 0 ) {
printf("输入错误,重新输入\n");
while ( getchar() != '\n' ) { } // 注意这里的 '\n' 也会给 getchar() 接收
}
// 校验 pos 长度是否合理
int cpNum = num;
int count = 1;
while ( cpNum /= 10 ) {
count++;
}
printf("%d \n", count);
if ( pos > count ) {
printf("位数过大无法获取\n");
}
cpNum = num;
int n = pos;
while ( n > 1 ) {
cpNum /= 10;
n--;
}
printf("num = %d , n = %d , res = %d \n", num, pos, cpNum % 10);
return 0;
}
do{}while
语法: do{循环代码块}while(表达式)
do...while循环跟while相似,区别在于无论判别表达式是否为真do...while内部的表达都会先执行一次后再循环判断
do{}while 特点一定会执行一次。
do
{
num /= 10;
len++;
} while (num > 0); // 注意这里一定要有一个分号
break与continue
逻辑:
break
:① 跳出 switch 语句; ② 跳出当前层的循环体
int flag = 0; // 标记跟随循环记录,当前数组能否被其他数字整除,只要有整除我们将flag从0设为1
for (int i = 2; i < num; i++)
{
// 如果找到一个数能整除输入的数字,没有必要继续循环查找下去了,使用break关键字退出for循环
if (num % i == 0)
{
flag = 1;
break; // 结束当前循环
}
printf("i = %d",i);
}
continue
:结束当次循环,进入下次循环
// 输入一个数字打印从0开始到输入数子中所有能被3整除的数字,不能被三整除的数字打印 printf("正在遍历谁 %d \n",i);
for(int i = 1; i <= num; i++) {
if(i % 3 == 0) {
printf("%d \n", i);
continue;
}
printf("正在遍历谁 %d \n",i);
}
goto语句: 无条件跳转语言
语法
goto 语句标号; // 这个程序就会直接跳转到语句标号的未知开始执行
例子
int num = 0;
int res = scanf("%d", &num);
if (res != 1) // 输入字符不合法
{
goto err;
}
printf("你输入的是%d", num);
err:
return 0;
例子: 使用goto配合条件控制语句实现循环的效果
#include <stdio.h>
int main(int argc, const char* argv[]) {
// 找出 0 - 100 中相加,可以被 33 整除的 , 只要第一个
for ( int i = 1; i < 10; i++ ) {
for ( int j = 1; j < 10; j++ ) {
if ( 33 % (i + j) == 0 ) {
printf("i = %d , j = %d \n", i, j);
// break;
goto start;
}
}
}
start:
printf("end");
return 0;
}
注意:
- goto本身没有任何意义,但是goto语句是无条件跳转语句,应用太灵活会使得程序可读性变差,应限制使用
- goto语句只能在函数内进行跳转,不可以跨跃函数
- goto语句一般用于代码出现异常时,直接跳转到异常处理的代码段.比如说多层循环嵌套出现异常时使用goto直接跳出多层循环
二路分支
- 逻辑:程序中某段代码需要在满足某个条件时才能运行
- 形式:
- if 语句:表达一种 如果-则 的条件执行关系
- if-else 语句:表达一种 如果-否则 的互斥分支关系
- 举例:
// if 语句
if(a%2 == 0)
{
printf("a是偶数\n");
}
//if-else 语句
if(a%2 == 0)
{
printf("a是偶数\n");
}
else
{
printf("a是奇数\n");
}
- 注意:
if 语句可以单独使用,else 语句不可以,else 语句必须跟if语句配套使用
不管是 if 语句还是 else 语句,代码块都必须使用大括号{}括起来,否则只有首句有效
多路分支
if-else
if语句
if(num >= 90)
printf("优秀 \n");
else if (num >= 80) // 若上面表达式不满足才会进行这里表达式判断
printf("良好 \n");
else if (num >= 70)
printf("中等 \n");
else if (num >= 60)
printf("及格 \n");
else // if - else-if 语句中 else可有可无,局根据真实开发需求
printf("不及格 \n");
switch
语句
printf("请输入一个wsad分析行为\n");
char num;
while (1)
{
scanf("%[wsad]", &num);
switch (num)
{
case 'w':
printf("跳 \n");
break;
case 's':
printf("蹲 \n");
break;
case 'a':
printf("后 \n");
break;
case 'd':
printf("前 \n");
break;
default: // default在switch 一般一定要写,处理异常当以上条件都不满足时
printf("异常 \n");
}
getchar();
num = '0';
}
要点解析:
- switch(n) 语句中的 n 必须是一个整型表达式,即 switch 判断的数据必须是整型
- case 语句只能带整型常量,包括普通整型或字符。
- break 语句的作用是跳出整个 swtich 结构,没有 break 程序会略过case往下执行
- default 语句不是必须的,一般放在最后面(因此不需要 break)
小技巧:
-
当循环或者分支结构的代码只有一行的代码使用可以省略 {} 括号 , 将 最近的那一行 (有且只能有一行代码) 的作为循环体等。int a = 10 ;
int b = 20 ; if(a != b ) printf("a 不等于 b "); printf("执行结束"); // 注意这一行代码不属于 if 语句。
-
利用 switch 中 case 遇到 break 才停的特点,可以把一些相同的逻辑的 case 放在一起, case 与 case 之间不要使用 break 。
int n = 1; switch ( n ) { case 2: case 3: case 4: printf("春季\n"); break; case 5: case 6: case 7: printf("夏季\n"); break; case 8: case 9: case 10: printf("秋季\n"); break; case 11: case 12: case 1: printf("冬季\n"); break; default: break; }
-
使用 while + getchar 来清空缓冲区
while (getchar() != '\n'){} // 一直获取缓冲区的字符,直到获取到 '\n' 才算清空缓冲区。
License:
CC BY 4.0