零基础学C语言(4):进一步的判断与循环
逻辑类型和运算
C语言中本来没有布尔类型,关系运算的结果是0或1,就可以使if语句执行还是不执行。
- include <stdbool.h>
- 包含一个头文件以后才可以使用bool和true、false,但并没有真正的布尔量类型。
#include <stdio.h>
#include <stdbool.h>
int main()
{
bool b = 6>5;
bool t = true;
t = 2;
printf("%d\n",b);
return 0;
}
但输出的b只能是1,而不能是布尔量。
1
逻辑运算
- 逻辑运算是对逻辑量进行的运算,结果只有0或1
- 逻辑量是关系运算或逻辑运算的结果
Try:
如果要表达数学中的区间,如: x ∈(4,6)或x ∈[4,6],应该如何写C的表达式?
像4<x<6这样的式子,不是C能正确计算的式子,因为4<x的结果是一个逻辑值(0或1).
因此要写出 x>4 && x<6
的式子
如何判断一个字符c是否是大写字母?
c >=‘A’&& c<=‘Z’
理解一下:
age > 20 && age < 30
index <0 || index > 99
! age<20 (!age优先, age是0,!age变1;age不是0,!age变0。1/0再和20做比较,一定是1)
!(age<20)(age >=20)
! > && >|| (!done && (count > MAX))
运算符的优先级
短路
逻辑运算是自左向右进行的,如果左边的结果已经能够决定结果了,就不会做右边的计算
- a == 6 && b==1
- a == 6 && b+=1
- 对于&&,左边是false时就不做右边了
- 对于||,左边是true时就不做右边了
不要把赋值,包括复合赋值组合进表达式!
条件运算符
条件?条件满足时的值?条件不满足时的值;
count= (count > 20) ? count -10 : count+10;
那么上面这句话就等于下面蓝色选中部分。
条件运算符的优先级高于赋值运算符,但是低于其他运算符
- m<n ? x : a+5
- ++ >= 1 && b-- > 2 ? a : b
- x=3 *a ? 5 ? 5 : 20
嵌套条件表达式
理解太困难!不推荐使用!
- count = (count > 20) ? (cout < 50) ? count -10: count - 5 : (count <10 ) ? count + 10 :count + 5;
- 条件运算符是自右向左结合的
- w< x ? x + w : x<y ? x:y
逗号运算符
逗号用来连接两个表达式,并以其右边的表达式的值作为它的结果。过号的优先级是所有的运算符中最低的,所以它两边的表达式会先计算;过号的组合关系是自左向右,所以左边的表达式会先计算,而右边的表达式的值就留下来作为逗号运算的结果。
#include <stdio.h>
int main()
{
int i;
i = 3+4,5+6;
printf("%d\n",i);
return 0;
}
运行的结果是7,先计算逗号左边的 i=3+4=7,没有用到5+6的结果。
7
看看加上一对括号以后的逗号表达式。
#include <stdio.h>
int main()
{
int i;
i = (3+4,5+6);
printf("%d\n",i);
return 0;
}
运行的结果是11,是逗号表达式右边的5+6的结果。
那这个逗号表达式有什么用?主要是在for语句里面。
for里面用“;”隔出3个区域,每个区域是一个表达式,如果想在一个区域放多个计算结果的时候,就可以用逗号表达式。
for ( i=0.,j=10 ; i<j ; i++,j- - ) ......
嵌套的if-else语句
上一篇文章《零基础学浙大翁恺C语言(3)》中 “比较数的大小”找“ 三个数中的最大值”时,已经写到过。
嵌套的判断
当if的条件满足或者不满足的时候要执行的语句也可以是一条if或if-else语句,这就是嵌套的if语句。
# include <stdio.h>
int main()
{
const int READY =24;
int code =0 ;
int count = 0;
scanf("%d %d",&code,&count);
if (code == READY)
if (count <20 )
printf("一切正常\n");
else
printf("继续等待\n") ;
return 0;
}
注意!上面代码中else只跟前面离得最近的if,与缩进无关。
可以加上大括号,再else匹配第一个if。
Tips:
- 在if或else后面总是用{}
- 即使只有一条语句的时候
级联的if-else语句
也就是数学里说的分段函数。
多路分支
多个else if或者switch-case可以做出多路分支。
switch-case
switch(控制表达式){
case 常量:
语句
...
case 常量:
语句
break
default:
语句
...
注意
1.控制表达式只能是整数型的结果
2.常量可以是常数,也可以是常数计算的表达式。
3.switch语句可以看作是一种基于计算的跳转,计算控制表达式的值后,程序会跳转到相匹配的case(分支标号)处。分支标号只是说明switch内部位置的路标,在执行完分支中的最后一条语句后,如果后面没有break,就会顺序执行到下面的case里去,直到遇到一个break,或者switch结束为止。
用Switch-case做级联
但这段代码不符合“单一出口”的原则,因为我们还没有学过字符或字符串数据的处理。
用Switch-case输出英文月份
今后可以用数组做,做的更加漂亮!
思考:“级联的if-else语句”中的分段函数可不可以用switch-case来做?
循环的例子
编程难在哪?难在小问题!细微的地方。例如这里int ret =0 和x>1的选择。
log2x。
#include <stdio.h>
int main()
{
int x;
int ret = 0;
scanf("%d",&x);
int t=x;
while (x>1){
x/=2;
ret ++;
}
printf("log2 of %d is %d.",t,ret);
return 0;
}
计数循环
思考:
- 这个循环需要执行多少次? ———————————— 101次
- 循环停下来的时候,有没有输出最后的0?—————— 有
- 循环结束后,count的值是多少?—————————— -1
- 交换count --; 和 printf("%d\n",count); 结果有没有区别?
算平均数
让用户输入一系列的正整数,最后输入-l表示输入结束,然后程序计算出这些数字的平均数,输出输入的数字的个数和平均数.
变量->算法->流程图->程序.
变量
- 一个记录读到的整数的变量
- 平均数要怎么算?
- 只需要每读到一个数,就把它加到一个累加的变量里,到全部数据读完,再拿它去除读到的数的个数就可以了
- —个变量记录累加的结果,一个变量记录读到的数的个数(++)
算法和流程图
#include <stdio.h>
int main()
{
int number;
int sum = 0;
int count = 0;
scanf ("%d",&number);
while ( number != -1){ #输入-1退出
sum += number;
count ++;
scanf("%d",&number);
}
printf("%f\n",1.0*sum/count);
return 0;
}
猜数游戏——循环
让计算机来想一个数,然后让用户来猜,用户每输入一个数,就告诉它是大了还是小了,直到用户猜中为止,最后还要告诉用户它猜了多少次。
1.计算机随机想一个数,记在变量number里;
2.一个负责计次数的变量count初始化为0;
3.让用户输入一个数字a;
4. count递增(加一);
5.判断a和number的大小关系,如果a大,就输出
“大”;如果a小就输出“小”;
6.如果a和number是不相等的(无论大还是小),程序转回到第3步;(循环条件)
7.否则,程序输出“猜中”和次数,然后结束。
生成100内的随机数
每次召唤rand()就得到一个随机的整数。
#include <stdio.h>
#include <stdlib.h> #为了rand的两句话使用的
#include <time.h> #为了rand的两句话使用的
int main()
{
srand(time(0)); #目的是为了让随机数看上去像随机数的样。
int a = rand(); #这句前需要srand(time(0))
printf("%d\n",a%100); #每次得到100以内的数。
return 0;
}
整数逆序
- 一个整数是由1至多位数字组成的,如何分解出整数的各个位上的数字,然后加以计算
- 对一个整数做%10的操作,就得到它的个位数;
- 对一个整数做/10的操作,就去掉了它的个位数;
- 然后再对2的结果做%10,就得到原来数的十位数了
- 依此类推。
#include <stdio.h>
int main()
{
int x;
scanf("%d",&x);
int digit;
int ret = 0;
while (x>0){
digit = x%10;
printf("%d\n",digit);
ret = ret*10+digit;
printf("x=%d,digit=%d,ret=%d\n",x,digit,ret) ;
x /= 10;
}
printf("%d",ret);
return 0;
}
输出如下:
12345
5
x=12345,digit=5,ret=5
4
x=1234,digit=4,ret=54
3
x=123,digit=3,ret=543
2
x=12,digit=2,ret=5432
1
x=1,digit=1,ret=54321
54321
判断和循环常见的错误
if语句常见的错误
- 忘了大括号
- if“()”后面不能加分号,加分号执行:什么都不做。C的编译器不觉得后面的"{…}"是错误的。
- 错误使用==和=
- 使人困惑的else
- C语言不管缩进和空格的。
代码风格
- 在if和else之后必须加上大括号形成语句块;
- 大括号内的语句缩进一个tab的位置;