第3章 逻 辑 处 理
3.1 关系运算符和关系表达式
3.1.1 关系运算符
关系运算符均为双目运算符,共有以下6种:
> 大于
< 小于
>= 大于等于
<= 小于等于
!= 不等于
== 等于
关系运算符要求两个操作数是同一种数据类型,其结果为一逻辑值,即关系成立时,其值为“真”(true),用非0值表示;关系不成立时,其值为“假”(false),用0表示。
关系运算符的优先级低于算术运算符,关系运算符==和!=低于前4种运算符,并且结合方向均为自左向右。
3.1.2 关系表达式
由关系运算符将两个表达式连接起来的有意义的式子称为关系表达式。运算对象可以是常量或变量,也可以是表达式。例如:
例如:a+b<c+d
先进行a+b和c+d两个算术表达式的运算,得到两个值后再进行比较,从而求出关系表达式的值。
关系表达式的值是一个逻辑值,即“真”或“假”, 其值为0或非0。
注意:在C语言中,常用1表示“真”,用0表示“假”。
例如:当x>y为“真”时,其表达式的值为1;当x>y为“假”时,其表达式的值为0。
可以将关系表达式的运算结果(0或1)赋给一个整型变量或字符型变量。
【例3.1】 关系运算示例。
main()
{ int a=4,b=1,c; 3>2 a+b>100 x==y a%b!=0
printf("%d",c=a>b); printf("%d",c=a<b); }
/*输出值为1*/ /*输出值为0*/
3.2 逻辑运算符和逻辑表达式
3.2.1 逻辑运算符
C语言提供了以下3种逻辑运算符: && 逻辑与运算符 || 逻辑或运算符 ! 逻辑非运算符
其中“&&”和“||”为双目运算符,并为右结合方向;“!”为单目运算符,仅对其右边的对象进行逻辑求反运算。逻辑运算的操作对象为0或非0的整数值,其运算规则如表3.1所示。
表3.1 逻辑运算规则
数据A T T F F
数据B T F T F
A&&B T F F F
A||B T T T F
!A F F T T
!B F T F T
3.2.2 逻辑表达式
由逻辑运算符和其操作对象组成的表达式称为逻辑表达式。 【例3.2】 计算表达式5>3&&'a'||5<4–!0的值。 求解过程为:
(1)逻辑运算!0的结果为1(得表达式5>3&&'a'||5<4–1)。 (2)算术运算4–1的结果为3(得表达式5>3&&'a'||5<3)。 (3)关系运算5>3的结果为1(得表达式1&&'a'||5<3)。 (4)关系运算5<3的结果为0(得表达式1&&'a'||0)。 (5)逻辑运算1&&'a'的结果为1(得表达式1||0)。 (6)逻辑运算1||0的结果为1,即整个表达式的结果为1。
注意:在逻辑表达式的求解过程中,并不是所有的逻辑运算都被执行,只有在必须执行下一个逻辑运算才能求出表达式的值时,才执行该运算。
由于a>b的值为0,使m=0,而n=c>d没有被执行,因此n的值不是0,仍保持原值1。
a&&b&&c 该表达式只有a的值为真时才判断b的值,只有a&&b的值为真时才判断c 的值。若a的值为假,整个表达式的值肯定为假,就不再往下判断b和c;若a的值为真,b的值为假,整个表达式的值肯定为假,就不再往下判断c。 3.3 语句和复合语句
在C语言中,一个表达式的后面跟随一个分号就构成了语句,也称表达式语句,如:x=x+a;。
分号“;”是语句的终结符,而不是语句的分隔符,即分号是语句的最末组成部分。
除了表达式语句外,C语言还有复合语句、流程控制语句、函数返回语句及空语句等。
复合语句是由左右花括号括起来的语句,其一般形式为:
一个复合语句在语法上等同于一个语句,在程序中,凡是单个语句能够出现的地方,都可以出现复合语句。一个复合语句又可以出现在其他复合语句内部。
复合语句是以右花括号为结束标志的,因此,在复合语句的后面必须有一个分号,此分号是语句的终结符。 {说明部分; 语句部分}
3.4 分 支 结 构
3.4.1 if语句
if语句有以下3种格式:单分支格式、双分支格式、多分支格式。
目前,在国内的大学中,为了教学管理的需要,将课程分为3类:选修课、考查课和考试课。对于选修课,记录在学生档案中的总评成绩只有“及格”一档,成绩不及格不做记录;对于考查课,记录在学生档案中的总评成绩分为“及格”、“不及格”两档;对于考试课,记录在学生档案中总评成绩分为“优”、“良”、“中”、“及格”和“不及格”(或者直接记录百分制的分数)。
在实际工作中,一般要根据学生的平时成绩、实验成绩和考试成绩等计算出来一个百分制的成绩,然后再按照规则将其转换成登记在学生档案中的总评成绩。如何将百分制的成绩转换成总评成绩,就是我们提出的问题。
对于选修课,只要百分制成绩大于等于60分,就可以得到“及格”的总评成绩。
1.单分支格式
【例3.4】 编写程序,输入一个选修课成绩的分数,输出应登记到学生档案中的总评
成绩。
main()
{ int score; /*定义整型变量记录分数*/
printf("n Please enter score (0<=score .&&.score<=100)");
scanf("%d",&score); /*接收分数*/
if (score>=60) /*判断分数是否大于等于60*/
printf("Passed!n"); /*如果是,则输出"及格"*/
}
本例使用的是if语句的单分支格式,其一般形式为:
执行过程:先计算if后面的表达式,若结果为真(非0),执行
后面的语句;若结果为假(0),不执行该语句。其流程图如图3.1
所示。 if(表达式) 语句;
2.双分支格式 图 3.1 对于考查课,如果百分制成绩大于等于60分,则总评成绩为
“及格”,否则,总评成绩为“不及格”。
【例 3.5】 输入一个考查课的分数,输出其登记到学生档案中的总评成绩,编写相应程序。
main()
{ int score; /*定义整型变量记录分数*/
printf("n Please enter score (0<=score .&&.score<=100)");
scanf("%d",&score); /*接收分数*/
if (score>=60) /*判断分数是否大于等于60*/
printf("Passed!n"); /*如果是,则输出“及格”*/
else
printf("Failed!n"); /*否则输出“不及格”*/
本例使用的是双分支格式,一般形式为:
if(表达式)
语句1;
else
语句2; }
执行过程:先计算if后面的表达式,若结果为真(非0),
则执行语句1;否则执行语句2。其流程图如图3.2所示。 图 3.2
;如果分数小于90分,但是大于等于80分,总评成绩为“良”;如果分分,但是大于等于90分,总评成绩为“优”。当然,实际工作中,考试课
【例 3.6】 输入一科考试的分数,输出其登记到学生档案中的总评成绩,编写相应 程序。
main()
{ int score; /*定义整型变量记录分数*/
printf("n Please enter score (0<=score .&&.score<=100)");
scanf("%d",&score); /*接收分数*/
if (score<60)
printf("Failedn"); /*分数小于60分输出“不及格”*/ else if(score<70)
printf("Passedn"); /*分数小于70分输出“及格”*/
else if(score<80) printf("Middlingn"); /*分数小于80分输出“中”*/ else if(score<90) printf("Finen"); /*分数小于90分输出“良”*/
else
printf("Excellentn"); /*分数小于等于100分输出“优”*/
本例选用的是多分支格式,其一般形式为:
if(表达式1) 语句1
else if(表达式2) 语句2
else if(表达式3) 语句3
…
else if(表达式n) 语句 n
else 语句 m }
执行过程:先计算表达式1,若表达式1的结果为真(非0),执行语句1,否则计算表达式2,若表达式2的结果为真(非0),执行语句2,依次类推,若n个表达式的结果都为假(0),则执行语句m。其流程图如图3.3所示。
图 3.3
由执行过程可知,n+1个语句只有一个被执行,若n个表达式的值都为假,则执行语句m,否则执行第一个表达式值为真(非0)的后面的语句。
4.嵌套的if格式
【例3.7】 修改例3.5,输入一个考查课的分数,输出其登记到学生档案中的总评成绩。
main()
{ int score; /*定义整型变量记录分数*/
printf("n Please enter score (0<=score .&&.score<=100)");
scanf("%d",&score); /*接收分数*/
if (score>=0&&score<=100) /*判断分数是在0~100之间*/
if(score>=60) /*判断分数是否大于60*/
printf("Passed!n"); /*如果是,则输出“及格”*/
} else printf("Failed!n"); /*否则输出“不及格” */ else printf("n Error Score"); /*提示用户分数输入有误*/
本例是在if„else形式中嵌套了if„else形式。
if语句可以嵌套,即在一个if语句中又可以包含一个或多个if语句,一般形式为:
if(表达式1)
if(表达式2) 语句1 else 语句2
else
语句
C语言提供了专门用于处理多分支情况的语句——switch语句,使用该语句编写程序可使程序的结构更加清晰,增强可读性。
【例3.8】 假设某高速公路的一个收费站的收费标准为:小型车15元/车次、中型车35元/车次、大型车50元/车次、重型车70元/车次。编写程序,首先在屏幕上显示一个表如下:
1——小型车
2——中型车
3——大型车
4——重型车
然后请用户选择车型,根据用户的选择输出应交的费用。
/*高速公路收费*/
main()
{ int x;
printf("n 1----小型车");
printf("n 2----中型车");
printf("n 3----大型车"); printf("n 4----重型车"); printf("n 请选择车型:"); scanf("%d",&x); switch (x) { case 1: printf("费用是%d元n",15);break; case 2: printf("费用是%d元n",35);break; case 3: printf("费用是%d元n",50);break; case 4: printf("费用是%d元n",70);break; default: printf("输入错误!"); /*如果x 等于1*/ /*如果x 等于2*/ /*如果x 等于3*/ /*如果x 等于4*/ /*否则,提示输入有误*/ }
}
switch语句的一般形式为:
switch (表达式)
{ case 常量表达式1:语句1 [break;]
case 常量表达式2:语句2 [break;]
…
case 常量表达式n:语句n [break;]
default:语句n+1; [break;]
}
说明:
① switch后面的圆括号后不能加分号。
② switch后面圆括号内表达式的值必须为整型、字符型或枚举型。
③ 各case后面常量表达式的值必须为整型、字符型或枚举型。
④ 各case后面常量表达式的值必须互不相同。
⑤ 若每个case和default后面的语句都以break语句结束,则各个case和default的位置可以互换。
⑥ case后面的语句可以是任何语句,也可以为空,但default的后面不能为空。若为复合语句,则花括号可以省略。
⑦ 若某个case后面的常量表达式的值与switch后面圆括号内表达式的值相等,就执行该case后面的语句,执行完后若没有遇到break语句,则不再进行判断,接着执行下一个case后面的语句。若想执行完某一语句后退出,必须在语句最后加上break语句。
⑧ 多个case可以共用一组语句。
⑨ switch-case语句可以嵌套,即一个switch-case语句中又含有switch-case语句。 从语法上看,任何一个switch语句表示的多分支结构都可以用else if形式来替代,但是,并不是所有的用else if形式表示的程序段都能用switch语句来替代。switch语句对条件的写法要求更苛刻。紧跟着switch后面的表达式的数据类型应为整型或字符型,它与case
switch后面的常量表达式的数据类型必须一致,并且常量表达式中不能包含变量。实际上,
语句的重点就在于如何设计switch后面的表达式,并让它的值正好能够匹配n个常量表达式的值。
3.4.3 条件运算符
C语言中提供的唯一的三目运算符就是条件运算符“?”,它的运算对象有3个。条件运算符的语法格式:
条件运算符是一种特殊的运算符,由条件运算符与操作数构成的表达式也可以称为条件表达式。
包括了条件运算符的表达式的计算方法是首先计算表达式1的值;若表达式1为真,条件表达式的解取表达式2的值;若表达式1为假,整个表达式的解取表达式3的值。
例如:
实际上,“c=a>b?a:b”语句是将a和b两个数中较大的数存入c中,它与下面的if语句是等价的。
if (a>b)
a=2;b=3; c=a>b?a:b; 表达式1?表达式2:表达式3
用条件运算符求3个整数中的最大数。 3个整数中的最大数 */
/*定义变量*/ /*提示用户输入3个整数*/ /*接收用户输入3个整数*/ printf("n Please input three int:"); scanf("%d%d%d",&a,&b,&c);
条件运算符优先级低于逻辑运算符,高于赋值和逗号运算符。 printf("Max is %dn",(a>b?a:b)>c?(a>b?a:b):c); /*输出最大的数*/ }
3.5 循 环 结 构
计算机的优势就在于它可以不厌其烦地重复工作,而且还不出错(只要程序编写正确)。其实,表示循环结构语句的语法并不难掌握,关键是如何使用循环程序设计的思想去解决实际问题。
首先,提出两个实际问题:
第一个问题是在屏幕上输出整数1~20,每两个整数中间空一个格。
第二个问题是计算1+2+3+„+n,n由用户指定(在程序运行是输入)。
也许,有的读者会这样来解决第一个问题:
main()
{ printf("1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20n");
毫无疑问,这个程序的语法是对的,它能够顺利地通过编译,也能够完成题目的要求,但是,这绝对不是一个好的程序,因为程序设计者没有掌握程序设计思想。如果题目是要求输出1~2000,那又如何呢?对循环程序设计来说,首先要掌握的是思想,而不是语法,只要是重复的工作,就要想办法用循环语句实现。这个问题的解决思路应该是从输出1开始,每次输出一个比前一次大1的整数,重复20次。哪怕是只重复10次,或者5次,都是“重复”。重复就要用循环结构。
循环语句有3种:while、do while、for。用goto语句和if语句也能构成循环。 }
3.5.1 while语句
while语句的一般形式为:
while(表达式)
其中,表达式可以是任意类型,一般为关系表达式或逻辑表达式,
其值为循环条件。循环体可以是任何语句。
while语句的执行过程如下。
循环体
图 3.4
(1)计算while后面圆括号中表达式的值,若其结果为非0,转2;否则转3。 (2)执行循环体,转1。
(3)退出循环,执行循环体下面的语句。 其流程图如图3.4所示。
while语句的特点:先判断表达式,后执行循环体。
解决第一个问题的关键是使用循环变量i,从1~20,循环刚好进行20次。i的初值是1,当i小于等于20时,循环做两件事,输出i和i增1。由于每次循环都使i增1,因此i的值会越来越大,当i的值增加到21时,循环条件i<=20 不成立,循环结束。在这个循环当中,重复的次数是用存储单元i记录的,这个存储单元就称为循环计数器,在循环结构中又称循环变量。
【例3.10】 用while语句解决“在屏幕上输出1~20”的问题。
main() { int i; }
{ }
printf("n");
i=1;
while (i<=20) printf("%d ",i); i++;
/*定义变量i*/ /*设i的初值为1*/
/*i小于等于20时,进行循环*/ /*输出当前i的值*/ /*i 的内容增1*/
第二个问题的解决则必须使用循环结构,不能使用顺序结构,因为在程序执行之前,并不知道n是多少,所以不能写出类似于这样的程序:
main()
{ printf("%dn",1+2+3+„+n);
这个程序的设计者也没有掌握循环程序设计思想,并且该程序并不能解决1+2+3+„+ n的问题。试问不知道n的具体值(是由用户输入的),如何将其罗列出来呢?
解决这个问题的基本思路是使用一个初值为0的存储单元(这个存储单元叫做累加器),从加1开始,每次加一个比前一次大1的整数,重复n次。
循环体的工作包括:将i的值累加到sum(累加器)中,并将循环变量i的值增1。在循环前,要赋给累加器和循环变量正确的初值。
【例3.11】 用while语句解决“1+2+3+„+n”的问题。
main()
{ int i,sum,n;
/*定义变量*/ }
/*累加*/ /*i的内容增1*/ /*输出结果*/
}
说明:
① 由于while语句是先判断表达式,后执行循环体,所以循环体有可能一次也不执行。
② 循环体可以是任何语句。如果循环体不是空语句,不能在while后面的圆括号后加分号(;)。
③ 在循环体中要有使循环趋于结束的语句。
3.5.2 do-while语句
do-while语句的一般形式为:
其中,表达式可以是任意类型,一般为关系表达式或逻辑表达式,其值为循环条件。循环体可以是任意语句。
do-while语句的执行过程为:
(1)执行循环体,转2。 (2)计算while后面圆括号中表达式的值,若其结果为非0,转1;否则转3。
(3)退出循环,执行循环体下面的语句。
其流程图如图3.5所示。
do-while语句的特点:先执行循环体,后判断表达式。
说明: 图 3.5 ① do-while语句最后的分号(;)不可少,否则将出现语法错误。 ② 循环体中要有使循环趋于结束的语句。
③ 由于do-while语句是先执行循环体,后判断表达式,所以循环体至少执行一次。 【例3.12】 用while语句解决“1+2+3+„+n”的问题。
main()
{ int i,sum,n; i=1; sum=0;
/*定义变量*/ /*赋初值*/
/*提示用户输入一个整数*/ /*接受用户输入一个整数*/ /*循环体开始*/ /*累加*/
/*i的内容增1*/
do
循环体while(表达式);
printf("n Please input a integer:"); scanf("%d",&n); do
{
sum=sum+i; i++;
}while(i<=n);
printf("sum=%dn",sum);
/*输出结果*/
运行情况一:
Please inupt a integer: 10 55
}
运行情况二:
从运行情况看,当用户的输入为55时,程序的运行结果是正确的;当用户的输入为0时,程序的运行结果是错误的。而使用while语句编写程序时,输入0是不会出错的。为什么呢?这是因为do-while语句是先执行循环体,再判断循环表达式。所以,不论n 的值是0还是其他的数值,循环体必然被执行一遍。请读者自己修改程序。
Please input a integer: 0 1
3.5.3 for语句
for语句的一般形式为:
其中,循环体可以是任意语句。3个表达式可以是任意类型,一般来说,表达式1用于给某些变量赋初值,表达式2用来说明循环条件,表达式3用来修正某些变量的值。
for语句的执行过程为: (1)计算表达式1,转2。
(2)计算表达式2,若其值为非0,转3;否则转5。 (3)执行循环体,转4。 (4)计算表达式3,转2。
(5)退出循环,执行循环体下面的语句。 其流程图如图3.6所示。
for语句的特点:先判断表达式,后执行循环体。 【例3.13】 用for语句解决“1+2+3+„+n”的问题。
/* 求和问题 */
main()
{ int i,sum,n; printf("n Please input a integer:");
/*定义变量*/
/提示用户输入一个整数/ for(表达式1;表达式2;表达式3) 循环体
图 3.6
1和表达式3经常使用逗号表达式,用于简化程序,提高程序3个程序段是完全等价的:
)必须保留的前提条件下,3个表达式的任何一个都可以省略。 在for语句中,在分号(;
3.5.4 循环语句的嵌套
一种循环语句的循环体中又有循环语句,称为循环语句嵌套。3种循环语句可以互相嵌套,并且可以嵌套多层。
【例3.14】 输出如下九九乘法表。
1*1=1
1*2=2 2*2=4
1*3=3 2*3=6 3*3=9
1*4=4 2*4=8 3*4=12 4*4=16
1*5=5 2*5=10 3*5=15 4*5=20 5*5=25
1*6=6 2*6=12 3*6=18 4*6=24 5*6=30 6*6=36
1*7=7 2*7=14 3*7=21 4*7=28 5*7=35 6*7=42 7*7=49
1*8=8 2*8=16 3*8=24 4*8=32 5*8=40 6*8=48 7*8=56 8*8=64
1*9=9 2*9=18 3*9=27 4*9=36 5*9=45 6*9=54 7*9=63 8*9=72 9*9=81 main()
{ int i,j;
for(i=1;i<=9;i++)
{
}
} for(j=1;j<=i;j++) printf("%d*%d=%-4d",j,i,i*j); printf("n");
3.5.5 break语句和continue语句
1.break语句
break语句的一般形式为:
break语句的功能:用于switch语句时,退出switch语句,程序转至switch语句下面的语句;用于循环语句时,退出包含它的循环体,程序转至循环体下面的语句。
【例3.15】 判断输入的正整数是否为素数,如果是素数,输出Yes,否则输出No。 break;
main()
{ int m,i;
scanf("%d",&m);
for(i=2;i<=m-1;i++)
if(m%i==0) break;
if(i>=m) printf("Yes");
else printf("No");
}
注意:
① break语句不能用于循环语句和switch语句之外的任何其他语句。
② 在多重循环的情况下,使用break语句时,仅仅退出包含break的那层循环体,即break语句不能使程序控制退出一层以上的循环。
2.continue语句
continue语句的一般形式为:
continue语句的功能:结束本次循环,跳过循环体中尚未执行的部分,进行下一次是否执行循环的判断。在while语句和do-while语句中,continue把程序控制转到while后面的表达式处,在for语句中continue把程序控制转到表达式3处。
【例3.16】 输出100~200中不能被7整除的数。
main()
{ int n;
for(n=100;n<=200;n++)
{ if (n%7==0)
}
} continue; printf("%dn",n); continue;
3.6 程序设计举例
【例3.17】 输入3个数,按由小到大的顺序输出。
main()
{ int a,b,c,t;
}
程序运行结果如下: 10, 3, 6
3<6<10
注意:两个变量内容互换时,应该引入一个中间变量t,协助完成两变量值的互换。
【例3.18】 用下列公式计算的值:
111111–4(精度要求为<10) =4*( )1357nn
#include "math.h"
main()
{ int n=1,t=1;
} float pi=0; while(fabs(t*1.0/n)>=1e-4) { pi+=t*1.0/n; t=-t; n+=2; /*控制循环的条件是当前项的精度*/ /*将当前项累加到pi中*/ /*得到下一项的符号*/ /*得到下一项的分母*/ /*程序中用到求绝对值函数fabs() */ } printf("pi=%.2fn",4*pi);
程序运行结果如下:
注意:求实型数据的绝对值用fabs函数,求整型数据的绝对值用abs函数。
【例3.19】 从屏幕输入某一正整数,判断其是否为素数。
main()
{ int m,i,n=0;
scanf("%d",&m);
for(i=2;i<=m-1;i++)
if(m%i==0)
break; /*如果2~(m-1)之间有整除m的数,则退出循环 */ if(i>=m)
printf("yes! ");
else
printf("no! ");
} pi=3.14
【例3.20】 请列出所有的个位数是6,且能被3整除的两位数。
main()
{ int i;
for(i=10;i<=99;i++) /*i在10~99之间,步长为1*/ if(i%10==6&&i%3==0) /*如果i的个位数是6,且i能被3整除*/ printf("%3d",i); }
程序运行结果如下:
36 66 96
两位的十进制数是10~99,从这些数中找出个位数是6,且能被3整除的数,就是对10~99之间的每个数都要进行判断,一个也不能少,这属于穷举类型题。
【例3.21】 求出Fibonacci数列的前20项。该数列源自于一个有趣的问题:一对兔子,一个月后长成中兔,第三个月长成大兔,长成大兔以后每个月生一对小兔。第20个月有多少对兔子?
Fibonacci数列可以用数学上的递推公式来表示:
F1=1 F2=1
Fn=Fn–1+Fn–2 (n3)
main() {
int a,b,j,f1,f2; f1=1;f2=1;
printf("n%10d%10d",f1,f2); for(j=2;j<=10;j++)
f1=f1+f2; f2=f2+f1; if(j%2==0)
printf("n");
/*输出序列的前两个值*/ /*从3 到20循环*/
/*求最新的数列值覆盖f1 */ /*求第二新的数列值覆盖f2 */ /*输出f1和f2*/ /*每输出4个数字换行*/
{ } }
printf("%10d%10d",f1,f2);
程序运行结果如下:
1 5 34 233 1597
1 8 55 377 2584
2 13 89 610 4181
3 21 144 987 6765
3.7 上 机 实 践
(1)进一步熟悉C语言的基本语句。
(2)掌握if语句和switch语句。
(3)掌握三种循环语句的使用。
2.上机实践内容
(1)运行本章例题。
(2)判断下面程序的运行结果。
① 判断下面程序的运行结果,并用for语句代替while语句重新编写程序,确保输出结果相同。
main()
{ int i,sum;
i=0;sum=0;
while(i<=5)
{ sum+=i;
} i++;
程序运行结果如下:
i=6,sum=15 printf("i=%d,sum=%dn",i,sum); }
用for语句代替while语句重新编写的程序如下:
main()
{ int i,sum;
for(i=0,sum=0;i<=5;sum+=i,i++);
printf("i=%d,sum=%dn",i,sum);
}
② 判断下面程序的运行结果,并用while语句代替do-while语句重新编写程序,确保输出结果相同。
main()
{ int i,sum;
i=5;
sum=0;
do { sum+=2*i;
i--;
} }while(i>0); printf("i=%d,sum=%dn",i,sum);
程序运行结果如下:
用while语句代替do-while语句重新编写的程序如下:
main()
{ int i,sum;
i=5; sum=2*i; i--; while(i>0) { sum+=2*i; i--; } printf("i=%d,sum=%dn",i,sum); } i=0,sum=30
③ 判断下面程序的运行结果,不用break语句重新编写程序,确保输出结果相同。
main()
{ int i,sum;
for(i=1,sum=1;i<5;i++)
{ sum*=i;
if(sum>5*i)
} break;
printf("i=%d,sum=%dn",i,sum);
}
程序运行结果如下:
i=4,sum=24
不用break语句,重新编写程序如下:
main()
{ int i,sum,flag;
flag=1;
for(i=sum=1;i<5&&flag;i++)
main()

{ int i,j;
for(i=1,j=1;j<=50;j++) { if(i>=10) break; if(i%2) { i+=5; continue; }
i-=3; } printf("j=%dn",j); }
程序运行结果如下:
根据表3.2可以计算i和j的值。
表3.2 循环次数与i和j的值
j=6
注意:本题的i%2作为if的条件,如i能被2整除,则该表达式的值为0。 ⑤ 判断下面程序的运行结果,并说明原因。
main()
{ int i;
for(i=1;i<=5;i++)
switch(i) { case 1:printf("i=1n"); continue; case 2:i=1;
case 3:printf("i=3n"); i+=2;
continue;
case 4:printf("i=%dn",i++); break; } printf("i=%dn",i++);
}
程序运行结果如下:
i=1
i=3
i=4
(3)程序设计。
① 输入两个数,并将其中较大者显示出来。
main()
{
} int a,b,max; scanf("%d%d",&a,&b); max=(a>b)?a:b; printf("max=%d",max); i=6
② 从键盘输入一个操作符并进行相应的操作。
main()
{ int x=10,y=5,z;
} char op; scanf("%c",&op); switch(op) { case '+':z=x+y;break; case '-':z=x-y;break; case '*':z=x*y;break; case '/':z=x/y;break; default:printf("Operater Error! "); } printf("%d%c%d=%d",x,op,y,z);
③ 从键盘输入一正整数n,求n的阶乘。
main()
{ int i,s=1,n;
scanf("%d", &n);
for(i=1;i<=n;i++)
s=s*i;
printf("s=%d",s);
}
if(c>'Z'&&c<='Z'+4)
c=c-26;
printf("%c",c);
}
}
⑤ 输入一正整数,计算并显示该整数的各位数字之和,例如整数1987各位数字之和是1+9+8+7=25。
main()
{ long i,sum;
int k;
printf("nEnter a integer: ");
scanf("%ld",&i);
sum=0;
while (i!=0)
{ k=i%10;
} sum=sum+k; i=i/10; } printf("nsume is %d",sum);
习 题 3
1.选择题
(1)若定义:int x=5,y=4;,则下列语句中错误的是( )。
A.while(x=y) 5; B.do x++ while(x==10);
C.while(0); D.do 2; while(x==y);
int x,y;, (2)若定义:则循环语句for(x=0,y=0;(y!=123)||(x<4);x++);的循环次数为( )。
A.无限次 B.不确定次 C.4次 D.3次
(3)若定义:int a=1,b=10;,执行下列程序段后,b的值为( )。
do {b– – =a;a++;}while(b– – <0);
A.9 B.–2 C.–1 D.8
(4)表达式 (int) 3.6*3的值为( )。
B.10 C.10.8
(5)下面的叙述中不正确的是( )。
A.宏名无类型,其参数也无类型 A.9 D.18
B.宏定义不是C语句,不必在行末加分号
C.宏替换只是字符替换
D.宏定义命令必须写在文件开头
(6)与for( ;0; )等价的为( )。
A.while(1) B.while(0) C.break D.continue 2.程序填空题(在下列程序的 处填上正确的内容,使程序完整) ( 1)下列程序的功能是把从键盘上输入的整数取绝对值后输出。 main()
{ int x;
scanf("%d",&x);
if(x<0)
printf("%dn",x);
}
(2)本程序实现判断m是否为素数,如果是素数输出1,否则输出0。 #include "stdio.h"
main()
{ int m,i,y=1;
scanf("%d",&m);
for(i=2;i<=m/2;i++)
if( )
{ y=0;
break;
}
printf("%dn",y);
}
( 3)下列程序的功能是输出1~100之间能被7整除的所有整数。 main()
{ int i;
for(i=1;i<=100;i++)
{ if(i%7)
;
printf("%5d",i);
}
}
( 4)输入若干字符数据,分别统计其中A,B,C的个数。
#include "stdio.h"
case 'A': k1++;break;
case 'B': k2++;break;
case 'C': k3++;break;
printf("A=%d,B=%d,C=%dn",k1,k2,k3);
}
(5)下面程序的功能是从键盘输入若干个学生的成绩,统计并输出最高成绩和最低成绩,当输入负数时结束输入。
main()
{ float x,max,min;
scanf("%f",&x);
max=x; min=x; while( ) { if( x>max)
max=x;
if ( x<min)
min=x;
scanf("%f",&x);
} } printf("max=%f min=%fn",max,min);
3.程序改错题(下列每小题有一个错误,找出并改正)
(1)输入三个数,通过计算输出三个值。
main()
{ int a,b;
float x,y,z;
scanf("%f%f%f",&x,&y,&z);
a=b=(int)(x+y+z);
c=a+b;
printf("%d%d%d",a,b,c);
}
(2)求100以内的正整数中为13的倍数的最大值。
main()
{ int i;
for(i=100;i>=0;i--)
if(i%13==0) break;
printf("%d",i);
}
(3)求1+2+3+„+100
main()
{ int i=1,sum=0;
do
{ sum+=i; i++;
}while(i=100);
printf("%d",sum);
}
4)计算 1+1/2+1/3+„+1/10
main()
{ double t=1.0;
int i;
for(i=2;i<=10;i++)
t+=1/i;
printf("t=%fn",t);
}
5)把从键盘输入的小写字母变成大写字母并输出。#include "stdio.h"
main()
{ char c,*ch=&c;
while((c=getchar())!='n')
{ if(*ch>='a'&*ch<='z')
putchar(*ch-'a'+'A');
else
putchar(*ch);
}
}
4.程序分析题
1)以下程序的输出结果是( )。
main()
{ int x=3,y=3,z=1;
printf("%d, %dn",(++x,y++),z+2); }
2)以下程序的输出结果是( )。
main()
{ int a=10,b=4,c=3;
if(a<b) a=b;
if(a<c) a=c;
printf("%d,%d,%dn",a,b,c);
(( ((
(4)以下程序的输出结果是( )。
main()
{ int x=23;
do
} { printf("%d",x--); }while(!x);
(5)以下程序的输出结果是( )。
main()
{ int a,b;
for(a=1,b=1;a<100;a++)
} { if(b>20) break; if(b%3= =1) { b+=3; continue; } b-=5; } printf("%dn",b);
(6)以下程序的输出结果是( )。
#define N 2
#define M N+1
#define NUM 2*M+1
main()
{ int i;
} for(i=1;i<=NUM;i++); i--; printf("%dn",i);
(7)以下程序的输出结果是( )。
main()
{ float x=2,y;
if(x<0) y=0; else if(x<10) y=1.0/10; else y=1;
} printf("%.1fn",y);
(8)以下程序的输出结果是( )。
main()
{ int x=1,a=0,b=0;
} switch(x) { case 0: b++; case 1: a++; case 2: a++;b++; } printf("a=%d,b=%dn",a,b);
(9)以下程序的输出结果是( )。
main()
{ int a=2,b=-1,c=2;
if(a<b)
} if(b<0) c=0; else c++; printf("%dn",c);
(10)以下程序的输出结果是( )。
#define MAX(x,y) (x)>(y)?(x):(y)
main()
{ int a=5,b=2,c=3,d=3,t;
t=MAX(a+b,c+d)*10;
printf("%dn",t);
}
5.程序设计题
(1)输入3个单精度数,输出其中最小值。
(2)输入10个整数,统计并输出正数、负数和零的个数。
(3)输入三角形的三边长,输出三角形的面积。
(4)输入两个正整数,输出它们的最大公约数和最小公倍数。
2(5)用if-else结构编写一程序,求一元二次方程ax+bx+c=0的根。
(6)用switch-case结构编写一程序,输入月份1~12后,输出该月的英文名称。 (7)求Sn=a+aa+aaa+„+aa„a(最后一项为n个a)的值,其中a是一个数字。如:
15012。
k1kk1k
e的值(精度要求为1<10–6)。 n!
e11111„ 1!2!3!n
(11)编程序按下列公式计算y的值(精度要求为
y1 rr1r1n1<10–6)。 nn1
(12)有一篮子苹果,两个一取余一,三个一取余二,四个一取余三,五个一取刚好不剩,问篮子至少有多少个苹果?