C语⾔是结构化的程序设计语⾔,这⾥的结构指的是顺序结构、选择结构、循环结构。
可以使⽤ if 、 switch 实现分⽀结构,使⽤ for 、 while 、 do while 实现循环结构。
一.if语句
1.if
if 语句的语法形式如下:
if ( 表达式 )语句
表达式
成⽴(为真)
,则语句执⾏:表达式
不成⽴(为假)
,则语句不执⾏。
在C语⾔中,
0为假
,
⾮0表⽰真
,也就是表达式的结果如果是0,则语句不执⾏,表达式的结果如
果不是0,则语句执⾏。
2.else
if...else...语法形式如下:
if ( 表达式 )语句1else语句2
例:输⼊⼀个年龄,>= 18岁就输出:成年,否则就输出:未成年
#include <stdio.h>
int main()
{
int age = 0;
scanf("%d", &age);
if(age>=18)
printf("成年\n");
else
printf("未成年\n");
return 0;
}
3.分⽀中包含多条语句
if 语句只能控制
⼀条语句,如果要 if 语句
同时控制2条语句,那就要使⽤
{ } 将代码括起来, else 后也可以跟上⼤括号。
if(age >= 18) //if 后使⽤ { } 来控制多条语句-这个块也叫: 程序块,或者复合语句{printf("成年了\n");printf("可以谈恋爱了\n");}else //else 后使⽤ { } 来控制多条语句-这个块也叫: 程序块,或者复合语句{printf("未成年\n");printf("好好学习\n");}
4.嵌套if
在 if else 语句中, else 可以与另⼀个 if 语句连⽤,构成
多重判断。
输⼊⼀个整数,判断输⼊的整数是0,还是正数或者负数:if(num == 0)printf("输⼊的数字是0\n");else if (num > 0) //这⾥的 if 相当于嵌套在else语句中,形成了嵌套结构printf("输⼊的数字是正数\n");elseprintf("输⼊的数字是负数\n");// if else表示嵌套在 else里面的if语句,构成了 嵌套的 if 语句。
输⼊⼀个整数,如果是正数,再判断是奇数还是偶数,并输出;如果不是正数则输出:⾮正数:if(num>0){if(num%2 == 0)printf("偶数\n");elseprintf("奇数\n");}else{printf("⾮正数\n");}// if else表示嵌套在 if 语句中的if语句,构成了 嵌套的 if 语句。
5.悬空else问题
如果有
多个 if 和 else ,
else 总是跟
最接近的 if 匹配。
int a = 0;int b = 2;if(a == 1)if(b == 2)printf("hehe\n");elseprintf("haha\n"); //结果为 什么都没输出
实际上
else 是和第⼆个
if 进⾏匹配的,这样后边的
if...else 语句是
嵌套在第⼀个 if 语句中的,如果
第⼀个 if 语句就不 成⽴,嵌套 if 和 else 就
没机会执⾏了,最终
啥都不打印。
若将
if...else 语句整体用
{ }括起来,则更容易理解。
二.关系操作符
C 语⾔⽤于
⽐较的表达式,称为
“关系表达式”,⾥⾯使⽤的
运算符就称为
“关系运算符”。
•
> ⼤于运算符
•
< ⼩于运算符
•
>= ⼤于等于运算符
•
<= ⼩于等于运算符
•
== 相等运算符
•
!= 不相等运算符
关系表达式通常返回
0 或 1 ,表⽰
真假。
C 语⾔中,
0 表⽰假,所有⾮零值表⽰真。⽐如, 20 > 12 返回 1 , 12 > 20 返回 0 。
关系表达式常⽤于
if 或
while 结构。
if (x == 3){printf("x is 3.\n");}
相等运算符
== 与 赋值运算符
= 是两个不⼀样的运算符。
1.错误⽰例一:
原意是 x == 3 ,但是不⼩⼼写成 x = 3 。这个式⼦表⽰对变量 x 赋值 3 ,它的返回值为 3 ,所以
if 判断总是为真。
将
变量写在等号的右边。如果把 == 误写成 = ,编译器就会
报错。
if (3 == x) ... //若不小心只写了一个=,则编译器显示运行错误
2.错误示例二:
多个关系运算符不宜连⽤。
i < j < k关系运算符是 从左到右计算,所以实际执⾏的是(i < j) < k // i < j 返回 0 或 1 ,所以最终是 0 或 1 与变量 k 进⾏ ⽐较。
想要判断变量
j 的值
是否在 i 和 k 之间,应该使⽤下⾯的写法:
i < j && j < k
3.正确示例:
输⼊⼀个年龄,如果年龄在18岁~36岁之间,我们输出⻘年:
#include <stdio.h>
int main()
{
int age = 0;
scanf("%d",&age);
if(age>=18 && age<=36)
{
printf("⻘年\n");
}
return 0;
}
三.条件操作符:也叫三⽬操作符,需要接受三个操作数的。
形式:
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;
//若输入20和50,结果为50;若输入50和20,结果为20.
printf("%d\n", m);
return 0;
}
四.逻辑操作符:&& , || , !
• ! :逻辑取反运算符(改变单个表达式的真假)。
•
&& :与运算符,就是并且的意思(两侧的表达式都为真,则为真,否则为假)。
•
|| :或运算符,就是或者的意思(两侧⾄少有⼀个表达式为真,则为真,否则为假)。
注:C语⾔中,⾮0表⽰真,0表⽰假。
1.逻辑取反运算符 !
示例:有⼀个变量叫 flag ,如果flag为假,要做⼀个什么事情:
int flag = 0;if(!flag){printf("do something\n");}
示例中
flag 为假,
!flag 就是真,执⾏if语句中的代码。
2.与运算符 &&
&& 就是
与运算符,也是
并且的意思, && 是⼀个
双⽬操作符,使⽤的⽅式是 a&&b 。
&& 两边的表达式
都是真的时候,
整个表达式才为真,只要
有⼀个是假,则整个表达式为假。
示例:⽉份是3⽉到5⽉,是春天:
if(month >= 3 && month <= 5){printf("春季\n");}//month既要⼤于等于3,⼜要⼩于等于5,必须 同时满⾜。
3.或运算符 ||
|| 就是
或运算符,也就是
或者的意思, || 也是⼀个
双⽬操作符,使⽤的⽅式是 a || b 。
|| 两边的表达式只要
有⼀个是真,
整个表达式就是真,两边的表达式
都为假的时候,
才为假。
示例:⼀年中⽉份是12⽉或者1⽉或者2⽉是冬天:
if(month == 12 || month==1 || month == 2){printf("冬季\n");}
4. 练习:闰年的判断
闰年判断的规则:
1. 能被4整除并且不能被100整除是闰年
2. 能被400整除是闰年
①方法一:
int year = 0;
scanf("%d", &year);
if(year%4==0 && year%100!=0)
printf("是闰年\n");
else if(year%400==0)
printf("是闰年\n");
②方法二:
int year = 0;
scanf("%d", &year);
if((year%4==0 && year%100!=0) || (year%400==0))
printf("是闰年\n");
5.短路
C语⾔
逻辑运算符的⼀个
特点
:它总是先对
左侧的表达式求值,再对右边的表达式求值,这个顺序是保证的。
如果左边的表达式
满⾜逻辑运算符的条件,
就不再对右边的表达式求值。这种情况称为
“短路”。
仅仅根据左操作数的结果就能知道整个表达式的结果,不再对右操作数进⾏计算的运算称为短路求值。
(1)示例2中:
if(month >= 3 && month <= 5)
当左操作数 month >= 3 的结果是
0的时候,即使
不判断 month <= 5 ,整个表达式的结果也是
0(不是春季)。
对于&&操作符来说,
左边操作数的结果是
0的时候,
右边操作数就不再执⾏。
(2)示例3中:
if(month == 12 || month==1 || month == 2)
如果month == 12,则
不⽤再判断month是否等于1或者2,整个表达式的结果也是1(是冬季)。 所以, || 操作符的
左操作数的结果
不为0时,就
⽆需执⾏右操作数。
五.switch 语句
switch
语句是⼀种特殊形式的
if...else
结构,⽤于判断条件有
多个结果
的情况。它把多重
的
else if
改成更易⽤、可读性更好的形式。
switch (expression){case value1: statementcase value2: statementdefault : statement}
上⾯代码中,根据表达式
expression
不同的值,执⾏
相应的 case 分⽀
。如果
找不到
对应的值,
就执⾏
default 分⽀
。
注
:
•
switch
后的
expression
必须是
整型表达式
•
case
后的值,必须是
整形常量表达式
1.if语句和switch语句的对⽐
例:输⼊任意⼀个整数值,计算除3之后的余数。
①if语句
# include <stdio.h>int main (){int n = 0 ;scanf ( "%d" , &n);if (n% 3 == 0 )printf ( " 整除,余数为 0\n" );else if (n% 3 == 1 )printf ( " 余数是 1\n" );elseprintf ( " 余数是 2\n" );return 0 ;}
②switch语句(case决定入口,break决定出口)
# include <stdio.h>int main (){int n = 0 ;scanf ( "%d" , &n);switch (n% 3 ){case 0 :printf ( " 整除,余数为 0\n" );break ;case 1 :printf ( " 余数是 1\n" );break ;case 2 :printf ( " 余数是 2\n" );break ;}return 0 ;}
注:
1.
case
和后边的
数字
之间必须有
空格
2.
每⼀个
case
语句中的代码执⾏完成后,需要加上
break
,才能跳出这个switch语句。
2.switch语句中的break
case决定入口,break决定出口。
break
语句能实现真正的
分⽀效果
。如果某⼀个 case
语句的后边没有
break
语句,代码会继续往下执⾏,有可能执⾏其他
case 语句中的代码,直到遇到 break
语句或者
switch
语句结束。
3.switch语句中的default
switch 后的表达式中的值
⽆法匹配
代码中的
case 语句
的时候(switch
后边的
expression
的结果不是
value1
,也不是
value2
的时候)就会执⾏
default ⼦句
。
4.switch语句中的case和default的顺序问题
在
switch
语句中
case
语句和
default 语句是
没有顺序要求
的,通常是把
default
⼦句放在最后处理。