if(表达式)
语句;
if(表达式)
语句;
else //“二选一”
语句;
例子:
输入一个整数,判断奇偶
#include
int main()
{ int a = 0;
scanf("%d",&a);
if(a%2 == 0)
printf("%d是偶数",a);
else
printf("%d是奇数",a);
return o;
}
在if语句中,else可以和if连用,形成嵌套if。
例子:
输入一个数,判断是0,还是正数或者负数。
int main()
{
int num = 0;
scanf("%d",&num);
if (num == 0)
printf("%d是0", num);
else if (num > 0)
printf("%d是正数", num);
else printf("%d是负数", num);
return 0;
#include
int main()
{
int a = 0;
int b = 2;
if (a == 1)
if (b == 2)
printf("hehe \n") ;
else
printf("haha\n");
return 0;
}
上述代码中第一个if与else对齐,容易造成误解,导致结果被误认为haha,而实际上结果什么也没有打印,好像else”悬空“了,其实else本就应该没被执行,在嵌套中我们可以理解成else和上边离它最近的if是一对if-else语句,他们共同嵌套在上方的if当中,上方的if条件不满足,下边的语句自然不会执行了。
代码写成下边这样就好理解了
#include
int main()
{
int a = 0;
int b = 2;
if(a == 1)
{
if(b == 2)
printf("hehe\n");
else
printf("haha\n");
}
return 0;
}
关系表达式一般返回0或者1表示真假
注意==和=的区别
防止不小心写错,可以在表达式中把常量写在左边(由于常量不可被赋值,所以如果打错了会报错)
操作符不要连用,会造成错误
比如:
#include
int main()
{
int age = 0;
scanf("%d", &age);
if(18 <= age <= 36)
{
printf("⻘年\n");
}
return 0;
}
上述if表达式中,第一步比较18和age,不管哪个大,返回值的结果不是0就是1,肯定比36小,导致后半段条件判断失真。
int main()
{
int a = 0;
int b = 0;
int m = 0;
scanf("%d,%d", &a, &b);
m = (a > b ? a: b);
printf("m=%d\n", m);
return 0;
}
注意两个占位符中间的,不要输入成英文的,不然会出错。
&&:逻辑与,有一个表达式是假,那整个表达式就是假。
||:逻辑或,有一个表达式是真,那整个表达式就是真。
!:逻辑否 真变假,假变真
练习:输入一个年份,判断它是否为润年(闰年:能被4整除,但是不能被100整除,或者能被400整除)
#include
int main()
{
int a = 0;
int b = 2;
if (a == 1)
if (b == 2)
printf("hehe \n") ;
else
printf("haha\n");
return 0;
}
c语言中逻辑操作符先算左边的表达式,再算右边的表达式,当左边表达式算出结果后已经确定了整个表达式的返回结果时,后边的表达式将不会再计算。
例子;
if(month >= 3 && month <= 5)
练习:阅读下面代码,思考运行的结果
#include
int main()
{
int i = 0, a = 0, b = 2, c = 3, d = 4;
i = a++ && ++b && d++;
printf("a = %d\nb = %d\nc = %d\nd = %d\n", a, b, c, d);
return 0;
}
运行结果是a=1,b=2,c=3,d=4,i=0
解析:回忆我们之前学的自加运算符,++在后边表示a是先用后加,先用使得这个表达式的结果为0,而逻辑运算符从左往右算,从而整个表达式的结果已经确定(i=0),那么后边的表达式将不会再计算。而a在用完之后会给自己自加1。
思考一下,如果将a的初始值改成1,或者把++放到前边,结果又是什么?
可以把switch语句理解成特殊的if-else语句,用来代替嵌套if语句,使结构更加清晰明白
switch(表达式)
{ case 值
语句;
break;
case 值
语句;
break;
default
语句;
break;
}
说明:根据表达式的结果,进入对应的case,如果结果找不到对应的case,则进入default,最后从break跳出switch语句。
注意
int main()
{
int a = 0;
scanf("%d", &a);
switch (a % 3)
{
case 0:
printf("余数是0");
break;//break1
case 1:
printf("余数的是1");
break;//break2
case 2:
printf("余数是2");
}
return 0;
}
如果不加break,那么程序会一直执行,直到遇到break,或者语句结束才会跳出switch语句。
上述代码中输入3,去掉break的情况如下
1.去掉break1,输出结果是:”余数是0余数是1“
2.去掉break2,输出结果是:”余数是0“
记住一点:“case决定入口,break决定出口”就行。
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:
break;
}
return 0;
}
思考一下,假如没有break,而default被写在多个case之间,假如入口是第一个case,将会是什么结果。
我们尝试从意思的角度来理解
if是如果的意思,”如果表达式结果为真“那就执行语句
while是当()时的意思,”当表达式为真时“那就执行语句
不知道大家有没有体会到二者之家的区别和联系,二者都是跟据表达式的真假来决定是否执行语句,但是不同的是while具有多次判断的能力,当表达式为真,就能执行语句,直到表达式为假。而if只判断一次。
int main()
{
int i = 1;
while(i <= 10)
{
printf("%d\n",i);
i++;
}
return 0;
}
int main()
{
int a = 0;
int b = 0;
scanf("%d", &a);
while (a != 0)
{
b = a % 10;
printf("%d", b);
a /= 10;
}
return 0;
}
for(表达式1; 表达式2; 表达式3)
语句;
三个表达式的意义分别是
1.初始化(只执行一次)
2.判断
3.调整
注意
1.在表达式一处初始化的变量只能在循环里用,若想在外部用,可以先在外部初始化
2.三个表达式之间是分号
int main()
{
for (int i = 1;i <= 10;i++)
printf("%d", i);
return 0;
}
int main()
{
int sum = 0;
int i = 0;
for (i = 3;i < 100;i += 3)
sum += i;
printf("%d", sum);
return 0;
}
do
语句;
while(表达式);
这里语句至少执行一次
int main()
{
int num = 0;
scanf("%d", &num);
int cent = 0;
do
{
cent++;
num /= 10;
} while (num != 0);
return 0;
}
思考一下,用for和while怎么写
break:跳出这个循环
continue:跳过这次循环中continue后边的代码
例子:
#include
int main()
{
int i = 1;
while(i <= 10)
{
if(i == 5)
break;//当i等于5后,就执⾏break,循环就终⽌了
printf("%d ", i);
i = i + 1;
}
return 0;
}
#include
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;
}
练习:找出100到200之间的素数
解析,首先要产生100到200 的数(for)
然后根据素数条件筛选,用2到i-1之间的数除i,如果有一个余数为0 的情况,即i被整除,那这个i就不是素数
int main()
{
int i = 0;
for (i = 100;i <= 200;i++)//100到二百的数
{
int flag = 1;//用flag的真假来标志i是否为素数,先假设它为真
for (int j = 2;j < i;j++)//2到i-1的数
{
if (i % j == 0)
{
flag = 0;标志出这个i不是素数
break;跳出的是第二个for循环
}
}
if (flag ==1)如果i被j除完之后没有发现因数,那它就是素数
printf("%d ", i);
}
return 0;
}
注意:flag不要放在第一层循环外面,因为放在第一层循环外边它只等于1一次,在第二层循环中flag等于0后,它就一直等于0了,由于第一个i=100不是素数,结果将变成啥也不打印。
将上述代码的算法优化
由于i是由俩个因数相乘得到的,故这两个因数至少有一个小于等于开根后的i,只要j小于等于开根号的i,那它一定包含一个因数。
#include
int main()
{
int i = 0;
for (i = 100;i <= 200;i++)
{
int flag = 1;
for (int j = 2;j <= sqrt(i);j++)
{
if (i % j == 0)
{
flag = 0;
break;
}
}
if (flag ==1)
printf("%d ", i);
}
return 0;
}
注意用sqrt开方函数要加头文件。
‘可实现从一个函数内调到设置好的标号处
但是不提倡使用,防止打乱程序流程
建议在多层嵌套函数中跳出使用
思考一下,为什么不用break?