1.if语句
1.1 if
if 语句的语法形式如下:
if ( 表达式 ) 语句
表达式成立(为真),则语句执行,表达式不成立(为假),则语句不执行。
在C语言中,0为假,非0表示真,也就是表达式的结果如果是0,则语句不执行,表达式的结果如果不是0,则语句执行。
例子:输入一个整数,判断是否为奇数
#include <stdio.h> int main() { int num = 0; scanf("%d", &num); if(num % 2 == 1) printf("%d 是奇数\n", num); return 0; }
1.2 else
如果一个数不是奇数,那就是偶数了,如果任意一个整数,我们要清楚的判断是奇数还是偶数怎么表示呢?
这里就需要ifelse 语句了,语法形式如下:
if ( 表达式 ) 语句1 else 语句2
例子:输入一个整数,判断是否为奇数,如果是奇数打印是奇数,否则打印偶数。
#include <stdio.h> int main() { int num = 0; scanf("%d", &num); if(num % 2 == 1) printf("%d 是奇数\n", num); else printf("%d 是偶数\n", num); return 0; }
练习:输入一个年龄,>= 18岁就输出:成年,否则就输出:未成年
#include <stdio.h> int main() { int age = 0; scanf("%d", &age); if(age>=18) printf("成年\n"); else printf("未成年\n"); return 0; }
1.3 分支中包含多条语句
#include <stdio.h> int main() { int age = 0; scanf("%d", &age); if(age >= 18) printf("成年了\n"); printf("可以谈恋爱了\n"); return 0; }
上面的代码,你会发现输入的值不管是>=18 还是<18,"可以谈恋爱了" 都会打印在屏幕上。
这是因为if 语句只能控制一条语句,就是printf("成年了\n"); ,if语句为真,则打印成年了,
if语句为假,则不打印,对于printf("可以谈恋爱了\n"); 是独立存在的,不管if语句的条件的真
假,都会被执行。那如果我们要if语句同时控制2条语句,怎么办呢?那就要使用 {} 将代码括起来,
else 后也可以跟上大括号。如下:
include <stdio.h> int main() { int age = 0; scanf("%d", &age); if(age >= 18) //if 后使用{} 控制多条语句-这个块也叫:程序块,或者复合语句 { printf("成年了\n"); printf("可以谈恋爱了\n"); } return 0; } #include <stdio.h> int main() { int age = 0; scanf("%d", &age); if(age >= 18) //if 后使用{} 控制多条语句-这个块也叫:程序块,或者复合语句 { printf("成年了\n"); printf("可以谈恋爱了\n"); } else //else 后使用{}控制多条语句-这个块也叫:程序块,或者复合语句 { printf("未成年\n"); printf("不可以早恋哦\n"); } return 0; }
1.4 嵌套if
在if else 语句中, else 可以与另一个if 语句连用,构成多重判断。
比如:要求输入一个整数,判断输入的整数是0,还是正数或者负数。请看如下代码:
#include <stdio.h> int main() { int num = 0; scanf("%d", &num); if(num == 0) printf("输入的数字是0\n"); else if(num > 0) //这里的if 相当于嵌套在else语句中,形成了嵌套结构 printf("输入的数字是正数\n"); else printf("输入的数字是负数\n"); return 0; }
上图中橙色背景的代码就是嵌套在前面的else 子句中的,构成了嵌套的if语句。
再比如:
输入一个整数,如果是正数,再判断是奇数还是偶数,并输出;如果不是正数则输出:非正数。
#include <stdio.h> int main() { int num = 0; scanf("%d", &num); if(num>0) { if(num%2 == 0) printf("偶数\n"); else printf("奇数\n"); } else { printf("非正数\n"); } return 0; }
以上就是嵌套if语句的语法,有了嵌套if语句,就可以完成更多复杂逻辑的判断。
1.5 悬空else问题
如果有多个if 和else ,可以记住这样一条规则, 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; }
程序运行的结果是啥?
很多初学者,上来以判断a 是 0,不等于 1 ,那就执行 else 子句,打印haha
但是当你去运行代码,输出的结果是:啥都不输出
这就是悬空else 的问题,如果有多个if 和else ,可以记住这样一条规则, else 总是跟最接近
的if 匹配。
上面的代码排版,让else 和第一个if 语句对齐,让我们以为else 是和第一个if匹配的,当if
语句不成立的时候,自然想到的就是执行 else 子句,打印haha ,但实际上else 是和第二个if
进行匹配的,这样后边的if...else 语句是嵌套在第一个if 语句中的,如果第一个if 语句就不
成立,嵌套if 和else 就没机会执行了,最终啥都不打印。
如果代码改成下面这样就更加容易理解了
2. 关系操作符
C 语言用于比较的表达式,称为 “关系表达式”(relational expression),里面使用的运算符就称
为“关系运算符”(relational operator),主要有下面6个。
- > 大于运算符
- < 小于运算符
- >= 大于等于运算符
- <= 小于等于运算符
- == 相等运算符
- != 不相等运算符
下面是一些例子
a == b; a != b; a < b; a > b; a <= b; a >= b;
关系表达式通常返回0 或1 ,表示真假。
C 语言中, 0 表示假,所有非零值表示真。比如, 20 > 12 返回1 , 12 > 20 返回0 。
关系表达式常用于if 或while 结构。
if (x == 3) { printf("x is 3.\n"); }
注意:相等运算符== 与赋值运算符= 是两个不一样的运算符,不要混淆。有时候,可能会不小心写
出下面的代码,它可以运行,但很容易出现意料之外的结果。
if (x = 3) ...
上面示例中,原意是x == 3 ,但是不小心写成x = 3 。这个式子表示对变量x 赋值3 ,它的返
回值为3 ,所以if 判断总是为真。
为了防止出现这种错误,有的程序员喜欢将变量写在等号的右边
if (3 == x) ...
这样的话,如果把== 误写成= ,编译器就会报错。
1. /* 报错 */ 2. if (3 = x) ...
另一个需要避免的错误是:多个关系运算符不宜连用
3. 条件操作符
条件操作符也叫三目操作符,需要接受三个操作数的,形式如下
exp1 ? exp2 : exp3
条件操作符的计算逻辑是:如果exp1 为真, exp2 计算,计算的结果是整个表达式的结果;如果
exp1 为假, exp3 计算,计算的结果是整个表达式的结果
练习1:使用条件操作符表示下面代码的逻辑
#include <stdio.h> int main() { int a = 0; int b = 0; scanf("%d", &a); if (a > 5) b = 3; else b = -3; printf("%d\n", b); return 0; } 改造后: #include <stdio.h> int main() { int a = 0; int b = 0; scanf("%d", &a); b = a>5 ? 3:-3; printf("%d\n", b); return 0; }
4. 逻辑操作符:&& , || , !
逻辑运算符提供逻辑判断功能,用于构建更复杂的表达式,主要有下面三个运算符。
• ! :逻辑取反运算符(改变单个表达式的真假)。
• && :逻辑与运算符,就是并且的意思(两侧的表达式都为真,则为真,否则为假)。
• || :逻辑或运算符,就是或者的意思(两侧至少有一个表达式为真,则为真,否则为假)。
注:C语言中,非0表示真,0表示假
4.1 逻辑取反运算符 !
比如,我们有一个变量叫flag ,如果flag为假,要做一个什么事情,就可以这样写代码:
#include <stdio.h> int main() { int flag = 0; if(!flag) { printf("do something\n"); } return 0; }
如果flag 为真, !flag 就是假,如果flag 为假, !flag 就是真
所以上面的代码的意思就是flag 为假,执行if语句中的代码.
4.2 逻辑与运算符
&& 就是与运算符,也是并且的意思, && 是一个双目操作符,使用的方式是a&&b , && 两边的表达式都是真的时候,整个表达式才为真,只要有一个是假,则整个表达式为假。
比如:如果我们说月份是3月到5月,是春天,那使用代码怎么体现呢?
int month = 0; scanf("%d", &month); if(month >= 3 && month <= 5) { printf("春季\n"); }
这里表达的意思就是month既要大于等于3,又要小于等于5,必须同时满足。
4.3 逻辑或运算符
|| 就是或运算符,也就是或者的意思, || 也是一个双目操作符,使用的方式是a || b , ||
两边的表达式只要有一个是真,整个表达式就是真,两边的表达式都为假的时候,才为假。
比如:我们说一年中月份是12月或者1月或者2月是冬天,那么我们怎么使用代码体现呢?
int month = 0; scanf("%d", &month); if(month == 12 || month==1 || month == 2) { printf("冬季\n"); }
4.4 练习:闰年的判断
输入一个年份year,判断year是否是闰年
闰年判断的规则:
1. 能被4整除并且不能被100整除是闰年
2. 能被400整除是闰年
#include <stdio.h> //代码1 int main() { int year = 0; scanf("%d", &year); if(year%4==0 && year%100!=0) printf("是闰年\n"); else if(year%400==0) printf("是闰年\n"); return 0; } //代码2 int main() { int year = 0; scanf("%d", &year); if((year%4==0 && year%100!=0) || (year%400==0)) printf("是闰年\n"); return 0; }
4.5 短路
C语言逻辑运算符还有一个特点,它总是先对左侧的表达式求值,再对右边的表达式求值,这个顺序是保证的。
如果左边的表达式满足逻辑运算符的条件,就不再对右边的表达式求值。这种情况称为“短路”。
如前面的代码:
if(month 1 >= 3 && month <= 5)
表达式中&& 的左操作数是month >= 3 ,右操作数是month <= 5 ,当左操作数month >= 3 的
结果是0的时候,即使不判断month <= 5 ,整个表达式的结果也是0(不是春季)。
所以,对于&&操作符来说,左边操作数的结果是0的时候,右边操作数就不再执行。
对于|| 操作符是怎么样呢?我们结合前面的代码:
if(month == 12 || month==1 || month == 2)
如果month == 12,则不用再判断month是否等于1或者2,整个表达式的结果也是1(是冬季)。
所以, || 操作符的左操作数的结果不为0时,就无需执行右操作数。
像这种仅仅根据左操作数的结果就能知道整个表达式的结果,不再对右操作数进行计算的运算称为短路求值
练习:阅读代码,计算代码输出的结果
#include <stdio.h> int main() { int i = 0,a=0,b=2,c =3,d=4; i = a++ && ++b && d++; //i = a++||++b||d++; printf("a = %d\n b = %d\n c = %d\nd = %d\n", a, b, c, d); return 0; }