如果
if(条件成立){
...
}
eg.
int hour1,minute1;
int hour2,minute2;
scanf("%d %d",&hour1,&minute1);
scanf("%d %d",&hour2,&minute2);
int ih=hour2-hour1;
int im=minute2-minute1;
if(im<0) {
im=60+im;
ih--;
}
printf("时间差是%d小时%d分。\n",ih,im);
条件
if(条件,是一种运算)
- 是计算两个值之间的关系,所以叫做关系运算或比较运算,关系运算符也叫比较运算符
关系(比较)运算的结果只有1或0
- 当两个值的关系符合关系运算符的预期时,关系运算的结果为整数1,否则为整数0
printf("%d\n",5==3);
printf("%d\n",5>3);
printf("%d\n",5<=3);
优先级
- 所有的关系运算符的优先级比算术运算的低,但比赋值运算的高
7>=3+4
int r=a>0; - 判断是否相等的 == 和 != 的优先级比其他的低,而连续的的关系运算是从左到右进行的
5>3 == 6>4
6>5>4
a == b == 6
a==b>0
找零计算器
找零计算器需要用户做两个操作:输入购买的金额,输入支付的票面,而找零计算器则根据用户的输入做出相应的动作:计算并打印找零,或告知用户余额不足以购买。
从计算机程序的角度看,这就是意味着程序需要用户的两个输入,然后进行一些计算和判断,最后输出结果。
//初始化
int price=0;
int bill=0;
//读入金额和票面
printf("请输入金额:") ;
scanf("%d",&price);
printf("请输入票面:") ;
scanf("%d",&bill) ;
//计算找零
printf("应该找您:%d\n",bill-price) ;
注释
- 单行:/ /
- 多行:/ * 要注释的内容* /
延续数行的注释,要用多行注释的格式来写。多行注释由一对字符序列 / * 开始,以 * / 结束,也可以用于一行内的注释
int ak=47 / *36 */ ,y=9
判断票面够不够
//初始化
int price=0;
int bill=0;
//读入金额和票面
printf("请输入金额:") ;
scanf("%d",&price);
printf("请输入票面:") ;
scanf("%d",&bill) ;
//计算找零
if(bill>=price){
printf("应该找您:%d\n",bill-price) ;
}
eg.
const int MINOR=35;
int age=0;
printf("请输入你的年龄:");
scanf("%d",&age) ;
printf("你的年龄是%d岁。\n",age);
if(age<MINOR){
printf("年轻是美好的,");
}
printf("年龄决定了你的精神世界,好好珍惜吧。\n");
不够怎么办?else
else否则的话
int price=0;
int bill=0;
printf("请输入金额:") ;
scanf("%d",&price);
printf("请输入票面:") ;
scanf("%d",&bill) ;
if(bill>=price){
printf("应该找您:%d\n",bill-price) ;
}else{
printf("你的钱不够\n");
}
比较数的大小
int a,b;
printf("请输入两个整数:");
scanf("%d %d",&a,&b);
int max=0;
if(a>b) {
max=a;
}
printf("大的那个是%d\n",max);
这个程序没有解决b大于a的问题,当a>b的条件不成立时,程序就结束了,max没有得到值。
方案一:
并没有解决a=b的情况,同时判断了两次a和b的大小,没必要。方案一pass
int a,b;
printf("请输入两个整数:");
scanf("%d %d",&a,&b);
int max=0;
if(a>b) {
max=a;
}
if(b>a) {
max=b;
}
printf("大的那个是%d\n",max);
方案二:
简单易懂,最套路的做法,最基础的做法,推荐,足够的傻
int a,b;
printf("请输入两个整数:");
scanf("%d %d",&a,&b);
int max=0;
if(a>b) {
max=a;
}else{
max=b;
}
printf("大的那个是%d\n",max);
方案三:
有一点点聪明了
int a,b;
printf("请输入两个整数:");
scanf("%d %d",&a,&b);
int max=b;
if(a>b) {
max=a;
}
printf("大的那个是%d\n",max);
if语句
一个基本的if语句由一个关键字if开头,跟上括号里的一个表示条件的逻辑表达式,然后是一对大括号“{}”之间的若干条语句。如果表示条件的逻辑表达式的结果不是0,那么就执行后面跟着的这对大括号中的语句,否则就跳过这些语句不执行,而继续下面的其他语句。
还有一种形式:
if(total>amount)
total+=amount+10;
if语句这一行结束的时候并没有表示语句结束的“;”,而后面的赋值语句写在if的下一行,并且缩进了,在这一行结束的时候有一个表示语句结束的“;”。这表明这条赋值语句是if语句的一部分,if语句拥有和控制这条赋值语句,决定它是否要被执行。
计算薪水
const double RATE=8.25;
const int STANDARD=40;
double pay=0.0;
int hours;
printf("请输入工作的小时数:");
scanf("%d",&hours) ;
printf("\n");
if(hours>STANDARD)
pay=STANDARD*RATE+(hours-STANDARD) *(RATE*1.5);
else
pay=hours*RATE;
printf("应付工资:%f\n",pay);
判断成绩
const int PASS=60;
int score;
printf("请输入成绩:");
scanf("%d",&score) ;
printf("你输入的成绩是%d.\n",score);
if(score<PASS)
printf("很遗憾,这个成绩没有及格。");
else
printf("祝贺你,这个成绩及格了。");
printf("再见\n") ;
数数几位数
程序要读入一个4位以下(含4位)的正整数,然后输出这个整数的位数。如:输入352,输出3
计算机的方式:判断数的范围来决定它的位数,352属于[100,999],则3位数。
int x;
int n=1;
scanf("%d",&x);
if(x>999){
n=4;
}else if(x>99){
n=3;
}else if(x>9){
n=2;
}
printf("%d\n",n);
因为从高处往下判断,所以不需要判断上限了。用大于号的时候,从高往低判断。
问题:任意范围的正整数怎么办?
所以判断位数这种方法有一定的局限性
换个方式想:数数
int x;
int n=0;
scanf("%d",&x);
n++;
x/=10;
while(x>0){
n++;
x/=10;
}
printf("%d\n",n);
while循环
while(x>0){
循环体
}
- if和while的区别仅仅在于是做一次还是反复多次地做,while反复多次做包括要反复多次判断条件。
- 循环体内要有改变条件的机会,否则就是死循环了。
- 如果我们把while翻译作“当”,那么一个while循环的意思就是:当条件满足时,不断地重复循环体内的语句。
- 循环执行之前判断是否继续循环,所以可能循环一次也没有被执行;条件成立是循环继续的条件。
- 看程序的运行结果
法一:
通过人脑模拟计算机的运行,在纸上列出所有的变量,随着程序的进展不断重新计算变量的值。当程序运行结束时,留在表格最下面的就是程序的最终结果。
Q.上面那个程序可以改成这样吗?
int x;
int n=0;
scanf("%d",&x);
while(x>0){
n++;
x/=10;
}
printf("%d\n",n);
x | n |
---|---|
352 | 0 |
35 | 1 |
3 | 2 |
0 | 3 |
但测试程序不可能就用这一个数352就够了,通常使用边界数据,如有效范围两端的数据、特殊的倍数、个位数、10、0、负数…
试一下10,5,0,发现这个程序数不了0
如果是原来那个程序呢?
int x;
int n=0;
scanf("%d",&x);
n++;
x/=10;
while(x>0){
n++;
x/=10;
}
printf("%d\n",n);
原程序可以数0
或者改成:
int x;
int n=0;
scanf("%d",&x);
if(x>0){
while(x>0){
n++;
x/=10;
}
}else{
n=1;
}
printf("%d\n",n);
法二:
调试:在程序适当的地方插入printf来输出变量的内容
int x;
int n=0;
//scanf("%d",&x);
x=352;
while(x>0){
n++;
x/=10;
printf("x=%d,n=%d\n",x,n);
}
printf("%d\n",n);
数位数的算法
1.用户输入x
2.初始化n为0
3.x=x/10,去掉个位
4.n++
5.如果x>0,回到3
6.否则n就是结果
do-while循环
在进入循环的时候不做检查,而是在执行完一轮循环体的代码之后,再来检查循环的条件是否满足,如果满足则继续下一轮循环,不满足则循环结束。
do{
循环体
}while(循环条件);
要小心()后面要加;
do-while和while圆括号里的条件是一样的,区别在于什么时候判断条件,while要进循环的时候判断,do-while循环出来的时候判断。也就是说,无论条件满不满足,do-while循环至少会执行一次,而while循环可能一次也不执行。
int x;
int n=0;
scanf("%d",&x);
do{
x/=10;
n++;
}while(x>0);
printf("%d\n",n);
for循环
阶乘:
- n!=1×2×3×4×…×n
- 写一个程序,让用户输入n,然后计算输出n!
- 变量:
显然读用户的输入需要一个int的n,然后计算的结果需要用一个变量保存,可以是int的factor,在计算中需要有一个变量不断从1递增到n,那可以是int的i
int n;
scanf("%d",&n);
int fact=1;
int i=1;
while(i<=n){
fact*=i;
i++;
}
printf("%d!=%d\n",n,fact) ;
for(初始条件;循环继续的条件;循环每一轮要做的事情)
int n;
scanf("%d",&n);
int fact=1;
int i=1;
for(i=1;i<=n;i++){
fact*=i;
}
printf("%d!=%d\n",n,fact) ;
for循环像一个计数循环:设定一个计数器,初始化它,然后在计数器到达某值之前,重复执行循环体,而每执行一轮循环,计数器值以一定步进进行调整,比如加1或者减1
for(i=0;i<5;i=i+1){
printf("%d",i);
}
- for=对于
for(count=10;count>0;count–)
读成"对于一开始的count=10,当count>0时,重复做循环体,每一轮循环在做完循环体内语句后,使得count–" - 小套路
做求和的程序时,记录结果的变量应该初始化为0,而做求积的变量时,记录结果的变量应该初始化为1 - 循环控制变量i只在循环里被使用了,在循环外面它没有任何用处。因此,我们可以把变量i的定义写到for语句里面去,但这种写法只有C99能用
int n;
scanf("%d",&n);
int fact=1;
for(int i=1;i<=n;i++){
fact*=i;
}
printf("%d!=%d\n",n,fact) ;
- 1×1还是1,所以程序的循环不需要从1开始,可以改动令i=2
int n;
scanf("%d",&n);
int fact=1;
int i;
for(i=2;i<=n;i++){
fact*=i;
}
printf("%d!=%d\n",n,fact) ;
- 除了可以从1乘到n来计算n!,还可以从n乘到1来计算
int n;
scanf("%d",&n);
int fact=1;
int i=n;
for(;n>1;n--){//对于for循环来说,()里这三个表达式可以拿掉一个的
fact*=i;
}
printf("%d!=%d\n",i,fact) ;
循环次数
for(i=0;i<n;i++)
循环的次数是n,而循环结束以后,i的值是n。循环的控制变量i,是选择从0开始还是从1开始、是判断i<n还是i<=n,对循环的次数、循环结束后变量的值都有影响
int i;
for(i=0;i<5;i++){
printf("i=%d\n",i);
}
printf("\n最后i=%d\n",i) ;
for循环:
for(初始动作;条件;每轮的动作){
}
for中的每个表达式都是可以省略的: for(;条件;)== while(条件)
- 三种循环的选取:
如果有固定次数,用for
如果必须执行一次,用do-while
其他情况用while
逻辑类型 bool
#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;
}
逻辑运算
-
如果要表达数学中的区间,如: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结合在一起,age是0,则!age是1,age不是0,则!age是0,然后再和20作比较,因为!age结果不是0就是1,跟20比较一定比20小,所以这个式子永远都等于1。
优先级
for(i=a;i<=a+3;i++){
for(j=a;j<=a+3;j++){
for(k=a;k<=a+3;k++){
if(i!=j){
if(i!=k){
if(j!=k){
cnt++;
printf("%d%d%d",i,j,k) ;
if(cnt==6){
printf("\n");
cnt=0;
}else{
printf(" ");
}
}
}
}
}
}
}
for(i=a;i<=a+3;i++){
for(j=a;j<=a+3;j++){
for(k=a;k<=a+3;k++){
if(i!=j&&i!=k&&j!=k){
cnt++;
printf("%d%d%d",i,j,k) ;
if(cnt==6){
printf("\n");
cnt=0;
}else{
printf(" ");
}
}
}
}
}
不要把赋值,包括复合赋值组合进表达式!
条件运算符
- count=(count>20)?count-10:count+10;
count=条件?条件满足时的值:条件不满足时的值;
if(count>20)
count=count-10;
else
count=count+10;
我们不希望你使用嵌套的条件表达式,太复杂了
逗号运算
逗号在C语言里是一个运算符,它用来连接两个表达式,并以其右边表达式的值作为它的结果。逗号的优先级是左右运算符中最低的,所以它两边的表达式会先计算;逗号的组合关系是自左向右,所以左边的表达式会先计算,而右边的表达式的值就留下来作为逗号运算的结果。
int i;
i=3+4,5+6;
printf("%d\n",i);
输出7
int i;
i=(3+4,5+6);
printf("%d\n",i);
输出11
- 逗号表达式主要在for中使用
for(i=0,j=10;i<j;i++,j–)
找三个数中最大
嵌套的判断
当if的条件满足或不满足的时候要执行的语句也可以是一条if或if-else语句,这就是嵌套的if语句
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");
else的匹配
- else总是和最近的那个if匹配
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");
但是如果有大括号,else是与第一个if code匹配的
缩进
缩进格式不能暗示else的匹配
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");
这个else还是if count的
tips:在if或else后面总是加上{},作为我们的良好编程习惯,即使只有一条语句的时候。
分段函数
级联的if-else if
if(exp 1)
st 1;
else if(exp 2)
st 2;
else
st 3;
推荐左边的写法:单一出口
switch-case
int type;
scanf("%d",&type);
switch(type){
case 1:
printf("您好");
break;
case 2:
printf("早上好") ;
break;
case 3:
printf("晚上好");
break;
case 4:
printf("再见") ;
break;
default:
printf("啊,什么啊?");
break;
}
switch(控制表达式){
case 常量:
语句
...
case 常量:
语句
...
default:
语句
...
}
- 控制表达式只能是整数型int的结果,上面那个type必须是int型的
- 常量可以是常数,也可以是常数计算的表达式
const int MRN=1;//只有C99可以有这种写法
int type;
scanf("%d",&type);
switch(type){
case MRN:
printf("您好");
break;
case 1+1:
printf("早上好") ;
break;
case 3:
printf("晚上好");
break;
case 4:
printf("再见") ;
break;
default:
printf("啊,什么啊?");
break;
}
- switch语句可以看作是一种基于计算的跳转,计算控制表达式的值后,程序会跳转到相匹配的case(分支标号)处。分支标号只是说明switch内部位置的路标,在执行完分支中的最后一条语句后,如果后面没有break,就会顺序执行到下面的case里去,直到遇到一个break,或者switch结束为止。一般会给每一个case配一个break。
switch(type){
case 1:
case 2:
printf("早上好\n") ;
break;
case 3:
printf("晚上好\n");
case 4:
printf("再见\n") ;
break;
default:
printf("啊,什么啊?\n");
break;
}
例题.
//printf("输入成绩(0-100)");
int grade;
scanf("%d",&grade) ;
grade/=10;
switch(grade){
case 10:
case 9:
printf("A\n");
break;
case 8:
printf("B\n");
break;
case 7:
printf("C\n");
break;
case 6:
printf("D\n");
break;
default:
printf("F\n");
break;
}
这段代码不符合单一出口原则,因为我们还没学过字符或字符串数据的处理。