前言:
首先,无论对C语言还是世界上的绝大多数事情来说,一般都可以由顺序结构,选择结构,循环结构这三种结构类型构成。
对顺序结构并没有什么好说的,按照顺序一步一步执行。而对于选择结构和循环结构来说。
if,switch实现分支结构,for,while,do while实现循环结构。
1.if语句
1.if语句的语法形式
//单分支if语句
if(表达式)
语句
//多分支if语句
if(表达式1)
语句1
else if(表达式2)
语句2
...
...
else
语句n;
表达式成立(为真),则语句执行,否则不执行。
在C语言中,0为假,非0表示真。
提示:当存在多条语句时,需要加上{ },否则会报错
if(表达式)
{
语句1;
语句2;
...
语句n;
}
2.悬空else
#include <stdio.h>
int main()
{
int a = 0;
int b = 2;
if(a==1) //第一个if
if(b==2)//第二个if
printf("good\n");
else
printf("very good\n");
return 0;
}
上述这串代码什么结果也没有
该代码块没有控制缩进并且没有用{}来控制,此处的else让人茫然。
但是一般认为,else在没有{}控制的情况下,会自动与最近的if匹配。
因此,对于初学者来说我们一定要养成一个良好的习惯。
下图是if流程执行图
3.嵌套if
在if else语句中,else可以与另一个if语句连用,构成多重判断。
有了嵌套if语句,就可以完成更多复杂逻辑的判断。
练习:
输⼊⼀个⼈的年龄 如果年龄<18岁,打印"少年" 如果年龄在18岁⾄44岁打印"⻘年" 如果年龄在45岁⾄59岁打印"中⽼年" 如果年龄在60岁⾄89岁打印"⽼年" 如果90岁以上打印"⽼寿星"
#include <stdio.h>
int main()
{
int age = 0;
scanf("%d",&age);
if(age<18)
printf("少年\n");
else if(age<=44)
printf("青年");
else if(age<=59)
printf("中老年");
else if(age<=90)
printf("老年"\n);
else
printf("老寿星");
return 0;
}
2.关系操作符
C语言中用于比较的表达式,关系运算符只要有以下6个。
关系运算符通常返回0和1,表示真假。
C语言中,0表示假,所有非0值表示真。比如,20>12返回1,12>20返回0.
注意:
1.相等运算符 == 与赋值运算符 = 是两个不⼀样的运算符,不要混淆。有时候,可能会不⼩⼼写出下⾯的代码,它可以运⾏,但很容易出现意料之外的结果。
2.另⼀个需要避免的错误是:多个关系运算符不宜连⽤。
3.连续使⽤两个⼩于运算符。这是合法表达式,不会报错,但是通常达不到想要的结果
(5>2)>3
上面的式子中5>2为真则返回1,倘若他为假,那就返回0。所以是最后是0或1与3进行比较。
若想要判断3个值的大小关系,应该这样写
i < j && j < k
3.条件操作符
条件操作符也叫三目操作符,需要接受三个操作数的
exp1 ? exp2 : exp3
练习:使用条件表达式实现找两个数中较大值
#include <stdio.h>
int main()
{
int a=0;
int b=0;
scanf("%d %d",&a,&b);
int m=a>b?a:b;
printf("%d\n",m);
return 0;
}
4.逻辑操作符:&&,||,!
逻辑运算符提供逻辑判断功能,用于构建更复杂的表达式,主要有下面三个运算符。
! :逻辑取反运算符(改变单个表达式的真假)。
&& :与运算符,就是并且的意思(两侧的表达式都为真,则为真,否则为假)。
|| :或运算符,就是或者的意思(两侧⾄少有⼀个表达式为真,则为真,否则为假)。
逻辑反操作
比如我们定义一个flag,如果 flag 为真, !flag 就是假,如果 flag 为假, !flag 就是真。
逻辑与
&& 就是与运算符,也是并且的意思, && 是⼀个双⽬操作符,使⽤的⽅式是 a&&b , && 两边的表达式都是真的时候,整个表达式才为真,只要有⼀个是假,则整个表达式为假。
或操作符
|| 就是或运算符,也就是或者的意思, || 也是⼀个双⽬操作符,使⽤的⽅式是 a || b , || 两边的表达式只要有⼀个是真,整个表达式就是真,两边的表达式都为假的时候,才为假。
练习:
闰年的判断
#include <stdio.h>
int main()
{
int year = 0;
scanf("%d",&year);
if((year%4==0&&year%100!=0)||(year%400==0))
printf("是闰年");
return 0;
}
练习:
计算下面代码的结果
#include <stdio.h>
int main()
{
int i = 0,a=0,b=2,c=3,d=4;
i = a++ && ++b && d++;
printf("a = %d\n b = %d\n c = %d\n d = %d\n",a,b,c,d);
return 0;
}
5.switch语句
1. case 和后边的数字之间必须有空格
2. 每⼀个 case 语句中的代码执⾏完成后,需要加上 break ,才能跳出这个switch语句。
switch 语句也是分⽀效果的,只有在 switch 语句中使⽤ break 才能在跳出 switch 语 句,如果某⼀个 case 语句的后边没有 break 语句,代码会继续玩下执⾏,有可能执⾏其他 case 语句中的代码,直到遇到 break 语句或者 switch 语句结束。就⽐如上⾯的代码就执⾏了 case 2 中的语句。 所以在 switch 语句中 break 语句是⾮常重要的,能实现真正的分⽀效果。 当然, break 也不是每个 case 语句都得有,这就得根据实际情况来看了。
练习:
#include <stdio.h>
int main()
{
int day = 0;
scanf("%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;
}
switch语句中的case和default的顺序问题
在 switch 语句中 case ⼦句和 default ⼦句有要求顺序吗? default 只能放在最后吗? 其实,在 switch 语句中 case 语句和 default 语句是没有顺序要求的,只要你的顺序是满⾜实际需求的就可以。 不过我们通常是把 default ⼦句放在最后处理的。
switch语句也支持嵌套使用
#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;
}
执行输出m = 5,n = 3
6.while循环
练习:在屏幕上打印1~10的值
#include<stdio.h>
int main()
{
int i=0;
while(i<=10)
{
printf("%d ",i);
i++;
}
return 0;
}
练习:
题⽬解析 1. 要想得到n的最低位,可以使⽤n%10的运算,得到的余数就是最低位,如:1234%10得到4
2. 要想去掉n的最低位,找出倒数第⼆位,则使⽤ n=n/10 操作就可以去掉最低位的,如: n=1234/10得到123,123相较于1234就去掉了最低位,123%10就得到倒数第⼆位3。
3. 循环1和2两个步骤,在n变成0之前,就能到所有的位。
#include <stdio.h>
int main()
{
int n=0;
scanf("%d",&n);
while(n)
{
printf("%d ",n%10);
n/=10;
}
return 0;
}
7.for循环
for循环是用到的最多的一种循环。
for循环的语法形式:
for(表达式1;表达式2;表达式3)
语句
表达式1用于循环变量的初始化
表达式2用于循环结束条件的判断
表达式3用于循环变量的调整
练习:
在屏幕上打印1~10的值
#include <stdio.h>
int main()
{
int i=0;
for(i=1;i<=10;i++)
{
printf("%d ",i);
}
return 0;
}
for循环便于代码维护
练习1:
计算1~100之间3的倍数的数字之和
#include <stdio.h>
int main()
{
int i=0;
int sum = 0;
for(i=1;i<=100;i++)
{
if(i%3==0)
sum+=i;
}
printf("%d\n",sum);
return 0;
}
上述的代码可以做一个小小的优化,可以把i++改为I+=3
8.do-while循环
do while使用在循环体至少被执行一次的场景下,所以较少一些。
8.4 练习:
输⼊⼀个正整数,计算这个整数是⼏位数?
例如: 输⼊:1234 输出:4 输⼊:12 输出:2
#include <stdio.h>
int main()
{
int n=0;
scanf("%d",&n);
int count = 0;
do
{
count++;
n/=10;
}while(n)
printf("%d\n",count);
return 0;
}
这⾥并⾮必须使⽤ do while 语句,但是这个代码就⽐较适合使⽤ do while 循环,因为n即使是 0,也是1位数,要统计位数的。
9.break和continue语句
在循环执⾏的过程中,如果某些状况发⽣的时候,需要提前终⽌循环,这是⾮常常⻅的现象。C语⾔中 提供了 break 和 continue 两个关键字,就是应该到循环中的。 • break 的作⽤是⽤于永久的终⽌循环,只要 break 被执⾏,直接就会跳出循环,继续往后执 ⾏。 • continue 的作⽤是跳过本次循环 continue 后边的代码,在 for 循环和 while 循环中有所 差异的。
1.while循环中break举例
#include <stdio.h>
int main()
{
int i=0;
while(i<=10)
{
if(i==5)
break;
printf("%d ",i);
i++;
}
return 0;
}
结果
打印了1,2,3,4后,当i等于5的时候,循环正 break 的地⽅终⽌,不再打印,不再循环。 所以 break 的作⽤就是永久的终⽌循环,只要 break 被执⾏, break 外的第⼀层循环就终⽌了。 那以后我们在循环中,想在某种条件下终⽌循环,则可以使⽤ break 来完成我们想要的效果。
2.while循环中continue举例
continue 是继续的意思,在循环中的作⽤就是跳过本次循环中 continue 后边的代码,继续进⾏ 下⼀次循环的判断。
#include <stdio.h>
int main()
{
int i = 1;
while(i<=10)
{
if(i == 5)
continue;
//当i等于5后,就执⾏continue,直接跳过continue的代码,去循环的判断的地⽅
//因为这⾥跳过了i = i+1,所以i⼀直为5,程序陷⼊和死循环
printf("%d ", i);
i = i+1;
}
return 0;
}
到这⾥我们就能分析出来, continue 可以帮助我们跳过某⼀次循环 continue 后边的代码,直接 到循环的判断部分,进⾏下⼀次循环的判断,如果循环的调整是在 continue 后边的话,可能会造成 死循环。
1.for循环中break
其实和 while 循环中的 break ⼀样, for 循环中的 break 也是⽤于终⽌循环的,不管循环还需 要循环多少次,只要执⾏到了 break ,循环就彻底终⽌,我们上代码。
#include <stdio.h>
int main()
{
int i = 1;
for(i=1; i<=10; i++)
{
if(i == 5)
break;
printf("%d ", i);
}
return 0;
}
结果:
break 的作⽤是永久的终⽌循环,未来我们在某个条件发⽣的时候,不想再继续循环的时候,就可以 使⽤ break 来完成。
2.for循环中的continue
#include <stdio.h>
int main()
{
int i = 1;
for(i=1; i<=10; i++)
{
if(i == 5)
continue;//这⾥continue跳过了后边的打印,来到了i++的调整部分
printf("%d ", i);
}
return 0;
}
结果:
所以在 for 循环中 continue 的作⽤是跳过本次循环中 continue 后的代码,直接去到循环的调 整部分。未来当某个条件发⽣的时候,本次循环⽆需再执⾏后续某些操作的时候,就可以使⽤ continue 来实现。
在这⾥我们也可以对⽐⼀下 while 循环和 for 循环中 continue 的区别:
10.循环的嵌套
前⾯学习了三种循环 while , do while , for ,这三种循环往往会嵌套在⼀起才能更好的解决
问题,就是我们所说的:循环嵌套,这⾥我们就看⼀个例⼦。
练习:
找出100~200之间的素数,并打印在屏幕上。
注:素数⼜称质数,只能被1和本⾝整除的数字。
题⽬解析: 1. 要从100~200之间找出素数,⾸先得有100~200之间的数,这⾥可以使⽤循环解决。 2. 假设要判断i是否为素数,需要拿2~i-1之间的数字去试除i,需要产⽣2~i-1之间的数字,也可以使⽤ 循环解决。 3. 如果2~i-1之间有数字能整除i,则i不是素数,如果都不能整除,则i是素数。
#include <stdio.h>
int main()
{
int i = 0;
//循环产⽣100~200的数字
for(i=100; i<=200; i++)
{
//判断i是否为素数
//循环产⽣2~i-1之间的数字
int j = 0;
int flag = 1;//假设i是素数
for(j=2; j<i; j++)
{
if(i % j == 0)
{
flag = 0;
break;
}
}
if(flag == 1)
printf("%d ", i);
}
return 0;
}
11.goto语句
C语⾔提供了⼀种⾮常特别的语法,就是 goto 语句和跳转标号, goto 语句可以实现在同⼀个函数 内跳转到设置好的标号处
goto 语句如果使⽤的不当,就会导致在函数内部随意乱跳转,打乱程序的执⾏流程,所以我们的建 议是能不⽤尽量不去使⽤;但是 goto 语句也不是⼀⽆是处,在多层循环的代码中,如果想快速跳出 使⽤ goto 就⾮常的⽅便了。
for(...)
{
for(...)
{
for(...)
{
if(disaster)
goto error;
}
}
}
error:
本来 for 循环想提前退出得使⽤ break ,⼀个 break 只能跳出⼀层 for 循环,如果3层循环嵌套 就得使⽤3个 break 才能跳出循环,所以在这种情况下我们使⽤ goto 语句就会更加的快捷。