C语言——3-分支结构
C语言语句(指令) : 就是表达程序员某种操作或某种意图的指令.
-
简单语句
单语句 : 约定以 ; 号结束
如 ;
表达式 + ; ==> 单语句
a = 5
赋值表达式
a = 5 ;
赋值语句
3 + 5
加法表达式
3 + 5 ;
加法语句
;
空语句
.... -
复合语句
{} 语句块
{
//接0个或多个语句(单语句或者复合语句)
}
if 语句
switch 语句
while 语句
do while 语句
for 语句
return 语句
.....
C程序的主题是由函数组成,函数内部都是C语句组成
2 C程序设计结构
-
顺序结构
a = 5;
b = 3 + 5;
-
分支结构(选择结构)
if 语句
switch 语句
-
循环结构
while 语句
do while 语句
for 语句
3 if 语句
if语句程序员的某种意图 ? B
A 判断 B 选择
if语句表达程序员的某种操作
if 如果 ,假如 ..
如 :
我的择偶标准!!!
假如 是女的
去追求
if(女的)
去追求
if(按一个条件)
满足条件要执行操作
if语句有三种基本形式
-
(1) if的第一种形式
if(表达式)
语句
//如果 "表达式的值"为真(非0,条件成立),则执行"语句"
表达式 : 任何的C语言的合法的表达式,合法的表达式都有值
"某个条件"
语句 : 满足条件要执行的语句(操作)
单语句 : 只有一个 ; 的语句
复合语句 : {}/if/swith/while/for....
例子 :
if(a = 5)
b = 6;
if(a = 5;) //error if()括号内必须为一个表达式,不能为语句
b = 6;
if(1,2,3,4,0) //可以,逗号表达式也是表达是
a = 5;//if只能管到这里
b = 6;//这条语句,if管不到!!!
编程建议 :
不管if后面有没有语句 ,先打一对{}确定范围, 确定if的"管辖范围"
if()
{
}
-
if的第二种形式
仍然以我的择偶标准为例
假如 是女的
去追求
否则
做哥们
if(条件)
语句1
else
语句2
假如 "条件成立" ,则执行"语句1"
否则 "条件不成立" ,则执行"语句2"
条件 : 任何的C语言的合法的表达式,合法的表达式都有值
"某个条件"
语句 : 满足条件要执行的语句(操作)
单语句 : 只有一个 ; 的语句
复合语句 : {}/if/swith/while/for....if(a > b) a = 3; b = 4; else a = 250; /* 3.c: In function ‘main’: 3.c:9:5: error: ‘else’ without a previous ‘if’ else ^~~~ */编程建议 :
不管if,else后面有没有语句,都先大一对{},确定if/else的"管辖范围"
if() { } else { } -
if的第三种形式
if(条件1) 语句1 else if(条件2) 语句2 else if(条件3) 语句3 .... else if(条件m) 语句m else 语句n==>
if(条件1) 语句1 else { if(条件2) 语句2 else { if(条件3) 语句3 ... else { if(条件m) 语句m else 语句n } } }练习 :
请根据如下的代码,试写出number 和 cost 之间的数学关系表达式
if(number > 500) cost = 0.15; else if (number > 300) cost = 0.10; else if(number > 100) cost = 0.075; else if(number > 50) cost = 0.05; else cost = 0;==else 匹配问题==
原则 :
else总是与上面的,最近的,同级的,未配对的if语句配对
if(xxx) { if() { 语句1 } else { 语句2 } } else { if() { 语句3 } else { 语句 } }
4 if/else 程序练习
(1) scanf 和 printf 简单介绍
scanf : 从标准输入设备(如 : 键盘) 获取你想要的数据对象
printf: 格式化输出
scanf("格式化输入",地址列表);
格式化输入: 告诉用户 你 必须按照我的格式要求去输入 "字符串"
普通字符 : 用户得原模原样输入,否则就会失败
特殊字符 :
%d : 输入一个十进制的整数字符串 [0-9]+
%c : 输入一个字符
%f %lf 输入一个十进制的浮点型的字符串
%s : 输入任意一个字符串
如 :
scanf("%d%d",&a,&b);
123 456 OK
scanf("%c%c",&a,&b);
1 2 ok a = '1' b = '2'
12 ok a = '1' b = '2'
scanf("a=%d, b=%d\n",&a,&b);
a=123, b=123\n , 只会把123存放到a的地址中
why ?
scanf 会自动把输入的空白符(如 : \r \n)自动过滤掉!!!
(2) 写一段代码 ,完成如下功能 :
从键盘中输入一个字符,要求
如果输入的大写字母,则把他转换成相应的小写字母,然后再输出
如果输入的小写字母,则把他转换成相应的大写字母,然后再输出
其他字符,则不变,直接输出.
//1.定义一个变量, 接收键盘输入 char c; scanf("%c",&c); //2.根据要求转换 if(c >= 'A' && c =< 'Z') { c += ('a' - 'A'); //c = c + ('a' - 'A'); } else if(c >= 'a' && c <= 'z') { c += ('A' - 'a'); } //3.输出 printf("%c\n",c);
(3) 从键盘上输入三个整数 a , b , c,按从小到大的顺序, 输出他们
int a,b,c; scanf("%d%d%d",&a,&b,&c); if(a <= b) { if(a <= c) //a最小 { if(b <= c) //a < b < c { } else //a < c < b { } } else //c最小 c < a < b { } } else //b < c { }//1.输入三个整数 int a,b,c; scanf("%d%d%d",&a,&b,&c); //2.想办法, a <= b <= c //2.1 想办法 a < b if(a > b) { //交换 temp = a; a = b; b = temp; } //2.2 想办法 a < c if(a > c) { //交换a c } //上面两个if做完后,a是最小的 if(b > c) { //交换b c } 上面三个if做完后,a < b < c //3.依次输出 a,b,c printf("%d->%d->%d",a,b,c);
5 if总结
(1) if 语句的三种形式
<1>
if(条件) "条件" 表达式
{
}
<2>
if(条件)
{
}
else //否则,否定上面的与else配对if的条件
{
}
<3>
if(条件1)
{
}
else if(条件2)
{
}
else if(条件3)
...
else
{
}
(2) 并列条件 和 互斥条件
"并列条件"
if(条件1)
{
语句1
}
if(条件2)
{
语句2
}
//...
"互斥条件"
if(条件1)
{
语句1
}
else if(条件2)
{
}
//....
(3) if语句嵌套
"条件里面分条件" : 在if语句或else语句后面, 又包含一个或多个if语句,称之为if语句的嵌套
if(xxx) if() 语句1 else 语句2 else if() 语句3 else 语句4分析关键 : else匹配问题
原则 :
==else总是与他上面的,最近的,统计的,未配对的if语句配对==
==>
if(xxx) { if() { 语句1 } else { 语句2 } } else { if() { 语句3 } else { 语句4 } }
6 switch语句
0.一个练习
从键盘输入一个十六进制的字符('0' - '9' 'a' - 'f' 'A' - 'F'),输出其相应的数值.
char ch;//输入六进制字符 int d;//输入的十六进制对应的数值 scanf("%c",&ch); if(ch == '0') { d = 0; } else if(ch == '1') { d = 1; } //... else if(ch == 'a' || ch == 'A') { } printf("%c->%d\n",ch,d);上面的这个例子, 好像是列举 "十六进制的所有字符"
#include <stdio.h> int main() { char ch;//输入十六进制字符 int d;//输入的十六进制字符对应的数值 scanf("%c",&ch); switch(ch) { case '0': d = 0; break; case '1': d = 1; break; case '2': d = 2; break; case '3': d = 3; break; case '4': d = 4; break; case '5': d = 5; break; case '6': d = 6; break; case '7': d = 7; break; case '8': d = 8; break; case '9': d = 9; break; case 'a': case 'A': d = 10; break; case 'b': case 'B': d = 11; break; case 'c': case 'C': d = 12; break; case 'd': case 'D': d = 13; break; case 'e': case 'E': d = 14; break; case 'f': case 'F': d = 15; break; } printf("%d\n",d); return 0; }
switch语句
switch是用来列举所有的情况
1 switch 语法形式
switch(待列举的表达式) { case 值1: 语句1 case 值2: 语句2 case 值3: 语句3 ... //default : //其他情况 // 语句n }switch 是用来"列举" ("待列举的表达式")的所有的值的情况.
swith语句 让 "待列举的表达式" 的值 和 case后面的 "值"作匹配.
一旦匹配成功(值相等) ,则从那个 case 后面执行,一直往下执行,
直到遇到break或 switch 结束为止.
如果所有的case 都没有匹配成功,则匹配 default.
#include <stdio.h> int main() { char ch; scanf("%c",&ch); switch(ch) { case '0': printf("0\n"); // break; default: printf("other\n"); // break; case '1': printf("1\n"); // break; // default: // printf("other\n"); } return 0; }
2 关于switch
<1> switch后面的那个 "带列举的表达式" 以及 case 后面的 "值",都必须为一个整数类型.
因为只有整数,才可以"列举"
switch后面 "带列举的表达式" : 可以是一个整数类型的表达式 或 变量.
case 后面的 "值" : 必须是一个整型的常量 或 常量表达式,
并且各个case 后面的值不能相同(唯一).
int m,n; scanf("%d%d",&m,&n); switch(m + 1) { case n : //error n不是常量, case 后面的值,必须为一个常量或常量表达式 语句1 case 1 ://可以的 .. case 1*3 + 7://可以的 ... case 10 ://不可以的, 与上面的 case 值相同,不行的 ... }
<2> 各个case 和 default 出现的次序不影响匹配的结果
switch(m)
{
default : //default 可以在switch任何位置,也可以不要他
//有default 永远是所有的case都不匹配的情况下,再匹配到default.
...
case 1 :
...
case 2 :
...
case 100 :
...
case 10 :
...
}
<3> case后面的"语句" 可以省略,意识是,多个case可以共用一组语句
switch(m)
{
case 1 :
case 2 :
语句
case 3:
语句
default :
语句
}
<4> case 后面的 "语句" 可以是单语句/复合语句
<5> switch中的break语句,用来跳出他(break)所属的switch
练习 :
(1) 从键盘输入一个十六进制的字符('0' - '9' 'a' - 'f' 'A' - 'F'),输出其相应的数值.用switch语句完成
(2) 从键盘上输入一个成绩(int) , 把这成绩相应的等级输出.
'A' : [90,100]
'B' : [80,90)
'C' : [70,80)
'D' : [60,70)
'E' : [0,60)
int score; char grade; scanf("%d",&score); switch(score/10) { case 10: case 9: grade = 'A'; break; case 8 : grade = 'B'; break; //... }
(3) 输入一个日期(y,m,d) ,求该日期至当年末还有多少天?
int y,m,d;
int days = 0;//保存该日期当年末的天数
scanf("%d%d%d",&y,&m,&d);
//1.求整月的天数
switch(m + 1)
{
case 2 :
if(y是闰年)
days += 29;
else
days += 28;
case 3 :
days += 31;
case 4 :
days += 30;
...
}
//2.求当前月剩余的天数
if(m=1,3,5,7,8,10,12)
{
days += 31 - d;
}
else if( m == 2)
{
if(闰年)
...
else
...
}
else
{
}
作业 :
(1) 输入一个日期(y,m,d) ,求该日期至当年末还有多少天?
(2) 输入一个日期(y,m,d) ,求该日期至当年初还有多少天?
(3) 写个C程序,完成如下功能要求 :
企业发放的奖金根据企业的当年利润决定。 当利润I低于或等于100000元时,奖金可提成10%; 利润大于100000元,小于200000元(100000<I≤200000)时, 低于100000元的部分按10%提成,高于100000元的部分,可提成7.5%; 利润大于200000元,小于400000元(200000<I≤400000)时, 低于200000元的部分仍按上述办法提成(下同),高于200000元的部分按5%提成。 利润大于400000元,小于600000元(400000<I≤600000)时, 高于400000元的部分按3%提成。 利润大于600000元,小于1000000元(600000<I≤1000000)时, 高于600000的部分按1.5%提成; 利润大于1000000元(I>1000000)时, 超过1000000元的部分按1%提成。 从键盘输入当年利润I,求应发放奖金P总数。
要求 : 用if语句 和 switch 两种方法完成这个题目.
double I;//利润 double P = 0;//奖金 switch((long)I/100000) { }//计算到年末的天数#include <stdio.h>// 判断是否为闰年int Leap(int year){if ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0){return 1;}return 0;}// 获取某个月份的天数int getDay(int year, int month){switch (month) {case 1: // 1月case 3: // 3月case 5: // 5月case 7: // 7月case 8: // 8月case 10: // 10月case 12: // 12月return 31;//返回31天case 4: // 4月case 6: // 6月case 9: // 9月case 11: // 11月return 30;//返回30天case 2: // 2月return Leap(year) ? 29 : 28;//如果是闰年,返回29,否则返回28default:return -1; // 非法的月份}}// 计算日期到当年末还有多少天int Num(int year, int month, int day){int Day = 0;for (int m = month + 1; m <= 12; m++)// 循环累加每个月的天数{Day += getDay(year, m);}Day += getDay(year, month) - day; // 加上当月剩余的天数return Day;}int main() {int year, month, day;printf("请输入日期(格式:年 月 日):\n");scanf("%d %d %d", &year, &month, &day);int days = Num(year, month, day);printf("距离当年末还有 %d 天\n", days);return 0;}//计算到年初的天数#include <stdio.h>// 判断是否为闰年int Leap(int year){if ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0){return 1;}return 0;}// 获取某个月份的天数int getDay(int year, int month){switch (month) {case 1: // 1月case 3: // 3月case 5: // 5月case 7: // 7月case 8: // 8月case 10: // 10月case 12: // 12月return 31;//返回31天case 4: // 4月case 6: // 6月case 9: // 9月case 11: // 11月return 30;//返回30天case 2: // 2月return Leap(year) ? 29 : 28;//如果是闰年,返回29,否则返回28default:return -1; // 非法的月份}}// 计算日期到当年初还有多少天int Num(int year, int month, int day){int Day = 0;for (int m = 1; m < month; m++) // 循环累加每个月的天数{Day += getDay(year, m);}Day += day;// 加上当月的天数return Day;}
int main(){int year, month, day;printf("请输入日期(格式:年 月 日):\n");scanf("%d %d %d", &year, &month, &day);int days = Num(year, month, day);printf("距离当年初还有 %d 天\n", days);return 0;}#include<stdio.h>int main(){double i,p=0;printf("请输入年利润:\n");scanf("%lf",&i);if(i<0){printf("没得奖金\n");}else{switch((long)i/100000){case 0:p=i*0.1;break;case 1:p=100000*0.1+(i-100000)*0.075;break;case 2:case 3:p=100000*0.1+100000*0.075+(i-200000)*0.05;break;case 4:case 5:p=100000*0.1+100000*0.075+200000*0.05+(i-400000)*0.03;break;case 6:case 7:case 8:case 9:p=100000*0.1+100000*0.075+200000*0.05+200000*0.03+(i-600000)*0.015;break;default:p=100000*0.1+100000*0.075+200000*0.05+200000*0.03+200000*0.015+(i-1000000)*0.01;}}printf("应发奖金%lf元\n",p);return 0;}
浙公网安备 33010602011771号