C语言是结构化的程序设计语言
- 顺序结构
- 选择结构 if switch
- 循环结构 while 、for、do while
1.什么是语句
C语言语句分为以下五类
- 表达式语句
- 函数调用语句
- 控制语句
- 复合语句
- 空语句
控制语句用于控制程序的执行流程,以实现程序的各种结构方式,它们由特定的语句定义符组成,C语言有九种控制语句。
可以分成一下三类:
- 条件判断语句也叫分支语句:if 语句、switch语句;
- 循环执行语句:do while语句、while语句、for语句;
- 转向语句:break语句、goto语句、continue语句、return语句
2.分支语句(选择结构)
-
2.1 if语句
语法结构: if(表达式)
语句1;
if(表达式)
语句1;
else
语句2;
//多分枝
if(表达式1)
语句1;
else if(表达式2)
语句2;
else
语句3;
代码:
#include<stdio.h>
int main()
{
int age=0;
if(age<18)
printf("青少年\n");
else if(age>=18 && age<30)
printf("青年\n");
else if(age>=30 && age<50)
printf("中年\n");
else if(age>=50 && age<80)
printf("中老年\n");
else if(age>=80 && age<100)
printf("老年\n");
else
printf("老寿星\n");
return 0;
}
if 后面不加 { } 默认只能控制一条语句
如果表达式的结果为真,则语句执行。
在C语言中如何表示真假? 0表示假,非0表示真
如果条件成立,要执行多条语句,使用代码块
#include<stdio.h>
int main()
{
if(表达式)
{
语句列表1;
} else
{
语句列表2;
}
return 0;
}
这里的一对{ }就是一个代码块
-
2.1.1悬空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应该与最近的if匹配,所以上面的代码是不输出结果
改正:
//适当的使用{ }可以是代码的逻辑更加清楚
//代码风格很重要
#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;
}
-
2.1.2if书写形式的对比
//代码1
if(condition) {
return x;
}
return y;
//代码2
if(condition)
{
return x;
}
else
{
return y;
}
//代码1与代码2表达的是一个意思
//代码3
int num = 1;
if(num == 5)
{
printf("hehe\n");
}
//代码4
int num=1;
if(5==num)
{
printf("hehe\n");
}
//代码2和代码4更好,逻辑更加清晰,不容易出错
//代码3 num==5,我们有时会误写成num=5,但是编译器又不会报错,相反代码4 5==num,如果/写成5=num,编译器会直接报错,因为变量不能赋值给常量
-
2.1.3练习
1.判断一个数是否为奇数
int main()
{
int n = 0;
scanf("%d", &n);
if (n % 2 == 1)
{
printf("奇数\n");
}
return 0;
}
2.输出1—100之间的奇数
int main()
{
int n = 0;
while (n<=100)
{
if (n % 2 == 1)
printf("%d ", n);
n++;
}
return 0;
}
-
2.2 switch语句
switch语句也是一种分支语句
常常用于多分支的情况
比如:
输入1,输出星期一
输入2,输出星期二
输入3,输出星期三
输入4,输出星期四
输入5,输出星期五
输入6,输出星期六
输入7,输出星期日
switch 语法:
switch(整形表达式)
{
语句项;
}
//语句项:是一些case语句
//如:
case 整型常量表达式 ;
语句;
代码:
int main()
{
int day=0;
scanf("%d",&day);
switch(day)
{
case 1:
printf("星期1\n");
break;
case 2:
printf("星期2\n");
break;
case 3:
printf("星期3\n");
break;
case 4:
printf("星期4\n");
break;
case 5:
printf("星期5\n");
break;
case 6:
printf("星期6\n");
break;
case 7:
printf("星期日\n");
break;
default:
printf("输入错误\n");
break;
}
return 0;
}
-
2.2.1 在switch语句的break的作用
break语句的实际效果是把语句列表划分为不用的分支部分
编程好习惯
在最后一个case语句的后面加上一条break语句;
(这么写可以避免出现以前的最后一个擦色语句后面忘记添加break语句)
2.2.2 defual 子句
如果表达的值与所有的case标签的值都不匹配,并且并不想忽略所有标签的表达式值时
在语句列表中增添一条default子句,把下面的标签
defaul:
写在任何一个case标签可以出现的位置
当switch表达式的值并不匹配所有case标签的值,这个defaul子句后面的语句就会执行,所以,每个switch语句只能出现一条default子句
但是他可以出现在语句列表的任何位置,而且语句会像执行一个case标签一样执行default子句
编程好习惯
在每个switch语句中都放一条default子句是个好习惯,甚至可以在后边再加一个break
-
2.2.3练习
#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++;
break;
}
case 4:
m++;
break;
default:
break;
}
printf("m=%d,n=%d\n",m,n);
return 0;
} //switch允许嵌套使用
m=5,n=3;
3.循环语句
- while
- for
- do while
-
3.1 while
//while 语法结构
while(表达式)
循环语句;
在屏幕上打印1-10的数 数字
#include<stdio.h>
int main()
{
int i=1;
while(i<=10)
{
printf("%d",i);
i=i+1;
}
return 0;
}
3.1.1 while 语句中的break和continue
int main()
{
int i=1;
while(i<=10)
{
if(5==i)
break;
printf("%d",i);
i++;
}
}
//打印结果是:1 2 3 4死循环
while中break的作用是终止整个循环(提前结束)
int main()
{
int i = 1;
while (i <= 10)
{
if (5 == i) continue;
printf("%d", i);
i++;
}
}
//打印结果:1 2 3 4
//跳过5
while中continue的作用跳过continue后面的代码(跳过本次循环),直接到判断部分
总结:
break在while循环中的作用:
其实在循环中只要遇到break,就停止后期的所有的循环,直接终止循环
所以:while中的break是用于永久终止循环的。
continue在while循环中的作用就是:
continue是用于终止本次循环,也就是本次循环中continue后边的代码不会执行,而是直接跳到while语句的判断部分。进行下一次循环的入口判断。
int main()
{
char password[20] = { 0 };
printf("请输入密码:>");//123456
scanf("%s", password);
printf("请确认密码(Y/N):>");
int ch = getchar();
if ('Y' == ch)
printf("确认成功\n");
else
printf("确认失败\n");
}
当输入密码123456回车时直接就打印出:请确认密码(Y/N):>确认失败
这是为什么?
scanf和getchar在缓冲区读取数据,当输入123456时实际上在缓冲区放入123456\n
scanf把123456拿走,还剩下\n
然后getchar将缓冲区中的\n拿走,所以没有等待输入直接确认失败
所以想要是实现代码,将要\n清理掉
解决办法
int main()
{
char password[20] = { 0 };
printf("请输入密码:>");
scanf("%s", password);
int tmp = 0;
while ((tmp = getchar()) != '\n')
{
}//处理掉\n
printf("请确认密码(Y/N):>");
int ch=getchar();
if ('Y' == ch)
printf("确认成功\n");
else
printf("确认失败\n");
}
//代码1
#include<stdio.h>
int main()
{
char ch='\0';
while((ch=getchar())!=EOF)
putchar(ch);
return 0;
}
//这里的代码适当的修改是可以用来清理缓冲区的
//代码2
#include<stdio.h>
int main()
{
char ch='\0';
while((ch=getchar())!=EOF)
{
if(ch<'0'||ch>'9')
continue;
putchar(ch);
}
return 0;
}
//打印数字字符0-9 //这个代码的作用是:纸打印数字字符,跳过其他字符
-
3.2 for循环
-
3.2.1 语法
for(表达式1;表达式2;表达式3) 循环语句;
表达式1
表达式1为初始化部分,用于初始化变量的
表达式2
表达式2为条件判断部分,用于判断循环时候终止
表达式3
表达式3为调整部分,用于循环条件的调整
-
3.2.2 break和continue在for循环中的作用
break和continue,它们的意义和在while循环中是一样的但是还是有差异的,break是完全一样的,但是continue是不一样的,continue在for循环中是跳过本次循环,到调整部分;continue在while循环是跳过本次循环到判断部分
int main()
{
int i = 0;
for (i = 1; i <= 5; i++)
{
if (5 == i)
break;
printf("%d", i);
}
return 0;
}
int main()
{
int i = 0;
for (i = 1; i <= 10; i++)
{
if (5 == i)
continue;
printf("%d", i);
}
return 0;
}
-
3.2.3 for语句的循环控制变量
建议:
1.不可在for循环体内修改循环变量,防止for循环失去控制
2.建议for语句的循环控制变量的取值采用“前闭后开区间”写法
int i=0;
//前闭后开的写法
for(i=0;9<10;i++)
{
}
//两边都是闭区间
for(i=0;i<=9;i++)
{
}
-
3.2.4 一些for循环的变种
#include<stdio.h>
int main()
{
//代码1
for( ; ; )
//for循环中的判断部分省略了,就意味着判断恒为真 { printf("hehe\n"); }
//for循环中的初始化部分,判读部分,调整部分是可以省略的,但是不建议初学时省略,容易导致问题
//代码2
for(i=0;i<10;i++)
{
for(j=0;j<10;j++)
{
printf("hehe\n");//打印100个
}
}
//代码3
int i=0;
int j=0;
//如果省略掉初始化部分,这里打印多少个hehe?
for(;i<10;i++)
{
for(;j<10;j++)
{
printf("hehe\n");
}
}
//这里打印多少个hehe?10个
//i=0;
//j=0-9,j=10不满足条件跳出for循环
//i=1;
//此时j还是10,不打印hehe,所以这里只能打印10个hehe
//代码4 使用多余一个变量控制变量循环(很少见)
int x,y;
for(x=0,y=0;x<2 && y<5;++x,++y)
{
printf("hehe\n");
}
return 0;
}
//请问这个循环要循环多少次? 0
#include<stdio.h>
int main()
{
int i=0;
int k=0;
for(i=0,k=0;k=0;i++,k++)
//k=0这个表达式是0,此时这里是判断部分,0表示为假,所以不执行下面的代码
k++;
return 0;
}
-
3.3 do...while()循环
-
3.3.1 do 语句的语法:
do 循环语句; while(表达式)
break和continue在do...while的作用和在while的作用是一样的
-
3.4 练习
//计算n的阶乘
#include<stdio.h>
int main()
{
int n=0;
int i=0;
int ret=1;
scanf("%d",&n);
for(i=1;i<=n,i++)
{
ret=ret*i;
}
printf("%d",ret);
return 0;
}
//计算1!+2!+...+10!
int main()
{
int n=0;
int sum=0;
int ret=1;
for(n=1;n<=10;n++)
{
ret=ret*n;
sum=sum+ret;
}
printf("%d",sum);
}
//在有序数组中查找具体的某个数字n(二分查找)
int main()
{
int arr[]={1,2,3,4,5,6,7,8,9,10};
int k=8;//要查找的数字
int sz=sizeof(arr)/sizeof(arr[0]);
int left=0;
int right=sz-1;
while(left<=right)
{
//int mid=(left+right)/2;
int mid=left+(right-left)/2;
if(arr[mid]>k) right=mid-1;
else if(arr[mid]<k)
left=mid+1;
else
printf("找到了,下标是%d",mid);
}
if(left>right)
printf("找不到了\n");
return 0;
}
//编写代码,演示多个字符从两端移动,向中间汇聚
#include<string.h>
#include<windows.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];
printf("%s\n", arr2);
Sleep(1000);//单位是毫秒
system("cls");
left++;
right--;
}
printf("%s", arr2);
return 0;
}
//编写代码实现,模拟用户登录情景,并且只能登录三次。(只允许输入三次密码,如果密码正确则提示登录成功,如果三次均输入错误,则退出程序。)
int main()
{
int i = 0;
char password[20] = { 0 };
scanf("%s", password);
for (i = 0; i < 3; i++)
{
if (strcmp(password, "abcdef") == 0)
{
printf("密码正确\n");
break;
}
else
{
printf("密码错误,重新输入\n");
}
if (i == 3)
{
printf("三次均输入错误,退出程序");
}
}
return 0;
}
两个字符串的比较是不能使用==
应该使用strcmp