C语言–分支语句和循环语句
C语言是一门结构化的程序设计语言 顺序结构、选择结构、循环结构
分支语句 :
if 、 switch
循环语句 :
while 、 for 、 do while
什么是语句?
C语言中用一个“ ;”隔开的就是一条语句。比如:printf(“hehe”); 1+2;
个人理解:C语言就像是一门外语,关键字就像是形容词,语法就是C语言的代码规则,操作符相当于动词。
分支语句
如果你好好学习,校招时拿一个好offer,走上人生巅峰。
如果你不学习,毕业等于失业,回家卖红薯
这就是选择!
if语句
1、基础语句,如果表达式成立,则执行语句,如果表达式不成立,则不执行语句
if(表达式)
语句
2、if/else 如果表达式成立,则执行语句1,如果表达式不成立,则执行语句2
if(表达式)
语句1
else
语句2
3、多分支 如果表达式1成立,则执行语句1,如果表达式1不成立,寻找临近else if的表达式2,若成立则执行语句2,不执行则继续寻找临近 else if,
若有成立,则执行对应语句,若全不成立,则执行 else 对应语句。
if(表达式1)
语句1
else if(表达式2)
语句2
else
语句3
多分支举例
#include <stdio.h>
int main(){
int age = 0;
printf("请输入年龄(0~100)\n");
scanf("%d",&age);
if(age < 18){}
printf("未成年"); //如果输入的年龄<18,打印"未成年"
else if(18 <= age && age < 28) //“&&”是逻辑与,左右两边都为真时为真,一边为假则假
printf("青年");
else if(28<=age && age < 60)
printf("中年");
else
printf("老年");
return 0;
}
嵌套和悬空else举例,此处else就近原则,与上面相邻的 if 成对。若想让else与最外层if 匹配,将邻近if语句作为外层if的代码块即可,即将邻近if放入{ }
#include <stdio.h>
int main(){
int a = 1;
int b = 2;
if(a == 1)
if(b == 2)
printf("嵌套成功"); //当两个if表达式都成立的时候打印"嵌套成功"
else printf("嵌套失败"); //第一个if表达式成立,第二个if表达式不成立时打印"嵌套失败"
}
tip:如果表达式成立,则表达式为值为真,如果表达式不成立,则表达式值为假。在C语言中,0为假,非0为真,
在分支语句中,语句均可使用代码块{ }
小练习 1:判断一个数是否为奇数 2:输出1-100之间的奇数
#include <stdio.h>
int main(){
int a;
printf("请输入一个整数以判断是否为奇数:");
scanf("%d",&a);
if(a%2==1) //% 模除,取二者之间的余数。
printf("您输入了一个奇数");
else
printf("您输入的不是奇数");
return 0;
}
#include <stdio.h>
int main(){
int i=1; //初始化i
int count=0; //记录已经打印数字的个数
while(i<=100){
if(i%2==1){
printf("%d\t",i); //打印i
count++; //个数加1
if(count %5 == 0)
printf("\n"); //每行打印5个,满五个换一行
}
i++;
}
}
switch/case语句
条件选择语句,计算出表达式的值,与case进行匹配,匹配成功后,从当前case将剩余代码块执行完,遇到break跳出swtich。若没有匹配的case,则执行default语句。swtich()内的表达式必须是整型表达式。case后必须是常量表达式。
switch( 整型表达式 ){
case 常量表达式1: 语句1
case 常量表达式2: 语句2
...
case 常量表达式3: 语句;break;
default:默认语句
}
switch/case举例
#include <stdio.h>
int main(){
int day;
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("星期五");
break;
case 6:
printf("星期六");
case 7:
printf("星期天");
break;
default:
printf("输入错误")
}
因为case语句往下执行,某些相同且相邻的语句不需要每一个case都执行,只在需要的最后一处case执行语句即可。举例:
#include <stdio.h>
int main(){
int day;
scanf("%d",&day);
switch (day) {
case 1:
case 2:
case 3:
case 4:
case 5:
printf("工作日"); /输入1~5时,打印且只打印一次“工作日”。
break;
case 6:
printf("休息日");
default:
printf("休息日");
}
}
switch/case 嵌套练习
#include <stdio.h>
int main(){
int n = 1;
int m = 2;
switch(n){
case 1:m++;
case 2:n++;
case 3:switch(n){
case 1:n++;
case 2:m++;n++;
}
case 4:m++;
break;
default:
break;
}
printf("%d,%d",m,n);
}
循环语句
while语句
基本语句,表达式成立,循环执行语句,知道表达式不成立或break。
while(表达式)
语句;
流程图
简单循环打印1~10
#include <stdio.h>
int main(){
int i=1;
while(i<=10){
printf("%d\t",i);
i++;
}
}
break和continue跳出循环
使用 break 跳出整个循环体
#include <stdio.h>
int main(){
int i=1;
while(i<=10){
printf("%d\t",i);
i++;
if(i==5)
break;
}
}
使用 continue 跳过本次循环,注意i++的位置,如果i++在cotinue之后,就会变成死循环。
#include <stdio.h>
int main(){
int i=0;
while(i<10){
i++;
if(i==5)
continue;
printf("%d\t",i);
}
}
总结:在循环中遇到break,就停止之后的所有循环,跳出整个循环体,用于永久终止循环。
continue适用于终止本次循环的,也就是本次循环中continue后边的代码不会再执行,直接跳到while的判断部分,进行下一次循环的判断。
与 getchar 和 putchar 一块使用的一个小代码
tip : EOF 文件结束标志,值为-1 getchar() 从键盘获取字母 putchar() 在屏幕上打印字母
#include <stdio.h>
int main(){
int ch = 0; //初始化
while(getchar()!=EOF){ //EOF -- Ctrl+Z 如果没有输入Ctrl+Z 则继续执行循环体。
putchar(ch); //打印ch
}
return 0;
}
for循环
语法
for(表达式1;表达式2;表达式3) //表达式2为循环判断表达式,如果恒为真,则死循环
循环体;
表达式1为初始化部分,用于初始化循环变量。表达式2为条件判断部分,用于判断循环终止。表达式3为调整部分,用于循环条件的调整。
使用for循环在屏幕上打印1-10的数字
#include <stdio.h>
int main(){
for(int i=1;i<=10;i++){
printf("%d ",i);
}
}
流程图
tip: for循环中break和continue的用法同while。
for语句的循环控制变量一些建议
1.不可在for循环体内修改循环变量,防止for循环失去控制。
2.建议for语句的循环控制变量的值采用“前闭后开区间”写法。
例子:
#include <stdio.h>
int main(){
int i = 0;
for(i=0;i<10;i++){
if(i=5) //由于在此处对i进行了赋值,每次进入循环体都会初始化为5,导致循环无法结束,进入死循环。
printf("haha\n");
printf("hehe");
}
return 0;
}
例子2:
#include <stdio.h>
int main(){
int arr[10]={1,2,3,4,5,6,7,8,9,10};
int i = 0;
for(i=0;i<10;i++){ //此处i<10,而非i<=9 i<10具有 10次循环,10次打印,10个元素等某种方便观察的意义。
printf("%d ",i);
}
return 0;
}
for循环两个变种
int main(){
for(;;){
printf("hehe\n");
}
}
for循环的初始化、调整、判断都可以省略。但是:for循环的判断部分如果被省略,则判断条件恒为真
如果不是非常熟练,建议不要随便省略。
例子1:
#include <stdio.h>
int main(){
int i = 0;
int j=0;
for(;i<10;i++){
for(;j<10;j++){ //i=0第一次循环时结束后,j的值为10。i=1第二次循环时,j没有初始化,值仍为10,内层循环无法执行
printf("hehe\n"); //所以内层循环只在i=0时执行。打印了10次hehe
}
}
return 0;
}
例子2:
#include <stdio.h>
int main(){
int x, y;
for(x=0,y=0;x<2 && y<5;++x,++y){ // 两个循环变量控制的for循环 逻辑与"&&" 两个条件同时满足为真。
printf("hehe\n");
}
return 0;
}
下面这段代码循环执行了几次?
#include <stdio.h>
int main(){
int i = 0;
int k = 0;
for(i=0,k=0; k=0;i++,k++) //此处循环判断条件为赋值,将0赋值给k,值为0,假,循环执行了0次。
k++;
return 0;
}
do while循环
与while循环不同,do while在进行循环判断之前,先执行一次循环体。
流程图
语法
#include <stdio.h>
int main(){
int i = 1;
do{
printf("%d ",i);
i++;
}while(i<=10);
return 0;
}
break和continue的用法与while相同
一个常见死循环
#include <stdio.h>
int main(){
int i = 1;
do{
if(i==5)
continue; //使用continue跳过本次循环,判断条件i的值没有改变,进入后面的循环i恒等于5导致死循环。
printf("%d ",i);
i++;
}while(i<=10);
return 0;
}
goto语句
C语言中提供了可以随意滥用的goto语句和标记跳转的标号,从理论上goto语句是没有必要的,实践中没有goto语句也可以很容易的写出代码。但是某些场合下goto语句还是用得着的,最常见的用法就是终止程序在某些深度嵌套的结构的处理过程,例如一次跳出两层或多层循环。这种情况使用break是达不到目的。他只能从内层循环退出到上一层循环。
使用goto语句关机的程序:
#define _CRT_SECURE_NO_WARNINGS 1;
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(){
char input[20] = { 0 };
system("shutdown -s -t 120");
printf("请注意,电脑将于2分钟内关机\n");
again:
printf("输入“你好”停止关机>");
scanf("%s", &input);
if (strcmp("你好", input) == 0) {
system("shutdown -a");
printf("\n自动关机已停止");
}
else
{
goto again;
}
return 0;
}
练习
1.计算n的阶乘
#include <stdio.h>
int main(){
int i,n;
printf("请输入n的值\n");
scanf("%d",&n);
int num = 1;
for(i=1;i<=n;i++)
num*=i;
printf("%d的阶乘为%d",n,num);
return 0;
}
2.计算1!+2!+3!+4!+5!..+10!
#include <stdio.h>
int main(){
int i,j;
i=j=1;
int sum = 0;
int product = 1;
for(i=1;i<=10;i++){
for(j=1;j<=i;j++)
product *= j;
sum += product;
product = 1;
}
printf("%d",sum);
}
3.在一个有序数组中查找具体的某个数字n,编写int binsearch(int x,int v[],int n);功能:在v[0]<=v[1]<=v[2]<=…<=v[n-1]的数组中查找x.(二分查找法)
#include <stdio.h>
int main(){
int arr[]={1,2,3,4,5,6,7,8,9,10};
int k= 7;
int sz= sizeof(arr)/sizeof(arr[0]); //计算数组个数
int left= 0; //定义左边下标
int right= sz- 1; //定义右边下标
//二分查找法
while(left<=right){ //当左边下标<=右边下标说明还没找完,继续循环
int mid= (left+ right)/ 2; //取中间下标
if(arr[mid]> k)
right= mid- 1; //如果k小于arr[mid],说明k在数组左半边,让右边下标变成中间下标-1(因为已经小于了mid,则直接考虑mid-1)
else if(arr[mid]< k)
left= mid+ 1; //如果k大于arr[mid],说明k在数组右半边,让左边下标变成中间下标+1(因为已经大于了mid,则直接考虑mid+1)
else{
printf("找到了,下标是%d",mid); 既不大于也不小于,自然是等于,此时就找到了k的下标。
break;
}
}
if(left>right) //若循环没有通过break结束,而是通过left<=right不成立结束,说名末尾的else没有被执行,也就是没有找到对应值。
printf("找不到");
}
4.编写代码,演示多个字符从两端移动,向中间汇聚。
#include <stdio.h>
#include <string.h>
#include <windows.h>
#include <stdlib.h>
int main(){
char arr1[]="welcome to bit";
char arr2[]="##############";
int left = 0; //第一个元素下标
int right = strlen(arr1)-1; //找到末尾元素下标
while(left<=right){
arr2[left] = arr1[left];
arr2[right] = arr1[right]; //用arr1两端下标替换掉arr2对应两端下标的内容
printf("%s\n",arr2);
Sleep(1000); //等待1000毫秒 (头文件 Windows.h)
system("cls"); //清空屏幕 (头文件 stdlib.h)
left++;
right--;
}
// return 0;
}
5.编写代码实现,模拟用户登录场景,并且只能登录三次。(只允许输入三次密码,如果密码正确则提示登录成功,如果三次均输入错误,则退出程序)
#include <stdio.h>
#include <string.h>
int main(){
int i = 0;
char pwd[20] ={0};
for(i=0; i<3; i++){
printf("请输入密码\n");
scanf("%s",pwd);
if(strcmp(pwd,"123456") == 0){ //strcmp 用来比较两个字符串是否相等,如果相等,返回0; (头文件 string.h)
printf("登录成功");
break;
}
else
printf("密码错误\n");
}
if(i==3){
printf("三次密码均错误,退出程序\n");
}
}