C语言是结构化的程序设计语言,这里的结构指的是顺序结构、选择结构、循环结构,C语言是能够实现这三种结构的,其实我们如果仔细分析,我们日常所见的事情都可以拆分为这三种结构或者这三种结构的组合。
1.if语句
1.1语句
if语句的语法形式如下:
if(表达式)
语句
表达式的结果如果为真(非0),则语句执行,表达式为假(为0),则语句不执行
例子:
一个局部变量不初始化的时候,它的默认值是随机值,所以当对这个值进行计算的时候,未来如何变化,不好追踪。
#include<stdio.h>
int main()
{
int i = 0;
scanf("%d", &i);//输入
if (i % 2 == 0)//判断
{
printf("是偶数");//输出
}
else
{
printf("是奇数");
}
return 0;
}
判断相等用两个等号。
1.2 else
如果⼀个数不是奇数,那就是偶数了,如果任意⼀个整数,我们要清楚的判断是奇数还是偶数怎么表 ⽰呢? 这⾥就需要 if...else... 语句了,语法形式如下:
if(表达式)
语句1
else
语句2
练习:输入一个年龄,>=18岁就输出:成年,否则就输出:未成年
int main()
{
int year = 0;
scanf("%d", &year);
if (year >= 18)
{
printf("成年");
}
else
{
printf("未成年");
}
return 0;
}
1.3 分支中包含多条语句
默认情况下if和else语句中都只控制一条语句。
if语句中包含了两条语句,显示报错。那如果我们要if语句同时控制2条语句,怎么办呢?那就要使⽤ {} 将代码括起来, else后也可以跟上⼤括号。
1.4 嵌套 if
在 if else 语句中,else 可以与另一个 if 语句连用,构成多重判断。
比如: 要求输⼊⼀个整数,判断输⼊的整数是0,还是正数或者负数。
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 后是不用加括号的。还可以用下面这种方式写,只要逻辑满足就可以。
int main()
{
int num = 0;
scanf("%d", &num);
if (num > 0)
printf("是正数");
else if (num == 0)
printf("是 0");
else
printf("是负数");
return 0;
}
再比如:输入一个整数,如果是正数,再判断是奇数还是偶数,并输出;如果不是正数则输出:⾮正数。
int main()
{
int num = 0;
scanf("%d", &num);
if (num > 0)
{
if (num % 2 == 0)
printf("是偶数");
else
printf("是奇数");
}
else
{
printf("非正数");
}
return 0;
}
练习:
输⼊⼀个⼈的年龄 如果年龄18岁,打印"少年" 如果年龄在18岁⾄44岁打印"⻘年" 如果年龄在45岁⾄59岁打印"中⽼年" 如果年龄在60岁⾄89岁打印"⽼年" 如果90岁及以上打印"⽼寿星"
int main()
{
int age = 0;
scanf("%d", &age);
if (age < 18)
printf("少年\n");
else if (age <= 44)
printf("⻘年\n");
else if (age <= 59)
printf("中⽼年\n");
else if (age <= 89)
printf("⽼年\n");
else
printf("⽼寿星\n");
return 0;
}
1.5 悬空 else问题
如果有多个 if 和 else ,可以记住这样⼀条规则, else 总是跟最接近的 if 匹配。 我们⾸先从下⾯代码开始
判断该代码打印出的是hehe还是hah,但是当我们运行代码,输出的结果是:啥都不输出。上⾯的代码排版,让 else 和第⼀个 if 语句对⻬,让我们以为 else 是和第⼀个if匹配的,当 if 语句不成⽴的时候,⾃然想到的就是执⾏ else ⼦句,打印 haha ,但实际上 else 是和第⼆个 if 进⾏匹配的,这样后边的 if...else 语句是嵌套在第⼀个 if 语句中的,如果第⼀个 if 语句就不 成⽴,嵌套 if 和 else 就没机会执⾏了,最终啥都不打印。
或者如果我们希望 else 确实和第一个 if 匹配,可以这样修改代码:
int main()
{
int a = 0;
int b = 2;
if (a == 1)
{
if (b == 2)
printf("hehe\n");
}
else
{
printf("haha\n");
}
return 0;
}
只要带上适当的⼤括号,代码的逻辑就会更加的清晰,所以⼤家以后在写代码的时候要注意括号的使 ⽤,让代码的可读性更⾼。
2.关系操作符
C语言用于比较的表达式,称为“关系操作符”,里面使用的运算符就称“关系运算符”,主要有下面几个:
在C语言中,=是赋值,==是判断相等。关系表达式的结果通常返回0或1,表示真假。C语言中,0表示假,所有非零值表示真。
观察如下代码:
#include<stdio.h>
int main()
{
int a = 4;
int b = 5;
int c = (a > b);
printf("%d", c);
return 0;
}
运行结果为0,a>b并不成立,所以为假,c的值就为0.
关系表达式常用于if 或while语句中。
需要避免的错误是:多个关系运算符不宜连用。
int main()
{
int x = 6;
int y = 3;
int z = 5;
if (x < y < z)
{
printf("hehe\n");
}
else
{
printf("haha\n");
}
return 0;
}
观察这个比较关系式,是非常明显的,if语句不满足为假,所以打印haha,但是结果并不是我们想的那样,最终打印的结果为hehe,这是因为,x<y<z表达式是先判断x<y,不满足为假所以为0,接下来,再判断0<z,很明显是满足的,所以为真,打印hehe。
那如果我们就是想要去实现x<y<z,我们可以用如下的表达式来表达:
if ( x < y && y < z )
3.条件操作符
条件操作符也叫三目操作符,需要接受三个操作数,形式如下:
exp1 ? exp2 :exp3
条件操作符的计算逻辑是:如果 exp1 为真, exp2 计算,计算的结果是整个表达式的结果;如果 exp1 为假, exp3 计算,计算的结果是整个表达式的结果。
我们观察如下两个代码来理解条件操作符:
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;
}
int main()
{
int a = 0;
int b = 0;
scanf("%d", &a);
b = (a > 5 ? 3 : -3);
printf("%d\n", b);
return 0;
}
如果a>5为真,那么3就是整个表达式的结果,如果exp1的结果为假,那么整个表达式的结果就为-3。
4.逻辑操作符
逻辑操作符提供逻辑判断功能,用于构建更复杂的表达式,主要有下面三个运算符。
!:逻辑取反运算符(改变单个表达式的真假)
&&:逻辑与运算符,就是并且的意思(两侧的表达式都为真,则为真,否则为假)。
||:逻辑或运算符,就是或者的意思(两侧至少有一个表达式为真,则为真,否则为假)。
4.1逻辑取反运算符
上面的代码和运行结果,演示了逻辑取反运算符的使用,flag本来为假,使用了!后改变了真假,变为了真,所以可以输出。
4.2逻辑与运算符
&& 就是与运算符,也是并且的意思, && 是⼀个双⽬操作符,使⽤的⽅式是 a&&b , && 两边的表达 式都是真的时候,整个表达式才为真,只要有⼀个是假,则整个表达式为假。
有假则为假,两个同时为真,才是真!!
比如:我们说3月到5月,是春天,那使用代码怎么体现?
int main()
{
int month = 0;
scanf("%d", &month);
if (month >= 3 && month <=5)
{
printf("%d 月是春天", month);
}
return 0;
}
月份是大于等于三月,并且同时满足小于等于五月。
4.3 逻辑或运算符
只要有一个真,表达式就为真,两个都为假的才为假。
比如:我们一年中月份是12月或者1月或者2月是冬天,那么我们怎么使用代码体现?
int main()
{
int month = 0;
scanf("%d", &month);
if (month == 12 || month == 1 || month == 2)
{
printf("%d 是冬天\n", month);
}
return 0;
}
4.4 判断是否为闰年
闰年判断的规则:
1.能被4整除并且不能被100整除是闰年
2.能被400整除是闰年
分析第一个规则中有并且,说明两个都要满足,而第一个规则很多第二个规则是或的关系,只要满足一个就是闰年。
int main()
{
int year = 0;
scanf("%d", &year);
if (year % 4 == 0)
{
if (year % 100 != 0)
{
printf("%d 是闰年\n", year);
}
}
if (year % 400 == 0)
{
printf("%d 是闰年\n", year);
}
return 0;
}
上面的代码并没有满足我们学的逻辑运算符,可以再进一步改进:
int main()
{
int year = 0;
scanf("%d", &year);
if ((year % 4 == 0 && year % 100 != 0) || (year % 400 == 0))
{
printf("%d 是闰年\n", year);
}
return 0;
}
4.5 短路
C语⾔逻辑运算符还有⼀个特点,它总是先对左侧的表达式求值,再对右边的表达式求值,这个顺序是 保证的。 如果左边的表达式满⾜逻辑运算符的条件,就不再对右边的表达式求值。这种情况称为“短路”。
如下代码:
if (month >=3 && month <=5)
如果month是2,,左边的表达式都不满足,也就不会判断右边的表达式。如果前面为假,后面不计算,如果前面为真,后面要计算。
像这种仅仅根据左边操作数的结果就能知道整个表达式的结果,不再对右操作数进行计算的运算称为短路求值
阅读该代码并得出结论:
#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;
}
a++是后置加加,先使用再加加,所以a++表达式为0,为假,左边已经为假,所以右边不用再计算了。可以再自己去尝试一下||运算符。
5.switch语句
在前面我们提到了if语句的嵌套也可以实现多路分支,但是如果分支太多,即嵌套的if语句层数过多,则程序冗长且可读性较低。为此,C语言提供了更简练的语句——switch语句。
一般形式如下:
switch(表达式)
{
case 常量1:语句1
case 常量2:语句2
case 常量3:语句3
. .
. .
. .
. .
case 常量n:语句n
}
上面代码中,根据表达式不同的值,执行相应的case分支,如果找不到对应的值,就执行default分支。
注:
1.switch后的表达式必须是整型表达式
2.case后的值,必须是整型常量表达式。
5.1 if语句和switch语句的对比
练习:输⼊任意⼀个整数值,计算除3之后的余数
分析:无论是哪个值%3的结果只能是0/1/2
int main()
{
int num = 0;
scanf("%d", &num);
switch (num & 3)
{
case 0:
printf("余数是0\n");
break;
case 1:
printf("余数是1\n");
break;
case 2:
printf("余数是2\n");
break;
}
return 0;
}
C语言提供break语句,专用于跳出switch语句。break语句只有关键字break,没有参数。
注:case后可以使用字符,必须要加单引号。