目录
1.分支语句(选择结构)
1.1.if-else
1.1.1语法结构:
(1)if(表达式)
语句;
(2)if(表达式)
语句1;
else(表达式)
语句2;
(3)多分支:
if(表达式1)
语句1;
else if(表达式2)
语句2;
else
语句3;
1.1.2
int main()
{
int age = 0;
scanf_s("%d", &age);
if (age >= 18)
printf("成年人");
else
printf("未成年人 ");
printf("不能谈恋爱");
return 0;
}
输出:20 输出:成年人 不能谈恋爱
if/else只能控制一条语句,当需要if/else执行多条语句时,要加上 {}
int main()
{
int age = 0;
scanf_s("%d", &age);
if (age >= 18)
printf("成年人");
else
{
printf("未成年人 ");
printf("不能谈恋爱");
}
return 0;
}
输出:20 输出:成年人
1.1.3
int main()
{
int age = 0;
scanf_s("%d", &age);
if (age<=18)
printf("成年人");
else if (18<=age<26)
printf("青年");
return 0;
}
输入:40 输出:青年
语句18<=age<26中语法上age两边为或的关系,只要当age>=18或者age<26都可满足,但逻辑上为age>=18和age<26都满足方可执行语句,因此,应写为 age >= 26 && age < 40) 的形式
int main()
{
int age = 0;
scanf_s("%d", &age);
if (age < 18)
printf("未成年");
else if (age >= 18 && age < 26)
printf("青年");
else if (age >= 26 && age < 60)
printf("中年");
else
printf("老年");
return 0;
}
输入:40 输出:中年
1.1.4 悬空else
#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;
}
无输出
else的匹配:else是和它离的最近的if匹配的,不是看对齐哪个if
适当的使用 {} 可以使代码的逻辑更加清楚,代码的书写和风格很重要,要让别人容易看懂
int main()
{
int a = 0;
int b = 2;
if(a == 1)
{
if(b == 2)
{
printf("hehe\n");
}
}
else
{
printf("haha\n");
}
return 0;
}
🐖:当两个整型变量在一起比较时,最好将常量放在前面
if(5==num)
return("hhh");
练习1: 判断一个数是否为奇数
int main()
{
int num = 0;
scanf_s("%d", &num);
if (num % 2 == 0)
{
printf("%d不是奇数\n",num);
}
else
{
printf("%d是奇数\n",num);
}
return 0;
}
练习2:输出1-100之间的奇数
int main()
{
int i=0;
printf("1-100之间的奇数有:\n");
for (i = 1; i <= 100; i++)
{
if (i % 2 == 1)
{
printf("%d\n", i);
}
}
return 0;
}
1.2.switch
常用于多分支的场景
1.2.1 语法结构:
switch(整型表达式)
{
case 整型常量表达式:
语句;}
1.2.2 case决定入口,break决定出口
int main()
{
int day = 0;
scanf_s("%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;
}
return 0;
}
输入:5 输出:星期五
1.2.3 break不是一定要加,看具体需求
int main()
{
int day = 0;
scanf_s("%d", &day);
switch(day)
{
case 1:
case 2:
case 3:
case 4:
case 5:
printf("工作日\n");
break;
case 6:
case 7:
printf("休息日\n");
break;
}
return 0;
}
输入:5 输出:工作日
1.2.4 如果表达的值与所有的case标签的值都不匹配,程序并不会终止,也不会报错,当并不想忽略不匹配所有标签的表达式的值时,可以在语句列表中增加一条default子句,把 default:写在任何一个 case 标签可以出现的位置。当 switch 表达式的值并不匹配所有 case 标签的值时,这个 default 子句后面的语句就会执行。所以,每个switch语句中只能出现一条default子句。但是它可以出现在语句列表的任何位置,而且语句流会像执行一个case标签一样执行default子句。
int main()
{
int day = 0;
scanf_s("%d", &day);
switch(day)
{
case 1:
case 2:
case 3:
case 4:
case 5:
printf("工作日\n");
break;
case 6:
case 7:
printf("休息日\n");
break;
default:
printf("输入错误!\n");
break;
}
return 0;
}
输入:9 输出:输入错误!
练习:
int main()
{
int n = 1;
int m = 2;
switch (n)
{
case 1:
m++;//m=3
case 2:
n++;//n=2
case 3:
switch (n)
{//switch允许嵌套使用
case 1:
n++;
case 2:
m++;//m=4
n++;//n=3
break;
}
case 4:
m++;//m=5
break;
default:
break;
}
printf("m = %d, n = %d\n", m, n);
return 0;
}
输出:m=5 , n=3
2.循环语句
2.1 while
2.1.1 语法结构:
while(表达式)
循环语句;
2.1.2 while语句执行的流程:

2.1.3 break
在while循环中,break用于永久的终止循环
int main()
{
int i = 1;
while (i < 10)
{
if (i == 5)
break;
printf("%d", i);
i++;
}
return 0;
}
输出:1234
2.1.4 continue
在while循环中,continue用于跳过本次循环后面的代码
#include<stdio.h>
int main()
{
int i = 1;
while (i < 10)
{
if (i == 5)
continue;
printf("%d", i);
i++;
}
return 0;
}
输出:1234_(无限循环)
分析代码1:
#include <stdio.h>
int main()
{
int ch = 0;
while ((ch = getchar()) != EOF)
putchar(ch);
return 0;
}
getchar:获取字符(从键盘获取字符),返回类型为int类型
putchar:输出字符
EOF:-1,end of file-文件的结束标志
含义:getchar读取一个字符,putchar打印一个字符,当输入一个A字符时,相当于把 A\n 放入了缓冲区,此时getchar()先读入A,输出A,getchar()再读入\n,输出\n(即换行),再键入下一个字符,直至键盘按下Ctrl+Z,结束。相当于:
int ch = getchar();
printf("%c", ch);
这里的代码适当的修改是可以用来清理缓冲区的
例:
int main()
{
char password[9] = { 0 };
printf("请输入密码:");
scanf_s("%s", password,8);
printf("请确认密码(Y/N):");
int ch = getchar();
if (ch == 'Y')
{
printf("确认成功");
}
else
{
printf("确认失败");
}
return 0;
}
输出:

原因:getchar()需要从缓冲区获取数据,当缓冲区没有数据时,需要从键盘输入到缓冲区里,当执行scanf_s()语句时,键盘输入 12345678 ,回车会触发scanf_s()读取数据,当scanf_s()读取数据时,scanf_s()只读取 12345678 ,放入password字符串中,但实际上缓冲区内有 12345678\0 共九个字符,这时剩下的 \0 就会被getchar()读取,直接放到ch字符串中,而在if判断语句中发,\0 不等于 Y ,所以会执行else语句,直接输出确认失败
因此,当scanf_s()读取完字符 12345678 后,多使用一个getchar(),清理掉多余的 \0 ,即可实现想要的结果
int main()
{
char password[9] = { 0 };
printf("请输入密码:");
scanf_s("%s", password,8);
printf("请确认密码(Y/N):");
//清理缓冲区
getchar();//处理'\n'
int ch = getchar();
if (ch == 'Y')
{
printf("确认成功\n");
}
else
{
printf("确认失败\n");
}
return 0;
}
输出:

但是,我们发现当输入的password中有空格时,仍然会失败

这是因为,当输入 123 abc 时,缓存区会放入 123 abc\n ,但是scanf_s()只能读取 123 ,此时缓存区内仍有 abc\n ,一个getchar()无法完全清理掉缓存区
因此,需要多个getchar()来清理缓冲区,本题的这段代码就派上用场了
int main()
{
char password[9] = { 0 };
printf("请输入密码:");
scanf_s("%s", password,8);
printf("请确认密码(Y/N):");
//清理缓冲区
int tmp = 0;
while ((tmp = getchar()) != '\n')
{
;
}
int ch = getchar();
if (ch == 'Y')
{
printf("确认成功\n");
}
else
{
printf("确认失败\n");
}
return 0;
}
输出:

分析代码2:
#include <stdio.h>
int main()
{
char ch = '\0';
//int ch=0;
while ((ch = getchar()) != EOF)
{
if (ch < '0' || ch > '9')
continue;
putchar(ch);
}
return 0;
}
含义:只打印数字字符,跳过其他字符
2.2 for
2.2.1 语法结构:
for(表达式1; 表达式2; 表达式3)
循环语句;表达式1为初始化部分,用于初始化循环变量的。
表达式2为条件判断部分,用于判断循环时候终止。
表达式3为调整部分,用于循环条件的调整。
2.2.2 for循环的执行流程图:

2.2.3break和continue在for循环中
我们发现在for循环中也可以出现break和continue,他们的意义和在while循环中是一样的。
但是还是有些差异:
int main()
{
int i = 0;
for (i = 1; i <= 10; i++)
{
/*if (i == 5)
break;*/
if (i == 5)
continue;
printf("%d ", i);
}
return 0;
}
输出:1 2 3 4 6 7 8 9 10
这是因为for循环里的continue 跳到调整部分进行i的自增,while循环的continue可能会把i的自增这一步跳过去,导致死循环
2.2.4 for语句的循环控制变量
不可在for 循环体内修改循环变量,防止 for 循环失去控制
for (i = 1; i <= 10; i++)
{
printf("%d ", i);
i=5;
}
建议for语句的循环控制变量的取值采用“前闭后开区间”写法
for (i = 1; i < 10; i++)
2.2.5 for循环的变种
代码1:for循环的初始化、条件判断、调整每个部分都可以省略,但是判断部分一旦省略,就会进入死循环
for (;;)
{
printf("hehe\n");
}
return 0;
代码2:
int i = 0;
int j = 0;
//这里打印多少个hehe?
for(i=0; i<3; i++)
{
for(j=0; j<3; j++)
{
printf("hehe\n");
}
}
此时共打印9个 hehe
int i = 0;
int j = 0;
//如果省略掉初始化部分,这里打印多少个hehe?
for(; i<3; i++)
{
for(; j<3; j++)
{
printf("hehe\n");
}
}
此时共打印3个 hehe
这是因为当i=0时,j由0自增至2,跳出内层循环,进行外层循环,i自增为1,但此时的j仍然是3,不满足内层循环的条件,i自增至2,j=3,仍然不满足内层循环的条件,且此时外层循环的条件也不满足,跳出两层循环,所以一共输出三次 hehe
代码3:使用多个变量控制循环
int x, y;
for (x = 0, y = 0; x < 2 && y < 5; ++x, y++)
{
printf("hehe\n");
}
return 0;
代码4:请问循环要循环多少次?
#include <stdio.h>
int main()
{
int i = 0;
int k = 0;
for (i = 0, k = 0; k = 0; i++, k++)
k++;
return 0;
}
0次
判断部分 k=0 ,把0赋值给k,k为假,不会进行循环
2.3 do...while
2.3.1 语法结构:do循环语句 ;while ( 表达式 );
2.3.2执行流程图:

2.3.3 do while循环中的break和continue
int main()
{
int i = 1;
do
{
if (i == 5)
break;
printf("%d ", i);
i++;
} while (i <= 10);
return 0;
}
输出:1 2 3 4
int main()
{
int i = 1;
do
{
if (i == 5)
continue;
printf("%d ", i);
i++;
} while (i <= 10);
return 0;
}
输出:1 2 3 4_(无限循环)
2.3.4 do语句的特点
循环至少执行一次,使用的场景有限,所以不是经常使用
3.练习
练习1:计算n的阶乘
int main()
{
int n;
scanf_s("%d", &n);
int res1 = 1, res2 = 1, res3 = 1;
int i = 1;
//while循环
while (i <= n)
{
res1 *= i;
i++;
}
//for循环
for (i = 1; i <= n; i++)
{
res2 *= i;
}
//do...while循环
i = 1;
do
{
res3 *= i;
i++;
} while (i <= n);
printf("%d的阶乘为:%d\n", n, res1);
printf("%d的阶乘为:%d\n", n, res2);
printf("%d的阶乘为:%d\n", n, res3);
return 0;
}
输出:
5的阶乘为:120
5的阶乘为:120
5的阶乘为:120
练习2:计算 1!+2!+3!+……+n!
while循环:
int main()
{
int n;
scanf_s("%d", &n);
int i = 1, j = 1;
int sum = 0;
int res = 1;
while (i <= n)
{
j = 1;
res = 1;
while (j <= i)
{
res *= j;
j++;
}
sum += res;
i++;
}
printf("%d", sum);
return 0;
}
for循环:
int main()
{
int n;
scanf_s("%d", &n);
int res = 1, sum = 0;
for (int i = 1; i <= n; i++)
{
res = 1;
for (int j = 1; j <= i; j++)
{
res *= j;
}
sum += res;
}
printf("%d", sum);
return 0;
}
do...while循环:
int main()
{
int n;
scanf_s("%d", &n);
int i=1,j = 1;
int res = 1, sum = 0;
do
{
res = 1;
j = 1;
do
{
res *= j;
j++;
} while (j <= i);
sum += res;
i++;
} while (i <= n);
printf("%d", sum);
return 0;
}
练习3:在一个有序数组中查找具体的某个数字n-->二分查找
int main()
{
int* arr;
arr = (int*)malloc(sizeof(int));
int n;
scanf_s("%d", &n);
for (int i = 0; i < n; i++)
{
scanf_s("%d", &arr[i]);
}
int k;//要查找的值
scanf_s("%d", &k);
int left = 0;
int right = n - 1;
while (left <= right)
{
int mid = (left + right) / 2;
if (arr[mid] < k)
{
left = mid + 1;
}
else if (arr[mid] > k)
{
right = mid - 1;
}
else
{
printf("%d的下标为:%d", k, mid);
break;
}
}
if (left > right)
printf("找不到");
return 0;
}
输入:
10
1 2 3 4 5 6 7 8 9 10
7
输出:
6
练习4:编写代码,演示多个字符从两端移动,向中间汇聚
int main()
{
char arr1[] = "welcome to csdn";
char arr2[] = "###############";
int left = 0;
int right = strlen(arr1) - 1;
printf("%s\n", arr2);
//while循环实现
while (left <= right)
{
Sleep(1000);//睡眠一秒
arr2[left] = arr1[left];
arr2[right] = arr1[right];
left++;
right--;
printf("%s\n", arr2);
//system("cls");//清空屏幕
}
//for循环实现
char arr3[] = "###############";
printf("%s\n", arr3);
for (left = 0, right = strlen(arr1) - 1;left <= right;left++, right--)
{
Sleep(1000);
arr3[left] = arr1[left];
arr3[right] = arr1[right];
printf("%s\n", arr3);
//system("cls");//清空屏幕
}
return 0;
}
练习5:编写代码实现,模拟用户登录情景,并且只能登录三次。(只允许输入三次密码,如果密码正确则提示登录成功,如果三次均输入错误,则退出程序)
int main()
{
int i = 0;
char password[20] = { 0 };
char right_ps[20] = "123456";
for (i = 0; i < 3; i++)
{
printf("请输入密码:");
scanf_s("%s", password,20);
if (strcmp(password, right_ps) == 0)
{
printf("登录成功");
break;
}
else
{
printf("密码错误,请重新输入密码\n");
}
}
if (i == 3)
{
printf("三次密码均需哦呜,推出程序");
}
return 0;
}
练习6:自动生成一个1-100之间的随机数,若猜错,会知晓是猜大了还是猜小了,继续猜,直至猜对,游戏可以一直玩,除非退出游戏。
void game()
{
//1、生成随机数
int ret = rand()%100+1;
//2、猜数字
int guess = 0;
while (1)
{
printf("请猜数字:");
scanf_s("%d", &guess);
if (guess < ret)
{
printf("猜小了\n");
}
else if (guess > ret)
{
printf("猜大了\n");
}
else
{
printf("恭喜你!猜对了\n");
break;
}
}
}
void menu()
{
printf("*************************************\n");
printf("************ 1.play **************\n");
printf("************ 0.exit **************\n");
printf("*************************************\n");
}
int main()
{
int input = 0;
srand((unsigned int)time(NULL));//利用时间戳设置一个随机的起点
do
{
menu();//打印菜单
printf("请选择:>");
scanf_s("%d", &input);
switch(input)
{
case 1:
game();//猜数字游戏的实现
break;
case 0:
printf("退出游戏");
break;
default:
printf("选择错误,请重新选择");
break;
}
} while(input);
return 0;
}
该博客主要介绍C语言的分支和循环语句。分支语句包括if - else和switch,讲解了语法、使用场景及注意事项;循环语句有while、for和do...while,阐述了执行流程、break和continue的作用。此外,还给出多个相关练习,如计算阶乘、二分查找等。
1432

被折叠的 条评论
为什么被折叠?



