1.break和continue语句
在执行循环的过程中,如果发生某些状况需要提前终止循环,这时候就用到了break和continue
break的作用是用于永久性的终止循环,只要break被执行,循环就会被跳出,继续执行后面的
continue的作用是跳过本次循环continue后面的代码,在for循环和while循环中是有差异的
1.1 for循环中的break和continue
break举例:
int main()
{
int i = 0;
for (i = 1; i <= 10; i++)
{
if (i == 5)
break;
printf("%d ", i);
}
return 0;
}
运行结果
打印了1 2 3 4后,i变成了5,循环在break的地方就被终止了,所以break是永久性的终止循环,只要break被执行,break外的第一层循环就被终止了。
continue举例:
#include<stdio.h>
int main()
{
int i = 0;
for (i = 1; i <= 10; i++)
{
if (i == 5)
continue;
printf("%d ", i);
}
return 0;
}
运行结果:
continue的作用是跳过本次循环continue后面的代码,继续进行下一次循环的判断。
1.2 while循环中的break和continue
break举例:
#include<stdio.h>
int main()
{
int i = 1;
while (i <= 10)
{
if (i == 5)
break;
printf("%d ", i);
i++;
}
return 0;
}
运行结果:
continue举例:
#include<stdio.h>
int main()
{
int i = 0;
while (i < 10)
{
if (i == 5)
continue;
printf("%d ", i);
i++;
}
return 0;
}
运行结果:
到这里我们可以看出来,continue直接跳过后面的语句,但是由于循环的调整是在continue的后面,所以这个循环就变成了死循环。
1.3 do while循环中的break和continue
break:
#include <stdio.h>
int main()
{
int i = 1;
do
{
if (i == 5)
break;
printf("%d ", i);
i = i + 1;
} while (i <= 10);
return 0;
}
continue:
#include <stdio.h>
int main()
{
int i = 1;
do
{
if (i == 5)
continue;
printf("%d ", i);
i = i + 1;
} while (i <= 10);
return 0;
}
2.循环的嵌套
在解决实际问题时,三种循环往往需要一起使用,这就是循环的嵌套,下面我们来举几个例子。
练习1:
找出100到200之间的素数,并打印在屏幕上。
注:素数又称质数,只能整除1和它本身的数。
题目分析:
首先,我们需要打印出100到200之间的每一个数字,这是外层循环,然后再判断i是否为素数。我们可以生成从2到i-1之间的数字,然后用i去试除每一个数。
参考代码:
#include<stdio.h>
int main()
{
int i = 0;
for (i = 100; i <= 200; i++)
{
int t = 0;
int flag = 1;
for (t = 2; t < i; t++)
{
if (i % t == 0)
{
flag = 0;
break;
}
}
if (flag == 1)
printf("%d ", i);
}
return 0;
}
运行结果:
3.goto语句
C语言提供了一种非常特别的语法,就是goto语句和跳转符号,goto语句可以实现在同一个函数内跳转到设置好的标号处。
例如:
#include <stdio.h>
int main()
{
printf("hehe\n");
goto next;
printf("haha\n");
next:
printf("跳过了haha的打印\n");
return 0;
}
运行结果:
但是goto语句如果随意使用,就会导致函数内部随意乱跳转,打乱程序的运行,所以说能不用还是尽量不要用。但是goto语句并不是完全不好,在多层循环中,如果想直接跳出所有循环,可以用goto,break语句每次只能跳出一层循环,比较麻烦。
4.关系操作符
C语言常用的表达式叫关系表达式,里面的运算符就叫关系运算符,常用的关系运算符有:
>大于
<小于
<=小于等于
>=大于等于
!=不相等
==相等
注意:相等运算符==和赋值运算符=是两个不一样的运算符,不能混淆。有时候,会不小心写出下列的代码,可能也不会报错,但是运行结果不同。
if(x=3)
我们本想写x==3的判断条件,但是不小心写成了x=3,此时,将x赋值为3,系统并不会报错,但是非0的条件判断都为真。
为了防止这种错误,有些程序员喜欢把变量写到右边。
if(3==x)
此时如果把==误写成=,编译器就会报错。
另一个需要避免的错误就是,多个运算符不宜连用。
i<j<k
这种写法编译器并不会报错,但是运行的结果却不是我们想要的。因为关系运算符是从左到右计算的,实际运行的结果是下面的表达式:
(i<j)<k
上面式子中i<j返回0或1,所以最终是0或1与k进行比较。如果想判断j是否在i和k之间,需要用下面的代码:
i<j&&j<k
练习:我们输入一个年龄,如果年龄在18到36之间,我们就输出青年。
#include <stdio.h>
int main()
{
int age = 0;
scanf("%d", &age);
if (age >= 18 && age <= 36)
{
printf("⻘年\n");
}
return 0;
}
5.条件操作符
条件操作符也叫三目操作符,需要接受三个操作数的,形式如下:
exp1?exp2:exp3
条件操作符的计算逻辑是:如果exp1为真,执行exp2;如果exp1为假,执行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", m);
return 0;
}
6.逻辑操作符
!:逻辑取反运算符(改变单个表达式的真假)
&&:并且
||:或者
6.1 !
a | !a |
非0 | 0 |
0 | 非0 |
C语言中,非0表示真,0表示假。
举例,我们有一个变量叫flag,如果flag为假,打印,代码如下:
#include <stdio.h>
int main()
{
int flag = 0;
if(!flag)
{
printf("do something\n");
}
return 0;
}
如果flag为真,!flag就是假。上面代码的意思就是flag为假,执行if中的语句。
6.2 &&
a | b | a&&b |
非0 | 非0 | 非0 |
非0 | 0 | 0 |
0 | 非0 | 0 |
0 | 0 | 0 |
&&的意思是并且,是一个双目操作符,只有两边的表达式都为真时,整个表达式才为真,只要有一个为假,整个表达式都为假。
举例:如果我们说月份为3月到4月,是春天,那使用代码怎么体现呢?
#include <stdio.h>
int main()
{
int m;
scanf("%d", &m);
if (m >= 3 && m <= 5)
{
printf("春季");
}
return 0;
}
6.3 ||
a | b | a||b |
非0 | 非0 | 非0 |
非0 | 0 | 非0 |
0 | 非0 | 非0 |
0 | 0 | 0 |
||的意思是或者,也是一个双目操作符,表达式两边只要有一个为真,整个表达式都为真,两边都为假时,才为假。
比如:我们说一年中月份是12月或者1月或者2月是冬天,怎么用代码体现?
#include <stdio.h>
int main()
{
int m;
scanf("%d", &m);
if (m == 12 || m == 1 || m == 2)
{
printf("冬季");
}
return 0;
}
6.4 短路
C语言逻辑运算符还有一个特点,他总是先对左侧的表达式求值,再对右边的表达式求值。
如果左边的表达式满足逻辑运算符的条件,就不再对右边的表达式求值,这种情况称为“短路”。
如前面的代码:
if(m >= 3 && m <= 5)
表达式左操作是m>=3,右操作是m<=5,当左操作的结果是0的时候,即使不判断右操作,整个表达式的结果也是0。
所以对于&&操作符来讲,左操作为假时,右操作就不再执行。
那||操作符是怎么样的呢?结合前面的代码:
if (m == 12 || m == 1 || m == 2)
如果m==12,就不用再判断m是否等于1或者2;整个表达式也为真。
所以,||操作符的左操作不为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\nd = %d\n", a, b, c, d);
return 0;
}
在这段代码中,我们主要看i的表达式,a++是先使用后自加,因为a=0,所以为假,造成短路,不会再执行后面的代码,所以b和d的值都不会变。
我们再来看这段代码:
#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\nd = %d\n", a, b, c, d);
return 0;
}
我们同样看i的表达式,a++是先使用后自加,a=0为假,因为是||运算符,直到碰到真才会短路,所以继续执行,++b是先自加后使用,b=3非零所以为真,此时短路,后面代码不再执行,所以d的值不会改变。