题答案
Last revision on 21 December 2020
习题解析与答案
第1章C语言概述
一.简答题
1 .概述C语言的主要特点。
【解答】
(1)语言简洁、紧凑,使用方便、灵活。 (2)数据类型丰富,表达能力强。
(3)运算符多样。C语言中的运算符包含的范围非常广泛。
(4)具有结构化的控制语句。如if,“else语句、while语句、do while语句、 switch 语句、for 语句。
(5)允许直接访问物理地址。C语言中含有的位和指针运算,能够直接对内存地址 进
行访问操作。
(6)所生成的目标代码质量高,可移植性好。
2 .构成C语言程序的基本单位是什么它由哪几部分组成
【解答】函数是构成C语言程序的基本单位。一个完整的C程序一般由文件 包含、宏定义、函数说明、变量和一个或若干个函数组成。
3 . C语言程序的运行一般要经过哪几个步骤
【解答】⑴编辑;⑵编译;⑶连接,生成EXE文件;(4)执行。 二.运行程序写结果
1 -输入下面程序并运行。 main () (
int al, a2, x; al = 100; a2=50; x=al-a2;
printf (〃x=%d\\n\)
【解答】运行结果为:x=50 2 .输入下面程序并运行。
main () int alf a2, x; al=10; a2=20; x=al*a2;
printf (\"al=%d, a2=%d\\n\printf (\"x=%d\\n〃,x);
}
【解答】运行结果为:al=10, a2=20 x=200
3 .输入下面程序并运行。 #include <> main() (
printf(\"******\\n\"); printf(\" *****\\n\"); printf(\" ****\\n\"); printf(\" ***\\n\"); printf(\" printf(\" *\\n\"); )
【解答】运行结果为:******
*****
思考:可以修改程序,使之输出平行四边形,等腰三角形等图形。 三.编程题
1 .参照本章例题,编写一个C程序,用于显示如下信息:
* *
* * * * * * >k >k * * * * * * )k * * * *
I love C programs!
* >k * *****
***** >k >k >k >k * *
【分析与提示】
①要有文件包含语句include <> C语言中没有数据的输入、输出等功能,数据 的输入、输出都是通过调用系统提供的库函数scanf和printf等来实现的。这些 函数的说明都包括在文件中。
②main是主函数的名称。用{}括起来的内容是函数体,函数体由若干条语句组 成,这是计算机要执行的部分,每条语句以分号“;”结束。 ③注意显示的信息有三行,所以要用到换行符“\\n”。 参考代码:
o
#include <>
main()
printf(''************************\\n') printf(H I love C programs! \\nM); printf(''************************\\n') )
第2章数据类型及其运算
一・简答题
1 . C语言中的数据类型主要有哪几类
【解答】
短整型(short int )
「整型J 整型(int)
长整西(long intS
基本类字字符型(cdr)单精度(float),
3型(浮点型)] J
双精'(double) I
出举类型(enum) < 4组类型 r 构造类,结构体类目(struct)
少用体类型(unLn) 指针类在
I空类型(void)
2 .字符常量与字符串常量有什么区别
【解答】字符常量用单括号括起,字符串常量用双括号括起;字符常量存储时占
1
个字节,字符串常量存储时除了 n个字符外,还有系统加上的字符串终止符\\0,所以字 符串常量存储时占n+1个字节。
3 . C语言中的常量包括哪几类各自是如何构成的
【解答】C语言中的常量是一些其值预先定的量,并且在程序执行过程中其值不再 发生变化。常量的分类遵循基本数据类型分类原则,C语言编译系统自动将其存放在于 类型相应的内存单元中。其类别包含整形常量、浮点常量、字符常量、字符串常量和枚 举常量。整形常量又分为十进制整形常量、八进制整形常量、十六进制整形常量。浮点 常量分成十进制形式和指数形式。C语言中的,字符常量是用单括号括起来的一个字符 或是字符序列,而字符串常量是用一对双括号括起来的零个或者多个字符组成的序列。
4 .简述指针、变量的指针、变量的值、指针变量与指针变量的值的含义是什么
【解答】C语言中将地址又称为“指针;一个变量所分配的内存空间首字节地址, 称为该变量的指针(地址),变量的值就被放入所分配的地址单元中。地址一旦被分配, 就不会再改变,所以,指针是一个常量。既然是常量就可以把它赋给一个变量。用来存 放指针的变量,被称为指针变量。一个指针变量的值是变量的地址,一个指针变量可以 被赋予不同的指针值。
5 .下面哪些是不合法的常量说明不合法的理由。
Oxabc, , \"Morning\"【解答】非法常量有:
123, , 02,
02——含有非八进制数字8和9
——非法指数形式浮点常量:规定e后面的指数必须为整数。
6.下面对变量定义的语句哪些不正确为什么请改正。
(1) char cLint a2; (2) INT a,b; FLOAT x,y; (3) a.b:char; (4) char if; (5) int a,b (6) Int a:b:c; (7) int a,x; float x,y;
【解答】
(1) char c Lint a2;
错误。定义不同类型的变量时,应用分号彼此分开。 改正为:char cl; int a2;
(2) INT a,b; FLOAT x,y;
错误。C语言中表示类型名的关键字必须小写。 改正为:int a,b; float x,y;
(3) a,b:char;
错误。C语言中变量定义格式为:类型名变量名;
改正为:char a,b;
(4) char if;
错误。变量名不能与C语言的关键字重名。 改正为:char fl;
(5) int a,b
错误。变量定义以语句形式出现,应以分号结尾。 改正为:int a,b;
(6) Int a:b:c;
错误。类型名不能有大写字母,相同类型名之间用逗号分隔。 改正为:int a,b,c;
(7) int a,x; float x,y;
错误。在同一程序位置上,同一变量名不能重复定义充当两个不同的变量。 改正为:int a, x; float xl, y;
7.下述字符串常量的长度是多少在内存中存储时各自占用的单元数又是多少 1 1) “Hello!” (2) tkABC\\ii\\\\TH\\0V, (3) “\\xAB*V765+123=\"
【解答】
2 1) “Hell。!”字符串长度为6,占用内存字节数为7。
3 2) “ABC\\n\\\\TH\\0\\\"字符串长度为9,占用内存字节数为10。因为其中\\n\\\\
\\0\\各自只占一个字符的位置。
4 3) “\\xAB*\\765+123=\"该字符串不是合法的,因为\\765表示的值太大,超出合法
的ASCII字符集的范围。
二.运行程序写结果
5 .以下程序的执行结果是 main()
int ij ; i=15 ;
printf(“%d,%d”, ; }
【解答】14,15
6 .以下程序的执行结果是 _______ o main() (
int a=2O,b= 10,c,*p 1 ,*p2; pl=&a; p2=&b;
c=(-*p 1 )/(*p2)+6; printf(na=%d,b=%d\\nM,a,b);
printf(M*p 1 =%d,*p2=%d\\n*\\*p 1 ,*p2); printf(nc=%d\\n,\\c); )
【分析与提示】
pl
a
c=4 7
.以下程序的执行结果是 ______
#include o main() (
char a='G',b='o',c='o',d='d'; a=a+32;
b=b-6; c=c+3; d=d+8;
printf(n%c%c%c%c\\n'\\a,b,c,d);
)
【分析与提示】从ASCH代码表可以看出,字符“G,、\"d”的ASCII代码值 为 71、111、101,因此,'G +32、' o -6、' o' +3、' d' +8 的值分别是 103、
,
,
105、114、108,它们所对应的字符分别是I\"、\"V、匕”、“1”。
常用结论:
(1)在C语言中,字符数据可以按其ASCII代码值参加整数运算。由于英文字母
在ASCII代码表中是按顺序排列的,所以在计算,。〜3代表的字母时,可从字符,。,其
顺序向后取3个字母,该字母是匕”。
(2)从ASCII代码表可以看出“小写字母”一对应大写字母,的结果是32,因此可推
算出如下等式:大写字母的ASCII值+32=对应小写字母的ASCH值;小写字母的ASCII 值-32=对应大写字母的ASCII值。
【解答】girl
8
.以下程序的执行结果是 ______ o
#include o niain() { int x; x=-3+4*5-6;
printf(nx 1 =%d\\n\x=3+4%5-6;
printf(\"x2=%d\\n\x=-3*4%-6;
printf(\"x3=%d\\n\}
【分析与提示】xl=ll分*5是20, -3+20是17, 17-6等于11)
x2=l (4%5 等于 4, 3+4 等于 7, 7-6 等于 1) x3=0 (-3*4 等于-12, -12%-6
等于 0) x2=l x3=0
9 .以下程序的执行结果是 ______ o
#inckide o main() ( printf(\"%d\\n\printf(\"%d,%c\\n\
printf(\"%d,%c,%o\\n\)
【分析与提示】
0 (NULL的ASCH码值是0)
49, 1 (数字1的ASCII码值是49)
58, :,72 (48+10等于58,正好是“:”的ASCII码值,八进制表示是72)
【解答】0
49, 1 58, :,72
三、改错题
1 -请修改下列程序,使其能够通过编译。
#include <> Void Main() (
int a=6;b=8; int c; c=a*b; printfC%d\\c); )
【答案】错误的地方有3处:(1)第2行关键字应该小写;(2)定义b时前面 应该用逗号;(3)打印语句的格式应该用双引号括起来。 正确的程序如下:
#include <> void main() int a=6,b=8; int c; c=a*b;
printf(\"%d\1
2 .请修改下列程序,使其能够正确运行。
#inckide <> void main(); {
float f=;
char c=''c''; printf(“%c:c); )
【答案】错误的地方有3处:⑴第2行main。;不应该有分号;(2)定义
char c=''c\";
时,字符常量应该用单引号;(3)打印语句printf(\"%d\\n”,int(f%3));的格式有 错,应该在f前的int用括号括起来,因为实型数据不能执行取余运算。 正确的程序如下:
#include <> void main() ( float f=; char c=c*;
printf(,'%d\\n\printf(H%c\
1
第3章 顺序结构程序设计
一.简答题
1 .程序有哪三种基本结构
【解答】程序的三种基本结构为:顺序结构、选择结构和循环结构。
2 . C语言的语句有哪几类表达式语句与表达式有什么不同
【解答】C语句可分为以下五类:表达式语句、函数调用语句、控制语句、复合语 句和空语句。其中表达式语句与表达式的区别在于表达式语句是表达式加上“二组成。 二、填空题
运算符,%是指
2 . C语言中的空语句就是 _____________ ,
3 . Scanf函数中的“格式字符”后面应该是 ___________ 而不应该是
4 .若想输出字符%,则应该在“格式字符。的字符串中用 表示。 5 . int x=7;执行 x+=x- =x+x;后 x 的值是 ______________ c
6 . int a=10,b=20;a+=b;b=a-b;a-二b;的功能是 ______________ o
答案:1 .地址、变量a的内存地址。
2 .一个分号。 3
.变量地址,变量名。
4 .连续2个%号。 5 . -14 6
.交换变量a,b的值,打印出a=20,b=10
o
三 .运行程序写结果
1 .以下程序的执行结果是 ______ 。
#inckide o niain() { double d=;int x,y; x=;y=(x+/; printf(\"%d\\n';d*y); }
【解答】0
2 .以下程序的执行结果是 ______ o
main() ( double d;float f;long l;int i; i=f=l=d=20/3;
printf(\"%d %ld %f %An\
【解答】6 6
3
.以下程序的执行结果是
main() { int k=17;
printf(\"%d,%o,%x\\ii\}
【解答】17, 21, 11
4
.以下程序的执行结果是 _____ ,
#inckide o main() { char a,b,c,d; a='A,,b=,B,,c=,C;d='D'; printf(\"%lc\\n\printf(\"%2c\\n\printf(\"%3c\\n\printf(\"%4c\\n\)
【分析与提示】可以用%c格式输出的,也可以用%€1格式输出,所以与%md近 似,m指出了要输出数据的宽度。若数据位数小于m,则左端补空格,若数据位数大于 m,则按实际位数输出。
【解答】A
B C D
5
.以下程序的执行结果是 _____ ,
#include o main() { char cl,c2;
scanf(1,%c%c,\\&c 1 ,&c2);
printf(nc I=%c,c2=%c,c3=%d,c4=%d\}
【解答】运行输入:AB〈回车>
运行结果为:c 1 =A,c2=A,c3=65,c4=66
6 .以下程序的执行结果是 #inckide o main() ( char cl,c2;
scanf(\"%c,%c\\&c 1 ,&c2); ++cl; ~c2;
printf(Hc l=%c,c2=%c\\nH,c 1 ,c2); )
【分析与提示】例如当输入B,C<回车〉,B, C的AS析I码值为66, 67,7;后,cl为66+1变成67即C, c2为67-1变成66即B。
【解答】运行输入:B,C〈回车),运行结果为:cl=C, c2=B
7
.以下程序的执行结果是 ______ o
main() {
char ch=*a ;int a=98; double y=;
printf(n( 1 )a=%d,a=%c,ch=%d,ch=%c\\n,\\a,a,ch,ch); printfC(2)b=%u\\n';b);
执行- printf(\"⑶ c=%ld\\n”,c); printf(n(4)x=%f,y=%f\\nH,x,y); printf(n(5)x=%e,y=%e\\n'\\x,y); printf(n(6)y=%\\n,\\y); }
[解答](1 )a=98,a=b,ch=97,ch=a
(2)b=I000 (4)x=, y= (5)x=+00,y=+00 (6)y=
8 .以下程序的执行结果是 _______ o #inckide<> main() ( int a,b; float x;
scanf(\"%d,%d\x=a/b;
printf(n\\nx=%f\\n M,x);
1
【解答】运行输入:2, 2〈回车〉,运行结果为:
9
.当输入123451a时,给出程序的运行结果,执行结果是。
#inckide<> main() (
int a;char c;
scanf(\"%3d,%c\printf(,r\\n%d,%d\\n\}
【分析与提示】%md, m指出了要输出数据的宽度。若数据位数小于m,则左端补 空格,若数据位数大于m,则按实际位数输出。a的ASCII码值是97。
【解答】12345,97
10
.分析下面程序,在键盘上输入数据 才能使得变量a=10, b=20,
cl='A', c2='a\" x=, y=, z=o
程序如下:
#include<> main() ( int a,b;
float x,y,z; char cl,c2;
scanf(\"%5d%5d%c%c%f%f%*f,%f,,&a,&b,&cl,&c2,&x,&y,&z);
printf(na=%d,b=%d,c 1 =%c,c2=%c,x=%f,y=%f,z=%F',a,b,c 1 ,c2,x,y,z); )
【分析与提示】按%5 d格式输入a与b的值时,要先键入三个空格,然后再键入
10 与20。%*f是用来禁止赋值的。在输入时,对应%*f位置可以随意输入一个数(我们输
入,该数不会赋值给任何变量的)。
【解答】运行输入:— 〈回车》
11 .一个程序中,使用了多个scanf函数输入数据,用a=3,b=7,x=,y=,cl=,A\\c2=W
输入到每个变量,应该如何输入数据
int a,b; float x,y; char cl,c2;
scanf(,,a=%d,b=%d,,,&a,&b); scanf(H x= %f,y=%e\scanf(H cl= %cc2=%c,\\&c 1 ,&c2);
printf(Ha=%d,b=%d,x=%f,y=%f,c 1 =%c,c2=%c\\n\)
【分析与提示】在使用多个scanf函数输入数据时,第一个输入行末尾输入的回车 被第二个scanf函数吸收,因此在第二、三个scanf函数的双引号后放置一个空格以抵消 上行输入的回车键。若没有一个空格,则按上面输入的数据会出错。
【解答】运行输入:a=3, b=4<回车〉
X=8, y* 回车〉 Cl=AC2=a< 回车>
运行结果:a=3, b-7, x=,y, cl-A, c2-a
=
四 .编程题
1 .由键盘输入1个字母,输出其ASCII码值。
【分析与提示】将一个字符常数赋给一个字符变量,并不是把该字符本身放到内存 单元中去,而是将该字符的ASCII代码放到内存单元中,因此,字符型数据也可以像整 型数据那样使用,可以用来表示一些特定范围内的整数。所以int型与char型变量的 值可以互换,分别用枇和洞不同格式输出就行了。
但是注意这种转换是有条件的。因为,char变量在内存占一个字节,而int整型 变量占2个字节。当int型高位字节是0时,char与int可以互换;若不是0,则不可 以互换。例如,用%。格式输出时,取低位字节,高位字节被舍弃。
参考代码:
#include char ch; ch=getchar();
printf(\"%c,%d\
)
【解答】运行输入:B〈回车〉
运行结果:B, 66
2
.从键盘上输入一个大写字母,把它转换成小写字母,然后显示出来。 【分析与提示】大写字母转换小写时ASCII码值+32,相反的,小写字母转换成大
写字母时ASCII码值-32。
参考代码:
#include <> main()
(
char xl,x2; printf(Mxl=\\nH); scanf(\"%cH,&xl); x2=xl+32;
printf(n%c,%c\\nH,x 1 ,x2); )
【解答】运行输入:A〈回车》
运行结果:A, a
3 .从键盘上输入两个实型数,求两数的和、差、积,输出结果时要求小数部分占两位。
【提示】结果要求保留2位小数,所以输出的结果格式为%.2九
main() (
float x,y,a,b,c;
printf(Hplease input x,y:\"); scanf(\"%f,%f\a=x+y; b=x-y; c=x*y;
printf(nx=%f,y=%f\\nn,x5y);
printf(Hx+y=%.2f\\nx-y=%.2f\\nx*y=%.2f\\n,\\a,b,c);
【解答】
运行输入:please input x,y: 10, 20V回车〉 运行结果:x=,y=
x+y= x-y= x*y=
4
.编写一个程序,求出给定半径r的圆以及内正n边形的面积,并且输出计算结
果。r和n的值由用户输入。
【分析与提示】由数学知识得到:半径为r圆的面积5 =加[半径为r圆的内接正
n边形的面积4 =\"飞心々/2,其中。=21/〃
处理步骤:提示信息,接收参数值;计算圆的面积;计算正n边形的面积;输出 结果。
参考代码:
#inckide o #inckide o #define PI niain() ( int n;
float r,s,area;
printf(HPlease input the radius and the scanf(\"%f%d\
s=PI*r*r;
area=(n*r*r*sin(2*PI/n))/; printf(nS=%.2f\A=%.2f\\n,\\s,area); return(O); }
运行结果如下:
Please inout the radius and the N.; 1 5 S= A=
5 .已知华氏温度与摄氏温度之间的转换公式是:c = 5/9x(F-32),编写一个程 序,将
用户输入的华氏温度转换成摄氏温度,并予以输出。
【分析与提示】首先要定义输入输出温度为浮点型,且5/9两数相除结果为整数,
5/9的值为0,故不能写成5/9,而应写成*(932)。结果要求保留2位小数,所以输出 的结果
格式为%。
参考代码:
#include <> niain() { int f; float c;
printf(n\\nplease input the F:n); scanf(\"%d'\\&f);
c=9*(f-32); 〃不能写成5/9,两数相除结果为整数,5/9的值为0*/ printf(nthe is : %.2f\\c); return(O); )
【解答】运行结果如下:
please input the F: 75〈回车〉 the ,[erature is :
6 .由键盘输入5个学生的计算机成绩,计算他们的平均分并保留2位小数。
【分析与提示】方法与上题类似,同样是保留两位有效数字%。 参考代码:
main() (
int a,b,c,d,e; float totaLaver;
printf(,,Plese input 5 students' scores : \\nH); scanf(\"%d,%d,%d,%d,%dotal=a+b+c+d+e; aver=total/;
printf(MAverage : %\\iV\\aver);
)
【解答】运行输入:80, 93, 75, 68, 87〈回车)
运行结果:Average :
7 .编写将输入的英里转换为公里,每英里等于5380英尺,每英尺等于12英
寸,每英寸等于2. 54厘米,每公里等于100 000厘米。
main() (
double mile,k; priiitf(uenter scanf(u%lf\\&mile); k=mile*5380* 12* 100000;
print*\" %lf mile is %lf kilometerNn'\\mile^k); )
【解答】运行:enter mile:2/
mile is kilometer
第4章 选择结构程序设计
习题
1 .已知a=3, b=4, c=5o则逻辑表达式a+b>c&&b= =c的值为 (a>b)&&clll 的值为, !(a+b)+c-l&&b+c/2 的值为 o
【分析与提示】本题考查运算符的优先级别。 【解答】0 : 1:1 二、运行程序写结果
L下列程序运行的运行结果为 o #inckide o main () {
int a=3, b=8, c=9, d=2, e=4;
int min; min= (amin= (min 【分析与提示】本题程序的功能为:找出a,b,c,d,e中最小的值并输出。 【解答】Min is 2 2 .若输入3,4〈回车>,下列程序运行的运行结果为;若输入4,3〈回车>,下列 程序运行的运行结果为 O #inckide<> main () { int a, b, c; printf (\"Input a, b:\"); scanf (\"%d, %d\if (a>=b) {c=a*b; printf (,,%d*%d=%d\\n\"1 a, b, c) ;} else {c=a/b; printf (\"%d/%d=%d\\n\ } 【分析与提示】本题程序的功能为:从键盘输入变量a,b,计算c的值(若a>=b,则 c=a*b,若 a【解答】3/4=0 ; 4*3=12 3 .下列程序运行的运行结果为 o #inckide o main () { int x=l, y=0f a=0? b=0; switch (x) ( case 1: switch (y) {case 0: a++; break; case 1: b++; break; ) case 2: a++; b++; break; ) printf (\"a=%d, b=%d\\n\ } 【分析与提示】本题中easel:后面是一个switch语句,执行完该语句后,直接执行case 2:后面的语句。 【解答】a=2t b=l 三.编程题 1 .输入一个字母,若为小写,则把它变成大写输出。 【分析与提示】小写字母的ASCII码值与其对应的大写字母的ASCII码值相 差32o 参考代码: main() char c; printf(\"请输入一个字母\\n”); scanf(n%c,\\ &c); if(c>='a'&&cv='z') c=c-32; printf(\"%c\\n\ 2 .企业发放的奖金根据利润提成。利润⑴低于或等于10万元时,奖金可提 10% ;利润高于10万元,低于20万元时,低于10万元的部分按10%提成,高于10万元 的 部分,可可提成舟;20万到40万之间时,高于20万元的部分,可提成5% ; 40万到 60万之间时高于40万元的部分,可提成3% ; 60万到100万之间时,高于60万元的部 分、 可提成%,高于100万元时,超过100万元的部分按居提成,从键盘输入当月利润 I,求应发放奖金总数 【分析与提示】请利用数轴来分界,定位。注意定义时需把奖金定义成长整型。 参考代码: main () { long int i; int bonusl,bonus2, bonus4, bonus6, bonuslO, bonus; scanf (〃/ld〃, &i); bonusl=100000*;bonus2=bonusl+100000*; bonus4=bonus2+200000*; bonus6=bonus4+200000*; bonus10=bonus6+400000*; if(i<=100000) bonus=i*; else if(i<=200000) bonus=bonusl+(i-100000)*; else if (i<=400000) bonus=bonus2+(i-200000)*; else if(i<=600000) bonus=bonus4+(i-400000)*; else if (i<=1000000) bonus=bonus6+(i-600000)*; else bonus=bonus10+(i-1000000)*; printf(\"bonus二%d”, bonus); ) 3 .由键盘输入三个整数a、b、c,用条件运算符求出其中最大值和最小值。 【分析与提示】首先比较输入的a,b的大小,并把大数装入max,小数装入min中, 然后再与c比较,若max小于c,则把c赋予max ;如果c小于min,则把c赋予min。因此 max内总是最大数,而min内总是最小数。最后输出max和min的值即可。 参考代码: main() ( int a,b,c,max,min; scanf(H%d,%d,%d\max=a>ba:b ; niax=max>cmax: c; min=a 4 .有一函数: X f(x 编一程序,输入一个x值,输出y值。 【分析与提示】本题考查if语句的嵌套,应当注意if与else的配对关系。从最内层开 始,else总是与它上面最近的(未曾配对的)if配对。 参考代码: main() ( float x,y; printfC请输入x的值\\n\"); scanf(H%f;&x); if(x printf(\"x=%,y=%”,x,y); I 5 .从键盘上输入星期号,并显示该日期的英文名字。 【分析与提示】本实例知识点:switch语句。 switch语句的控制流程是:首先计算表达式的值,然后依次与每一个case中的常量 值 进行比较,一旦发现了某个能够匹配的值,就执行该case后面的语句组,直到遇到 break语句为止。如果表达式的值与所有case中的常量都不匹配,则执行default后面的 语句组。 参考代码: main() int xqh; char ywm; printf(\"请输入星期号(1-7) : \\n\"); scanf(\"%d”,&xqh); switch(xqh) { case 1: printf(HMondayH); break; case 2: printf(HTuesdayM); break; case 3: printf(HWednesdayH); break; case 4: printf(HThursdayH); break; case 5: printf(HFridayH); break; case 6: printf(MSaturdayH); break; case 7: printf(nSundayH); break; default : printf(Merrorn); ) ) 6.某市不同车牌的出租车3公里的起步价和计费分别为:夏利7元/公里,3公里以 外元/公里;富康8元/公里,3公里以外元/公里;桑塔纳9元,3公里以外元/公里。编 程:从键盘输入乘车的车型及行车公里数,输出应付车资。 【分析与提示】可设三个变量,分别表示乘车的车型、行车公里数和应付车资,根 据乘车的车型和行车公里数,计算出应付的车资。 参考代码: main() ( /*定义乘车的车型变量ex */ float gl, cf; /*定义行车公里数变量gl、应付车资变量cf*/ 夏利 \\n \2-富康 \\n \3-桑塔纳 \\n\"); printf(、请输入车型(1-3) scanf(\"%d\ int ex; printf(\"\\n\请输入行车公里数:\"); scanf(\"%f',&gl); switch(cx) { case 1: if(gl<=3) cf=; else cf=7+(gl-3)* ;break; case 2: if(gl<=3) cf=; else cf=8+(gl-3)* ;break; case 3: if(gl<=3) cf=; else cf=9+(gl-3)* ; ) printf(”应付车资为 %. 1 ) 7 .给一个不多于5位的正整数,要求:①求出它是几位数;②分别打印出每一位数 字; ③按逆序打印出各位数字。如原数为12345,则逆序为54321。 【分析与提示】本题的思路是:设 5 个变量,分别代表个位、十位、百位、千位 和万位。从个位起,依次将各个位取出来,按取出的顺序组合成新的数据,并记录当前 取出的数字的个数。 参考代码: include \"\" main() ( unsigned x,m,n=O,w=O; unsigned ge=05shi=0,bai=0.qian=0,wan=0; printf(“请输入一个正整数) scanf(H%u,\\&x); m=x; ge=m%10; m=m/10; w= 1; n=ge; if(m) {shi=m%10; m=m/10; w=2; n=n*10+shi; if(m) {bai=m%10; m=m/10; w=3; n=n*10+bai; if(m) {qian=m%10; m=ni/10; w=4; n=n*10+qian; if(m) {wan=m; w=5; n=n*10+wan;} ) ) ) printf(H\\n%u 为%11 位数”,n,w); printf(\"\\n正整数的原序为:%u\printf(”\\n正整数的逆序为:%uH,n); ) 注:当该程序输入一个较大的5位数时,输出结果就不正确了,思考为什么 动手试一下怎样修改该程序。 第5章 循环结构程序设计 一、填空 1.下面程序的功能是用“辗转相除法力求两个正整数的最大公约数。请填空。 #inckide<> main () int r, m, n; scanf (,'%d%dn1 &m, &n); if (m printf (\"%d\\n\) 【分析与提示】辗转相除法:两数相除,若不能整除,则以除数作为被除数,余数 作为除数,继续相除,直到余数为0时,当前除数就是最大公约数。 【解答】(l)r=m;m=n;n=r; (2)r=m%n; 二 .运行程序写结果 1 .下列程序运行的运行结果为 O #inckide o main () ( int y=10; do {y--; } while (--y); printf (\"%d,,I y-); ) 【分析与提示】注意y~与y—的运算顺序。 【解答】0 2 .下列程序运行的运行结果为。 main() ( int x=3,y=6,z=2; while(x++!=(y-=l)) ( z+=l; if(y 1 【解答】4, 5,3 3 .下列程序运行的运行结果为, main() ( int a=Lb=O; for(;a<3;a++) switch(a++) ( case l:b—; case 2:b++; case 3:b+=3;break; 1 printf(“%d\\n”,b); ) 【解答】3 4 .下列程序运行的运行结果为 o main() int x=10,y=10J; for(i=0:i<2;y=i++) priiitf(u%4d%4d,,,x-,y); ) 【解答】10 10 9 0 三 .编程题 1 .求 s=l+2+4+8+-+ 的值。 【分析与提示】本题为数学项求和问题,数学项间的关系为:第n项的值为第n-1 项的值2倍。参考代码: main() ( int i,s=05t=l; while(t<=) { s=s+t; t=2*t; } printf(Hs=%d\\n*\\s); ) 2 .求 s=l+l/2+l/3+-+l/100 的值。 【分析与提示】本题为分数数学项求和问题,要想得到每一项的正确结果,分式 中的分子、分母至少要有一个为实型数据。 参考代码: main() {int i; float s=0,t; for(i=l ;i<= 100;i++) { t=i; s=s+t; ) printf(\"s=%.2f\\n\) 3 .求 T= 1!+2!+3! +…+10!的值。 【分析与提示】本题为数学项求和问题,数学项间的关系为:第n项的值为第n-1 项的n倍。参考代码: main() long int t=O.tn=l; int i; for(i=l ;i<=10;i++) { tn=i*tn; t=t+tn; ) printfC't=%ld\) 4 .求 s=2/1+3/2+4/3+5/44---+22/21 的值。 【分析与提示】请抓住分子与分母的变化规律。 参考代码: main() ( int m; float s=0,n=; for(m=l;m<=2 l;m++) { s=s+ii/m; n=n+1; ) printf(\"s=%.2fui\} 5 .输入一行字母,分别统计其中的英文字母、空格、数字和其他字符的个数。 【分析与提示】利用while语句,条件为输入的字符不为‘\\n' . 参考代码: include main() { char c; int Ietters=0,space=0,digit=0,other=0; printf(\"请输入一行字符:\\n\"); while((c=getchar())!=,\\n,) {if(c>=,a,&&c<=,z,llc>=,A,&&c<=,Z,) letters++; else if(c=,') space++; else if(c>=,0,&&c<=,9,) digit++; else other++; 1 printf(\"字母数=%d 空格数=%d 数字数=%d 其它字符数二%d\\n”,letters,space,digit,other); )6 .求100以内能被8整除的数,并求它们的和。 【提示】判断一个数m能否被n整除的方法是:将m对n取余数,若余数为0, 则为整除。 参考代码: main() ( int n,s=0; for(n= 1 ;n<= 100;n++) if(n%8==0) {s=s+n; printf(\"%4d',,n); ) printf(\"\\ns=%d\\n\) 7 .打印出所有的“水仙花数,所谓“水仙花数”是指一个三位数,其中各位数字的 立 方和等于该数本身。例如153=1 +5 +3 3 3 3o 【分析与提示】利用for循环控制100 ~ 999个数,每个数分解出个位,十位,百 位。 参考代码: main() { int i,j,k,n; printf(〃水仙花数是:\"); for(n= 100;n< 1000;n++) {i=n/100; j=n/10-i*10; k=n%10; if(n= =i*i*i+j*j*j+k*k*k) printf(z,%5d\\n); printf(〃\\n〃); ) 8 .以下面的格式,输出九九乘法表。 1*1=1 1*2=2 2*2=4 1*3=3 2*3—6 3*3=9 1*9=9 2*9=18 3*9=27 …9*9=81 【提示】分行与列考虑,共9行9歹IJ,利用双重for循环,外循环环j控制列。参考代码: main() {int i,j; for(i=l;i<10;i++) { for(j=l;j<=i;j++) printf(\"%d*%d=%-4d”,j,i,j*i); printf(\"\\nH); ) 1 9 .用for循环打印输出以下图案。 **** **** *冰冰水 * * ** (图形形 (图形b) 输出图形a程序代码: include \"\" main() ( int i,j,k; for(i=0;i<4;i++) /* 控制打印行数*/ { forG=0;j<10+i;j++) 严控制空格输出位置*/ printf(,'\"); for(k=0;k<4;k++) /*控制每行*的输出个数*/ printf(,,*H); i控制行,内循 printf(\"\\n\"); ) ) 输出图形b序代码: 痴chide main() ( int i,j,k; for(i=0;i<4;i++) /* 控制打印行数 { for(j=0;j<3-i;j++) priiitf(u \"); for(k=0;k<2*i+l;k++) /*控制每行*的输出个数*/ printf(“巧; printf(\"\\n”); } ) 10 /*控制空格输出位置*/ .猴子吃桃子问题。猴子第一天摘下若干个桃子,当即吃了一半,还不过瘾,又 多吃了一个。第二天早上又将剩下的桃子吃掉一半,又多吃了一个。以后每天早上都吃 了前一天剩下的一半零一个。到第十天早上再想吃时,见只剩一个桃子了。求第一天共 摘了多少个桃子。 【提示】采取逆向思维的方法,从后往前推断。参考代码: main() { int day,xl,x2; day=9; x2=l; whiIe(day>0) {xl=(x2+l)*2; x2=x 1; day--; ) printf(\"桃子总数=%d\\n\) 11 .求出500以内所有素数。 【提示】判断素数的方法:用一个数分别去除2到sqrt(这个数),如果能被整除, 则表 明此数不是素数,反之是素数。 参考代码: include main() {int m,k,i,n=O; for(m=2;m<=500;m++) ( k=sqrt(m); for(i=2;i<=k;i++) if(m%i==O) break; if(i>=k+l) { printf(\"%-5d\n=n+1; if(n%10==0) printf(H\\nH); ) ) printf(\"\\n\"); ) 12 .输入一个整数(0~99999),判断它的位数,并重新组合成同样位数的最大值, 如, 输入1345,输出5431。 【提示】先求出该整数的位数;其次分解出每一位数(个位、十位、百位、千位、 万位);接着将5个位数进行排序;最后根据整数的位数重新组合成同样位数的最大 值。 参考代码: main() {long int num,篦1或434445皿/*分别代表个位,十位,百位,千位,万位和位数 */ printf(\"请输入一个整数(0~99999):“); scanf(H%ld*\\ &num); if(nuni>9999) n=5; else if(num>999) n=4; else if(num>99) n=3; else if(num>9) n=2; else n=l; printf(Mn=%ld\\n,\\n); d5=num/10000; d4=(num-d5*l 0000)/1000; d3=(num-d5*10000-d4* 1000)/100: d2=(num-d5* 10000-d4* 1000-d3*l 00)/10; d l=num-d5*l0000-d4* 1000-d3* 100-d2* 10; if(d5Vd4) {t=d5;d5=d4;d4=t;} if(d5Vd3) {t=d5;d5=d3;d3=t;J if(d5Vd2) {t=d5;d5=d2;d2=t;J if(d5 {t=d4;d4=d3;d3=t;J if(d4Vd2) {t=d4;d4=d2;d2=t;J if(d4 { case 5: num=d5*10000+d4*1000+d3*100+d2*10+dl; break; case 4: num=d5* 1000+d4* 100+d3* 10+d2; break; case 3: num=d5*100+d4*10+d3; break; case 2: num=d5*10+d4; break; case 1: num=d5; ) printf(\"重组后的数为:%ld\\n*\\num); ) 13.求证100以内哥德猜想是成立的。即:100以内任何一个大的偶数(大于等 于6)都可以表示成两个素数之和。 【分析与提示】我们先不考虑怎样判断一个数是否为素数,而从整体上对这个问题 进行考虑,可以这样做:读入一个偶数d将它分成p和q,使n=p+q。怎样分呢可以令 p从2开始,每次加1,而令q=n-p,如果p、q均为素数,则正为所求,否则再试。 参考代码: #include o #inckide o main() { int j,n,p,q,flagp,flagq; printf(\"please input n :\\n'*); scanf(\"%d\if(((n%2)!=0)ll(n<=4)) printf(\"input data error!\\n\"); else { P= 1 ; do { p = p + 1 ; q = n - p ; flagp = 1 ; for(j=2;j<=(int)(sqrt(p));j++) /*判断 p 是否为素数*/ { if((p%j)==O) { flagp = 0 ; break; /*不是素数,退出循环*/ ) ) flagq=l ; for(j=2;j<=(int)(sqrt(q));j++) /*判断 q 是否为素数*/ { if ((q%j)==0) { flagq = 0 ; break ; /*不是素数,退出循环*/ ) ) } while(flagp*flagq==O); printf(,,%d=%d+%d\\n\) ) 第6章数组与指针 简答题 1、什么是数组,为什么在C语言中引用数组 【解答】数组是有序的、且具有相同性质类型的数据集合。引用数组来实现成批地处理数据。 2、在C语言中如何表示一个字符串 【解答】运用字符型数组来表示字符串。 3、指针是指什么 【解答】指针就是地址。 二 .运行程序写结果 1 .以下程序的执行结果是 _____ O main() ( int k,a[6]={ 1,2,3,4,5,6); for(k=5;k>0;—k) if(a[k]%2==0) printf(\"%d \) 【提示】从后向前把能被2整除的数组元素输出。 【解答】6 4 2 2 .以下程序的执行结果是 _____ o #include o main() { char str[]=\"SSSWLIA”,c; int k; for(k=2;(c=str[k])!='\\0';k++) { switch(c) ( case T:++k;break; case 'L':continue; default:putchar(c);continue; } putcharf**); ) } 【提示】从字符串中第3个字符开始,把符合要求的字符运用输出字符函数 putchar()输出;最后在其后输出一个\"*二 【解答】SW* 3 .以下程序的执行结果是 ______ : main() { char ss[10]=H12345H; strcat(ss,n67H); gets(ss); printf(n%sM,ss); ) 假设输入“ ABC” 【分析与提示】运用字符串连接函数strcat(),把两个串”12345”和“67”连接,对其 重新赋值后,原有数值被刷新输出新值。 【解答】“ ABC” 4 .以下程序的执行结果是 ______ : # include <> main() ( chara[]=\"Monday\strcpy(a,b); printf(\"%s\%s\\n\printf(\"%c\%c\\n\) 【分析与提示】把b字符串的内容拷贝到a字符串中,分别显示a和b串内容;再 显示数组元素a[4]和a[5]的内容。 【解答】day day a y 5 .以下程序的执行结果是 ______ : niain() ( intx[8]={8,7,6,5,O,O},*s; s=x+3; printf(\"%d\} 【分析与提示】运用指针显示数组元素值。需要注意的是把数组X第3个元素的地 址,赋给了指针变量s,所以s[2]里面存储的是x[5],即0。 【解答】。 6 .以下程序的执行结果是 _____ : main() { int a=7,b=8,*p,*q,*r; p=&a;q=&b; r=p:p=q;q=r; printf(\"%d,%d,%d,%d1*p,*qab); ) 【分析与提示】指针变量存储地址,而不是数值。 【解答】8,778 7 .以下程序的执行结果是 _____ o niain() ( char a[]=,,language,\\b[]=HprogrameH; char *p,*q; p=a;q=b; while(*p&&*q) { if((*p)==(*q)) printf(,l%c,\\*p); p++;q++; } ) 【分析与提示】程序功能是,输出两个字符串中相同的字符。 【解答】gae 8 .以下程序的执行结果是 _____ o # include <> # include <> main() ( char a[80]=HABH,b[80]=nLMNPn; int i=0; strcat(a.b); while(a[i++]!='\\0,) b[i]=a[i]; puts(b); ) 【分析与提示】把b串内容连接到a串上,再通过循环对b串重新赋值。 【解答】LBLMNP 三 .编程题 1 .已有10个数,求它们当中的最大值。 【分析与提示】运用一维数组保存10个数,依次比较保存最大值。 参考代码: main() { int i,a; int n[l O]={ 8,2,4,671,0,85,32,54); a=n[0]; for(i=l;i<10;i++) if(n[i]>a) a=n[i]; printf(Ha=%d\\n,\\a); } 2 .从键盘输入10个学生的成绩,建立一个一维数组,求学生的平均分。 【分析与提示】把1。个学生的成绩保存在一维数组,运用一重循环计算所有成绩 的总和,在此基础上计算平均值。 参考代码: main() { int i; float a[10],sum=0,ave; printf(”输入10个学生的成绩:\"); for(i=0;i<10;i++) { scanf(H%f;&a[i]); sum=sum+a[i]; } ave=sum/10; printf(“10个学生的平均成绩是%。”,ave); 3 .将两个一维整型数组中的对应元素相加后显示出来。 【分析与提示】把数组下标相同的元素值相加。 参考代码: #inckide<> main() ( int i; int x[5]={ 10,8,7,6,5}; int y[5]={-3,9,-10,24}; int z[5]; for(i=0:i<5:i++) z[i]=x[i]+y[i]; printf(\"\\n相加后一维数组为:\"); for(i=0;i<5:i++) printf(\"%d \) 4 .线性查找。 【分析与提示】从数组的第一个元素开始,依次将要查找的数和数组中元素比较. 直到找到该数或找遍整个数组为止。 参考代码: main() ( int table[ 10]={ 2,4,6,8,101214,16,18,20}; int find=0,i,x; printf(”请输入要找的数:\"); scanf(\"%d\for(i=0;i<10;i++) if(x==table[i]) {find=l;break;) if(find==l) printf(\"%d 在 table[%d]中 else printf(\"没有找到数%小】>); 5 ,求一个4x4矩阵对角线元素之和。 【分析与提示】若设置矩阵行列坐标分别为i和j,则对角线元素下标满足以下条 件: i==j 或 i+j=3。 参考代码: main() ( int a[4][4] ,i,j,sum=O; for(i=0;i<4;i++) for(j=0;j<4;j++) ( scanf(\"%d”,&a[i][j]); if(i==j||i+j==3) sum=sum+a[i][j]; ) printf(\"对角线元素之和:%d”,sum); ) 6 .将两个二维数组对应元素加起来,存到另一个二维数组中。 ,0 20) P 4 ' 【分析靠质点‘用双舐威J把行列下标均相同的元素值相加。 参考代码: main() ( int a[3][2]={ 10,20,30,40,50,60); int b[3][2]={ 14,2,5,3,6); intc[3][2]; int i,j; for(i=0;i<3;i++) { for(j=0;j<2;j++) { c[i]U]=a[i][j]+b[i][j]; printfC'%4d\\c[i]|j]); 1 printf(H\\nu); ) ) 7 .找出一个二维数组中的鞍点。 【分析与提示】所谓鞍点指该位置上的数在该行上最大,在该列上最小。注意并不 是所有的二维数组都有鞍点。 参考代码: #define N 3 #define M 3 main() ( int a[M][N],(*p)[N]; /* p为指向一维数组的指针*/ int max,maxi,maxj; int ini flag 1 =0,flag2=0; p=a; printf(\"给数组输入数据:\\n\"); for(i=0;i for(k=0,flag 1 = 1 ;k printf(\"\\n 第%<1 行,第%d 列的%d 是鞍点! \\n\flag2=l; ( ) if(»flag2) printf(”\\n矩阵中无鞍点! ”); ) 8 .用指针数组给一个整型二维数组输入数值,并求出各行元素的和。 【分析与提示】用二维数组a各行的首地址赋予指针数组p的各个元素,通过此循环嵌套,为各个数组元素赋值。 main() ( int a[3][3],*p[3],i,j,sum; for(i=0;i<3;i++) p[i]=a[i];\"把二维数组a各行的首地址赋予指针数组p的各个元素*/ for(i=0;i<3;i++) /*通过此循环嵌套,为各个数组元素赋值*/ for(j=0;j<3;j++) scanf(\"%d\printf(\"和分别为:\"); for(i=0;i<3;i++) /*通过此循环嵌套.求各行数组元素的和*/ ( sum=O; for(j=0;j<3J++) sum=sum+*(p[i]+j); printf(\" %d \/*分行输出每一行的和值*/ ) ) 9 .用指针实现合并两个字符串。 【分析与提示】把第二个字符串中字符逐个赋值给第一个字符串,需要注意的是两 个字符数组下标变量的初值不同。 参考代码: #include<> #inckide<> main() ( char sl[40],s2[20],*p 1 ,*p2; int i,j,n; pl=sl;p2=s2; printf(\"输入第一个字串: gets(pl); printf(”\\n输入第二个字串:”); gets(p2); n=strlen(pl); for(i=n,j=0;*(p2+j)!='\\0,;i++,j++) *(pl+i)=*(p2+j); *(pl+i)='\\O'; printf(”\\n输出合并后字串为:\"); puts(pl); ) 10 .从输入的5个字符串中找出最长的一个字符串输出。 【分析与提示】运用测试字符串长度函数strlen,进行串比较。 参考代码: # include <> # include <> main() ( char a[5][80],*sp; int i; for(i=0;i<5;i++) gets(a[i]); for(i=0;i<5;i++) if(strlen(sp) 第7章函数与指针 一.运行程序写结果 1 .下列程序运行的结果为 O int xl=30,x2=40 ; main() ( int x3=10, x4=20; swap(x3,x4); swap(x2,xl); printf(\"%d,%d,%d,%d\\n\) swap(int x,int y) {xl=x;x=y;y=xl;) 【提示】本题考查全局变量的作用范围。 【解答】10,20,40,40 2 .下列程序运行的结果为。 #inckide o void num() ( extern int x,y; int a=15,b=10; x=a-b;y=a+b; ) int x,y; main() { int a=7,b=5; x=a+b;y=a-b; num(); printf(\"%d,%d\\n\) 【分析与提示】用extern进行外部变量说明。 【解答】5, 25 3 .下列程序运行的结果为。 main() {int a[5]={5,10,-7,3,7),ij,t; sort(a); for(i=0; i<=4; i++) printf(\"%3d\) sort(int a[]) {int i,j,t ; for(i=0; i<4; i++) for(j=0; j<4-i; j++) if(aU]>aU+U) {t=aU];aU]=aU+l];a[j+l]=t;) ) 【提示】该程序的功能是将5个数由小到大进行排序。 【解答】-7 3 5 7 10 4 .下列程序运行的结果为 o #define SQR(x) 2*x+l main() {int a,b,c; a=3;b=2;c=l; a*=SQR(b+c)/ SQR(b+c); printf(\"%d\\n\) 【提示】a*二SQR(b+c)/SQR(b+c);宏展开为 a*=2*b+c+1 /2*b+c+1; 【解答】21 5 .下列程序运行的结果为 void swap 1 (int xjnt y) {int t; t=x;x=y;y=t; return; ) void swap2(int *xjnt *y) {int t; t=*x;*x=*y;*y=t; return; ) main() {int x=3,y=5; printf(\"%d,%d\\n\swapl(x,y); printf(n%d,%d\\nn,x,y); swap2(&x,&y); printf(\"%d,%d\\n\} 【提示】注意指针变量做函数参数时,改变形参的值就等同与改变了实参的值。 【解答】3,5 3,5 5,3 6 .下列程序运行的结果为 long fib (int g) switch (g) Case 0: return 0; case 1: case 2: return 1; return (fib (g-1) +fib (g-2)); k=fib (7); printf (nk=%ld\\nH, k); 【提示】注意函数递归调用的条件。 【解答】k=13 二.编程题 1 .已知圆的半径为R,求它的面积。 /*包含文件*/ /*包含数学库函数*/ #include <> #define PI /* 宏定义 */ /*主函数*/ #include <> /*函数area的原型,即函数说明*/ printf(“请输入半径:\\n\"); float area(float); scanf(u%f;&r); s=area(r); F /* 调 printf(“圆的半径float area(float a) { float d; /*定义函数area */ d=PI*a*a; return(d); ) /*返回计算结果*/ 【提示】本程序由主函数main ()和自定义函数area ()组成。程序的前2句是 文件包含语句,即把输入、输出标准函数和数学函数的文件包含到本程序中。第3句是 宏定义语句,即用标识符PI来代替数字。 运行:请输入半径:/ 显示:圆的半径为: 圆的面积为: 2 .编写一个函数输出三个数中的最大值。 【提示】在main。函数中输入数据,调用求3个数最大值函数。 int max(int x,int yjnt z) { int t ; if(x>=y) t=x ; else t=y; if(t printf(Hinput 3 numbers:H); scanf(\"%d%d%d'\\&x,&y,&z); printf(Hmax=%d\\n,\\niax(x,y,z)); ) 3 .编写一个函数,将一个任意三位数n逆序输出。即若n=456,则输出654。 【提示】将一个三位数n分解为个位、十位和百位分别放入c,b,a中,然后逆序输 出。 int rec(int x) int a,b,c ; a=x/100; b=x%100/10; c=x%10; return(c* 100+b* 10+a); ) main() ( int rec(int x); int y,z; printf(Hinput a number( 100-999):H); scanf(\"%d\z=rec(y); printf(Hthe changed number is :%d\\n'\\z); ) 4 ,编写比较两字符串是否相等的函数。 【提示】按ASCII码值大小比较,将两个字符串自左至右逐个字符相比, 直到出现不同的字符或遇到'\\0'为止。如果全部字符相同,则认为相等,如果出 现不同的字符,则以第一个不同的字符的比较结果为准。比较结果由函数值带 回。 参考代码: #include o int cmp(); niain() ( int resu; char sl[100],s2[100]; printf(HPlease input sl:\\nH); gets(sl); printf(nPlease int s2:\\nn); gets(s2); resu=cmp(sLs2); printf(\"%s 与%$ 的比较结果是%d.\) int cmp(sl,s2) char sl[ ],s2[]; {int i=0; while((s 1 [i]=s2[i])&&(s l[i] !=0)&&(s2[i] !=0)) i++; if(s 1 [i]=='\\0'&&s2[i]=='\\0') return 0; else return(sl[i]-s2[i]); } 5 .编写求字符串长的函数。 【提示】字符串的长度不包括在内。 参考代码: #include o main() {int test(); int n; char str[100]; gets(str); n=test(str); printf(Mthe numbers is :%d\\nH,n); } int test(str) char str[]; {int n=0; while(str[n]!=,\\0,) n++; return(n); ) 6 .编写一个函数判定一个数是否是素数,在主函数中调用该函数,输入一个整 数,输出是否是素数的信息。 【分析与提示】由主函数任意输入一个整数m,将其值传递给子函数isprime(m)由 子函数判断这个数是否为素数,是return(l),否则return(0) o 参考代码: #inckide o main() { int m; printf(HPlease input a data m=:n); scanf(\"%d\isprime (m); } isprinie(int n) int i,k; k=n/2; for(i=2;i<=k;i++) if (n%i=O) break; if(i>=k+l) printf(HThis is a prime number”); else printf(nThis is not a prime number”); ) 7 .用指针写一个删除字符串中空格的函数。 【提示】用指针P1指向待处理的字符串,用*pl从串头到串尾逐一走动,每走到一 个字符判断其是否为空格,若不是空格,则将其保存到指针?2中。 参考代码: #include o void dele(char *str) ( char *pl,*p2; for(pl=p2=str;*pl !=\"\\0\\pl++) if(*pl==,,)continue; else *p2++=*pl; *p2='\\0,; ) main() { char str[100]; gets(str); dele(str); puts(str); ) 8 .用指针写合并两个字符串的函数。 【分析与提示】先将字符串strl从串头到串尾逐一拷贝到字符串str3中,接着将字 符串str2从串头到串尾逐一拷贝到字符串str3中。 参考代码: #inckide o char unitestring(char *strl,char *str2,char *str3) /*合并函数*/ int i=0; while((*str1)!=,\\O\") { *(str3+i)=*strl; i++; strl++; } while((*str2)!=,\\0,) {*(str3+i)=*str2; i++; str2++; ) *(str3+i)=,\\0,; 户不能自动加入\\0*/ ) main() ( char p[50],q[50],r[100]; /*r为连接后的字符串到 printf(HPlease enter the first string:\\nH); gets(p); 借输入字符串*/ printf(HPlease enter the second string:\\nM); gets(q); /*输入字符串*/ unitestring(p,q,r); puts(r); /*输出结果*/ ) 9 .输入15个正整数,放在a数组中,要求:奇数放在a数组前部,偶数放在a数组 后部。再分别对奇数和偶数排序。 【分析与提示】在main函数中将数组中的奇数放在a数组前部,偶数放在a数组后 部。在分别两次调用sort函数将奇数和偶数进行排序。 参考代码: void sort(); main() int a[15]; int i j=14,n=0,t; for(i=0;i<15;i++) scanf(\"%d”,&a[i]); i=0; while(j>=i) if(a[i]%2!=0) {i++;n++;} else {t=a[i];a[i]=aU];aU]=t;j-;) } sort(aji); sort(&a[n],15-n); for(i=0;i<15;i++) printf(\"%3d”,a[i]); printfCVn\"); ) void sort(a,n) int a[]; int n; ( int ij,t; for(j=l;j<=n;j++) for(i=0;i {t=a[i];a[i]=a[i+l];a[i+l]=t;} ) 10 .编写一个程序完成“菜单”功能。提供三种选择途径: ⑴ 求水仙花数(narcissus number),找出100至999之间的所有水仙花数, ⑵ 求出素数(prime number),找出2至n之间的所有素数0 (3)求Faibonacci数列前n项的值。 世include main() { int m, xz; void narcissus(); void prime(); void faibonacci(); clrscr(); m=0; while(m=0) { printf(“\\n\\n\"); printf(u 1 find narcissus numberW'); printf(u 2 find prime numberXn\"); printf(u 3 find Faibonacci number\\nv); printf(u other number exit printf^ input number please!\\n*\"); scanf(\"%d”,&xz); switch(xz) { case 1: narcissus(); break; case 2: prime(); break; case 3: faibonacci(); break; default: m=l; )m=l; ) ) void narcissus() { int k,a,b,c,d; for (k=100: k<1000; k++) { a=k/100; b=k%100/10; c=k%10; d=a*a*a+b*b*b+c*c*c; if(d=k) printf(“%5d\\n'', k); void prime () { int i, j, k, n, m=0; priiitf(uinput n please !\\n'、);scanf(\"%d”, &n); for(i=2; i piintf(“%6d”, i); if(m%10==0) printffM\"); ) void faibonacci() { long fl,⑵ int k, n; printf(uint n please!\\nn); scanf(\"%d\fl=l; f2=l; for (k=l; k<=n/2; k++) { printf(“%8d%8d”, fl, £2); if(k%20) printf(%”); fl=fl+f2; f2=fl+f2; 【提示】程序共有4个函数,其中主函数提供了主菜单,允许选择三种情况之一,否 则就退出。通过开关语句switch进行选择。为了不断的提供菜单,用while来永远循 环。一开始给变量m赋值为0, ni=0就继续循环,一旦选择了不存在的情况,则将m置 1,循环就结束。 补充习题 一.单选题 1 .以下程序的输出结果是( ) fun(int x, int yt int z) { z=x*x+y*y ; } main() { int a=31 ; fun(5, 2, a); printf(H%dH, a); B、 29 D、无定值 【分析与提示】变量作参数时,形参值的改变不会影响实参的值。 【解答】答案:C 2 .当调用函数时,实参是一个数组名,则向函数传送的是( A、数组的长度 B、数组的首地址 C、数组每一个元素的地址 D、数组每个元素中的值 【解答】答案:B 3 .以下程序的输出结果是( int f() {static int i=0 ; )int s=l ; s+=i ; i++ ; return s ; ) main() {int i, a=0 ; for(i=0 ; i<5 ; i++) a+=f(); printf(,'%d\\nH, a); ) A、 20 B、 24 D、15 【分析与提示】自动变量在函数每次调用时,都进行初始化,而静态变量只在编译 【解答】答案:D 4 .以下程序运行后的输出结果是( ) f(int b[ ], int m, int n) {int i, s=0 ; for(i=m ; i C、 25 阶段初始化一次。A、10 B、18 C、8 D、 【分析与提示】数组名作参数时传送的是数组的首地址。 【解答】答案:A 5 .当执行下面的程序时,如果输入ABC,则输出结果是( ) include include main() { char ss[10]=\"l, 2, 3, 4, 5-; gets(ss) ; strcat(ss, \"67\") ; printf(H%s\\n,ll ss); ) A、 ABC67 B、 ABC67 C、 12345ABC6 D、 ABC4567 【分析与提示】注意库函数gets ()、strcat ()的用法。 【解答】答案:A 6 .以下程序运行后的输出结果是( ) void fun(char *c,int d) {*c=*c+l;d=d+l; printf(\"%c,%c,\ ) main() {char a='A\\b='a'; fun(&b,a); printf(\"%c,%c\\n\) A、B, a, B, a B、 a , B, a, B C、 A, b, A, b D、b, B, A, b 【分析与提示】注意指针作参数与普通变量作参数的“值传递, 【解答】答案:D 7 .以下程序运行后的输出结果是( void sort(int a[],int n) { int ijj; for(i=0;i {int aa[10]={l,2,3,4,5,6,7,8,9,10|,i; sort(&aa[3],5); for(i=0;i<10;i++) printf(\"%d,';aa[i]); printf(\"\\n\"); ) A、1, 2, 3, 4, 5, 6, 7, 8, 9, 10, B、10, 9, 8, 7, 6, 5, 4, 3, 2, 1, C、 1, 2, 3, 8, 7, 6, 5, 4, 9, 10, D、1, 2, 10, 9, 8, 7, 6, 5, 4, 3, 【分析与提示】注意实参的“值,【解答】答案:C 8 .以下程序运行后的输出结果是( int f(int n) {if(n==l ) return 1; else return f(n-l)+l; ) main() {int i,j=0; for(i=l;i<3;i++) j+=f(i); printf(n%d\\nnJ); I A、4 B、3 C、2 D、1 【分析与提示】本题为递归调用。【解答】答案:B 二,运行程序写结果 9 .下列程序运行的运行结果为 o include \"\" main() ) ( int i,num; for(i=0;i<3;i++) {num=2; printf(H\\n The num equal : %d \\rT,num); nuni++; ( static int num=l; printf(H\\nThe internal block num equal : %d\\nn,num); num++; ) ) ) 【分析与提示】注意static的用法。 【解答】The num equal : 2 The internal block num equal : 1 The num equal : 2 The internal block num equal : 2 The num equal : 2 The internal block num equal : 3 10 下列程序运行的运行结果为。 include \"\" int a,b,c; void add() {extern int a; c=a+b; } void main() { a=b=4; add。; printf(HThe value of c is equal to %d\\ii'\\c); 【分析与提示】注意xtemal的用法。 【解答】The value of c is equal to 8 11 下列程序运行的运行结果为 o void swap(int *a,int *b) {int *t; t=a;a=b:b=t; ) main() {int x=3,y=5,*p=&x,*q=&y; swap(p.q); printf(\"%3d%3d\\n”,*p,*q); ) 【分析与提示】指针作参数时,形参指针的改变不会影响实参。 【解答】3 5 三.改错题 12 下列给定程序中,函数fun的功能是计算正整数num的各位上的数字之平 方和。 例如,输入352,则输出应该是38;若输入328,则输出应该是77。 请改正程序中的错误,使它能得出正确的结果。 注意,不要改动main函数,不得增行或删行,也不得更改程序的结构。两 处错误分别在/**********found************/的下一行。 程序代码: #include o #include o long fun(long num) { /不不不不不不不不不不fou nd不不不不不不不不不不不不/ long k=l; do k+=(num% 10)*(num% 10); num/=10; /不不不不不不不不不不不fou nd不不不不不不不不不不不/ }while(num) return(k); ) niain() ( long n; clrscr(); printf(n\\n Please enter a number:H); scanf(\"%ld\ printf(\"\\n %ld\\n\) 【分析】错误1: k用来存放各位数字的平方和,初值应为0。错误2:语法 错误。 【解答】 ⑴ long k=0; (2) while(num); 13 下列给定程序中,函数fun的功能是:在字符串str中找出ASCII码值最 大的字符, 将其放在第一个位置上;并将该字符前的原字符向后顺序移动。 例如,调用fun函数之前给字符串输入:ABCDeFGH,调用后字符串中的内容 为:eABCDFGH 请改正程序中的错误,使它能得出正确的结果。 注意,不要改动main函数,不得增行或删行,也不得更改程序的结构。两 处错误分别在/**********found************/的下一行。 参考代码: #include<> void fun(char *p) { char max,*q; int i=0; max=p[i]; while(p[i]!=0) max=p[i]; /字不不不不不不不不不fou nd不不不不不不不不不不不不/ p=q+i; } i++; ) /*不不不不不不*不不不fou nd^^*不不不不不不不不/ while(q *q=*(q-i); q--; ) p[0]=max; } void main() ( char str[8O]; printf(nenter a string:n); gets(str); printf(n\\nthe original string:M); puts(str); fun(str); printf(n\\nthe string after moving:H); puts(str); ) 【分析与提示】本例考查指针指向字符串的操作。第一个错误出在P二q+i;这 一行,经过观察发现,Q是没有赋初值的指针,这样的指针指向不明确,是野指 针,所以必须给q赋初值,这一语句更改为q=p+i;就对了,作用是把q定位在字 符e所在的位置。因此在程序中,q的作用总是指向当前最大的字符。第二个错 误比较隐蔽,单从语法上检查不出来,但是分析程序的作用后可发现P是数组的 首地址,所以它总是小于或等于 Q的,而第二个while循环的作用是把e前面的 字符顺次往后挪动,所以,这里的循环条 件应该是q>P。 【解答】(l)q=p+i; 四.编程题 1 .已知e=l+l/l!+l/2!+l/3!+…+l/n!,试用公式求e的近似值,要求累加 所有不小于10-(2) while (q>p) 的项值。用函数fun完成任何数的阶乘。 【分析与提示】用主函数完成1与1/1!到1/n!的相加,直到1/n!的值小于 10\\通过形参传递给子函数fun,用1X2X3X…Xn求n的阶乘。 参考代码: #include o int fun(); main() { int i; float e ,n; e=; i二l; n=; while (n> {n=fun(i); i++; e=e+n ; ) printf(H%An\\e); I int fun( int i) { intj,k; k=l; for (j=l;j<=i ;j++) k=k*j; return(k); ) 输出结果: 2 .请编写函数fun(),该函数的功能是:将两个两位的正整数a,b合并形成一个整 数 放在c中。合并的方式是:将a数的十位和个位数依次放在c数的十位和千位上,b 数的十位和个位数依次放在c数的百位和个位上。 例如,当a=45, b=12时,调用到该函数后,c=51420 注意:部分源程序给出如下。请勿改动主函数main和其他函数中的任何内容,仅 在函数fun的花括号中添入所编写的若干语句。 部分源程序: #inckide o #inckide o void fun(int ajnt bjong *c) ( *c=a% 10*1000+b/10*100+a/10*l 0+b% 10; } main() {int a,b; long c; clrscr(); printf(HInput a,b:H); scanf(\"%d%d'\\&a,&b); fun(a,b,&c); printf(HThe result is :%ld\\n\) 3 .请编写函数fun(),该函数的功能是:将s所指字符串中ASCII码值为偶数的字 符 删除,串中剩余字符形成一个新串放在t所指的数组中 例如,若s所指字符串中的内容为ABCDEFG12345,最后t所指的数组中的内容应 是 ACEG135。 注意:部分源程序给出如下。请勿改动主函数main和其他函数中的任何内容,仅 在函数fun的花括号中添入所编写的若干语句。 部分源程序: #include o #include o #include o void fun(char *s,char t[]) ) main() ( char s[100],t[100]; clrscr(); printf(H\\n lease enter string s:H); scanf(,,%s,\\s); fun(s,t); printf(H\\nThe result is :%s\\nH,t); ) 参考代码: int i=0; for(;*s!=\\0,;s++) if(*s%2==l) t[i++]=*s; t[i]='\\O'; 4 . Hanoi汉诺塔问题。 【分析】这是一个典型的用递归方法解决的问题。问题是这样的:有三根针A、 B、C, A针上有个盘子,盘子大小不等,大的在下,小的在上。要求把这个盘子 从A针移到C针,在移动的过程中可以借助B针,每次只允许移动一个盘子,而且在 移动 过程中三根针上都保持大盘在下,小盘在上。编写程序并打印出移动的步骤。 将n个盘子从A针移到C针可以分解为以下三个步骤: ①将A上n-1个盘子借助C针先移到B针上。 ②把A针上剩余的一个盘子移到C针上。 ③将n-1个盘子从B针借助A针移到C盘上。 例如:要想将A针上的3个盘子移到C针上,可以分解为以下三步: ①将A针上的2个盘子移到B针上(借助C针)。 ②将A针上的一个盘子移到C针上。 ③将B针上的2个盘子移到C针上(借助A针)。 其中第②步可直接实现。 第①步又可以用递归方法分解为: a、将A上一个盘子从A移到C。 b、将A上一个盘子从A移到B。 C、将c上一个盘子从C移到B。 第③步可以分解为: a、将B上一个盘子从B移到A上。 b、将B上一个盘子从B移到C上。 c、将A上一个盘子从A移到C上。 将以上综合起来,可以得到移动的步骤为: —► ■, ► -► —> —► ..... > ' ► A C, A B, C B, A C, B A, B C, A C 上面第①步和第③步,都是把n-1个盘子从一个针移到另一个针上,采用的方法是 一样的,只是针的名字不同而已。为使之一般化,可以将①步和③步表示为: 将“one:\"针上的n-1个盘子移到“two”针上,借助“three”针。 只是在①步和第③步中,one、two、three和A、B、C的对应关系不同。对于第 ① 步,对应关系是:one—A, two―B, three—C对于第③步,对应关系是:one—— B、two—C three— o s Ao因此,可以将上面三个步骤分成两类操作: 第一类:将n-1个盘子从一个针移到另一个针上(n>l)。这是一个递归过程。 第二类:将1个盘子从一个针上移到另一个针上。 下面编写程序,分别用两个函数实现以上两类操作,用hanoi函数实现第一类操 作,用move函数实现上述第二类操作。hanoi(n,one,two,three)表示将n个盘子从“one”针 移动至lj\"three”针,借助“twe”针,move(getone,putone)表示一个盘子从“getone”针移动到 “putone”针。getone和putone也是代表A、B、C针之一,根据每次不同情况分别去A、 B、C代入。 程序如下: void move(char getone, char putone) printf(M%c---> %c\\n\",getone, putone); 1 void hanoi(int n, char one, char two, char three ) /*将n个盘子从one借助two,移到three*/ { if ( n=l) move(oneJhree); else { hanoi(n-l, one, threejwo); move(one, three); hanoi( n-1, two, one, three); 1 ) main() { int m; printf(Hinput the number of the diskes scanf(H%d'\\&m); printf(Mthe step to move %3d diskes :\\n' m); hanoi(m, W, 'B' C); ) 程序运行结果如下: Input the number of diskes: 3 The step to move 3 diskes: A——C A——B C—B A——C B----A B—C A----C 第8章结构体与共用体 一・简答题 5 .结构体类型与以前的标准数据类型有什么区别 【解答】 (1)结构体类型是一种构造出来的数据类型。它具体代表多少成员还需要由用户 定 义。基本类型不需要用户定义而可以直接使用,而结构体类型必须先定义类型再使 用。 (2)结构体类型是复合数据类型,可简单,也可复杂,而简单数据类型则比较单 纯。 (3)用简单类型定义的变量一般都可直接参与多种运算,而结构体变量则往往只 能 对其成员进行多种运算,对整个结构体变量适用的运算很少。 6 .结构体类型与共用体类型有什么异同 【解答】 (1)结构体和共同体都是构造数据类型,使用它们都可存储多种类型的数据,可 以 方便地组织不同类型的数据。 (2)结构体占用的空间是所有成员所占用空间的和,而共用体则是最大成员所占 据 的空间。结构体重在组织多种类型的数据,从而构造一个复杂的数据类型,而共用体 重在强调内存的共享与重复使用。 3• 枚举类型适用于什么场合 【解答】枚举类型用于程序中某个项目的所有可能选项是固定的,单一的表达场合 时。 4 .动态存储分配有什么作用 【解答】使用动态存储分配内存空间,可以让程序适应用户对内存变化的需要,及 事先不能确定内存用量的场合。它以小的牺牲(定义的指针也占用空间)换来了内存使 用效率的提高。 5 .类型定义有什么意义 【解答】所谓类型定义,并不是定义了一种新类型,而是为了书写方便或使程序易 于阅读,由程序员规定的一种已有类型的新名称而已。 二.运行程序写结果 L以下程序的执行结果是 #include o struct studinf) char*name; float grad; }*p; main() ( struct studinf a; p=&a; p->grad=; p->name=(char*)malloc(20); strcpy(p->nanie, nwang pi\"); printf(H%s\%2f\\n,\\ p->name, p->grad); ) 【分析与提示】本题旨在检查读者通过指针访问结构体变量的能力。同时,练习指 向运算符的用法、动态分配的使用,及结构体中指针成员的使用方法。 【解答】wang pi 2.以下程序的执行结果是 ______ : #inckide o typedef stnict month { char month[12]; int days; } DATE; DATE monthtab[]={,'January\31, \"April”,30, \"May\30, \"July”,31, “August”,31, \"September”,30, \"October”,31, “November”,30, \"December”, 31}; main() { int i; for(i=0;i<12:i++) printf(n%-10s%2d\\n'\\ monthtabfi].month, monthtab[i].days); ) 【分析与提示】本题意在练习比较复杂的类型定义的用法,所以,重点放在定义形 式上。 【解答】运行结果如下: January 31 February 28 March 31 April 30 May June 30 31 July 31 August 31 September 30 October 31 November 30 December 31 3.以下程序的执行结果是 #include o struct test {char x,y; }; union exec {int a; char b,c; struct test d; longe;}; main() union exec var; printf(H\\nSize of union exec = %d bytes.H,sizeof(union exec)); printf(H\\nSize of variable var = %d bytes.H,sizeof(var)); 二2345; printf(n\\nAddress of is %p, printf(H\\nAddress of is %p, printf(H\\nAddress of is %p, %#x:&,; printf(H\\nAddress of is %p, printf(n\\nAddress of is %p, %#x.”,&,; ) 【分析与提示】本题设计的目的是考查读者对结构体和共用体混合使用的认识与 理 解。通过运行程序,查看结果,并比较源程序进行分析,可加强读者对结构体和共用体 的认识。提醒读者注意:2345存储在计算机内是2进制数,表示成16进制是0x929。 存储时先存储的是低字节0x29,然后是高字节0x9。 Size of union exec = 4 bytes. Address of Address of Address of 【解答】某次运行的结果如 下: FFD6, 0x929. FFD6, 0x29. Size of variable var = 4 bytes. FFD6, 0x29. Address of is FFD6, 0x929. Address of is FFD6, 0x29. Address of is FFD7, 0x9. Address of is FFD6, 0x929. 4.以下程序的执行结果是 ______ o #include o enuni prov{Beijing, Tianjin, Shanghai, Chongqing, Liaoning=5, Heilongjiang, Jilin, Shandong=10, Hebei, Henan(addr; main() { enum prov addr; printf(n\\nBeijing=%d,Tianjin=%d,Shanghai=%d/\\Beijing,Tianjin,Shanghai); printf(nChongqing=%d,Liaoning=%d,Heilongjiang=%d/\\Chongqing,Liaoning,Heilongjia ng); printf(\"Jilin=%d,Shandong=%d,Hebei=%d,Henan=%d.\\n”,Jilin,Shandong,Hebei,Henan); addr=Shanghai; addr++; printf(H\\nAddress is %d.\\nM,addr); } 【提示】本题意在熟练读者对枚举类型的认识与使用:如何定义一个枚举类型;如 何定义枚举变量;如何在程序中赋值、运算等。特别要指出的是,最后一行的输出只是 一个代表本枚举变量的一个整数,而不少初学者往往误认为的是一个字符串 (Chongqing)。 【解答】 Beijing=0. Tianjin=L Shanghai=2, Chongqing=3, Liaoning=5, Heilongjiang=6, Jilin=7, Shandong=10, Hebei=I L Henan= 12 Address is 3. 三.编程题 1 .编写一程序,定义一个点的坐标。然后定义两个点,求这两个点间的距 离。 【提示】本题属于结构体的简单应用。主要练习如何使用结构体变量的成员 参与 运算等问题。 参考代码: #include o #include o struct point {int x,y; }; main() struct point pl,p2; float dist; /*定义两个点*/ printf(\"\\nPlease input the first pointVs value:\\nx=\"); scanf(\"%d\ printf(\"y=\");scanf(\"%d\ /*输入第一个点*/ printf(\"\\nPlease input the second point's value:\\nx=\");/*输入第二个点*/ scanf(\"%d\ printf(“y=\");scanf(”%d”,&: dist=sqrt( );/*计算两点距离*/ printf(\"Distance of two point is %.\\n\2 .请编写程序:将下表数据赋给结构体数组,并按照年龄从小到大顺序将它们 输出 到屏幕上。 姓名 zhangsan lisi wangwu 年龄 38 22 24 年薪 28000 22000 27000 【分析与提示】本题旨在练习结构体数组的定义、初始化及应用。对结构体 数组中的内容进行排序有多种办法,鉴于本题数据较少,参考程序中使用了最原 始的排序方法。 参考代码: #inckide o struct emp ( char name[20]; int age; long yearsal; }; main() struct emp data[3]={ {\"zhangsan”,38,28000}, {\"lisi\{\"wangwu\ int i; if (data[0].age>data[ 1 ].age) /*比较前两个的年龄,并在可能时交换位置*/ {tnip=data[0];data[0]=data[ 1 ];data[ 1 ]=tnip:) if(data[l].age>data[2].age) /*比较后两个的年龄,并在可能时交换位置*/ {tmp=data[ 1 ] ;data[ 1 ]=data[2] ;data[2]=tmp;} if (data[0].age>data[ 1 J.age) 产再次比较前两个的年龄,并在可能时交换位置*/ {tmp=data[0] ;data[0]=data[ 1 ] ;data[ 1 ]=tmp;) printf(”\\n%20s%4s%9s”,“Name”,“Age”, “Income”); for (i=0;i<3;i++) /*输出结果*/ printf(n\\n%20s,%3d5%81d'\\data[i].nameJata[i].age,data[i].yearsal); ) 3 .请利用教材中有关单向链表的例子,建立一个反向的链表。 【分析与提示】本题是一个非常常见的应用。其中涉及的到知识点有:建立 单向链 表、输出单向链表中的数据、链表的反序。其中链表的反序是教材中没有 涉及到的内容。下面的代码采用的算法是:从后向前建立链表。这也是另一种建 立链表的方法。教材中建立链表时,只要有一个结点存在,则表头地址就固定 了,以后就在链表尾部添加新结点。而反序时首先建立的尾部结点,以后有新结 点时,不断添加到其前面,即表头指针不断变化,直到无新结点时为止。此时的 首地址就是链表的头地址。 参考代码: #include o typedef struct site {int num; struct site *next; } SITE; main() SITE *headl,*head2,*pl,*p; head l=head2=NULL; while (1) /*建立一个链表,表头是headl */ ( p=(SITE *)malloc(sizeof(SITE)); if (!p) {printf(u\\nAllocate memory error!\\nM);exit(l);) printf(H\\nPlease input data of per site(O=end):\\nH); scanf(n%d,\\&p->num); if (!p->num) break; /*如果输入数为0,则结束*/ else { p->next=NULL; if (!headl) headl=p; else /次如果首指针为空,则为其赋值*/ /次如果不是首指针,添加到表的结尾*/ {p 1 =head 1 ;while(pl->next) pl=pl ->next;p 1 ->next=p;} ) ) free(p); /*释放最后一个无效的结点*/ printf(\"\\nThe original table is:\\n\"); p 1 =head 1; while (pl->num){printf(,,%8d,\\pl->num);p l=p 1 ->next;) printfCVn\"); pl=headl; /*表头是head 1的链表反序*/ while(pl) ( p=pl; /* 输出表头是 headl 的链表 */ /*暂存首结点后,并指向下一结点*/ pl=pl->next; if(!head2) /*如果新链表不存在,则为头指针赋值*/ {p->next=NULL;head2=p;} else /*如果新链表已经存在,则把结点添加到其首部*/ {p\">next=head2;head2=p;) ) printf(\"\\nThe new table is:\\»\"); /* 输出反序后的链表,表头是 head2 */ pl=head2; while (pl->num){printf(H%8d'\\p 1 ->num);pl=p 1 ->next;) printf(H\\nM); pl=head2; 产释放链表占用的空间*/ while(p 1)( p=p 1 ;p 1 =p 1 ->next;free(p);} ) 4 .假设有N个学生,每个学生的数据包括学号、姓名及三科成绩。要求从 键盘输 入各学生的数据,最后输出三科的总平均成绩及最高分学生的情况。 【分析与提示】本题是很多教材上选用的例题或习题。但算法却不尽相同。 他们采用的做法一般是先输入所有学生的信息,再计算,最后再输出满足条件的 记录。其实,在一个学生的信息输入完后,就已经可以计算其总分和平均分了, 而且还可以对平均分进行累计。下面的参考代码就采取这种一次性的处理方式, 这样可以大大提高程序运行 效率。另外,输出最高分学生的详细情况部分,我们 也要考虑到,这样的学生可能不只一个!所以,要在知道最高平均分的情况下, 再逐个搜索的方式进行,这样才比较完美。 参考代码: #include o #inckide o #define N 5 struct student ( long studno; char name[20]; float score[4]; )stud[N]; main() ( int i,j; float average=O,sum,maxave=O,temp; for (i=O;i printf(\"Student name:\");gets(stud[i].name); sum=O; for (j=O;j〈3;j++) { printf(HStudent score[%d]=n,j+1); scanf(n%f\\&temp); stud[i].score [j ] =temp; sum+=temp; I stud[i].score[j] =sum/3; average+=stud[i].score[j]; /*三科成绩及平均成绩*/ /*输入各学生的数据*/ /*保存每个学生总分的变量清0 */ /*输入的同时直接计算平均值并保存*/ /*保存每个人的平均分*/ /*累计所有人平均分之和*/ maxave=(stud[i].score[j]>maxave)stud[i].score[j]:rnaxave;/* 求最大平均分 */ ) average/=N; /*计算并输出所有学生全部课程的平均分*/ printf(H\\nThe average of %d studentsV is %\\n'\\N,average); printf(M\\nThe best student(sV) list:\\n%student no student name score3 sum aver\"); for (i=O;i /*输出所有平均分最高学生的完整信息*/ { if (fabs(maxave-stud[i].score[3])< 1 e-6) /* 只输出平均分最高的学生信息*/ ( printf(\"\\n%101d %-20s\for (j=O;j<3;j++) printf(\" %\printf(\" % %\) } } 第9章文件 一・简答题 i .什么是文件 【解答】文件是指存储在外部介质上的数据集合。一般分为程序文件和数据文件。 2 . C语言可以处理的文件类型是什么 【解答】顺序存取和随机存取文件。 3 . C语言文件的存取方式是什么 【解答】文本文件和二进制文件 4 .在C语言中,文件存取是以什么为单位的,这种文件是什么 【解答】字符,流式文件 5 .函数rewind。的作用是什么 【解答】使位置指针重新返回文件的开头 二.编程题 1 .将从键盘输入的数据存储到文件中,再将存储的文件内容在屏幕上显示(用 fputc(), fgetc()函数)。 【分析与提示】先以写的方式打开文件,运用fputc( )函数把键盘录入的数据写到文 件中;再以读的方式打开文件,运用fgetc()函数从文件中读取数据显示在屏幕上。 参考代码: include \"\" void write」。。 { FILE *fp; char ch; fp=fopen(\"we'\\\"wb\"); if (fp==NULL) {printf(ncannot open fileH);exit(O);) ch=getchar(); while (ch!=,\\n,) {fputc(ch,fp); ch=getchar();} fclose(fp); ) /*将刚才存储的文件在屏幕上显示函数。 void read_in() ( FILE *fp; char ch; fp=fopenC'we\if(fp==NULL) {printf(Hcannot open file\");exit(O);) while(!feof(fp)) {ch=fgetc(fp);putchar(ch);) } void main() { write_to(); read_in(); } 2 .编程实现两个文件中的内容合并到一个文件中,并显示出来。 #inckide<> main() { FILE *fpl,*fp2; char s[100]; if((fp 1 =fopen(u\uab\"))==NULL)尸以追加方式打开二进制文件al*/ printf(H\\nCan not open file !\"); else if((fp2=fopen(ll\llrbB))==NULL) /* 以只读方式打开二进制文件 a2*/ printf(H\\nFile has not been found !H); else while(fgets(s,l 00,fp2) !=NULL) fputs(s,fpl); /*读取文件a2中的内容,追加方式写到文件al原有内容后面\" fclose(fpl); fclose(fp2); /*关闭al和a2文件,防止数据丢失*/ if((fp 1 =fopen(Ma 1 \\Mrb\"))==NULL) printf(u\\nFile has not been found!\"); else /*以只读方式打开二进制文件 al*/ while(fgets(s, 1 OO,fp 1)! =NULL)尸在屏荒上显示合并后存储在al中的文件内容*/ printf(\"\\n%s”,s); fclose(fpl); ) 3 .编程:从键盘输入一行字符,把它们存入一个磁盘文件中,然后再从该文件 中读出. 并在屏幕上以大写方式显示出来。 #include o main() { int i,flag; char str[80],c; FILE *fp; fp=fopen(Htext,\\',w+H); for(flag=l;flag;) { printf(”\\n请输入字符串:\\n\"); gets(str); fpri nt f(fp,u % sstr); f!ag=O; } fseek(fpAO); while(fscanf(fp,\"%s';str)!=EOF) { for(i=0;str[i]!='\\0';i++) if((str[i]>=a,)&&(str[i]<=z,)) str[i]-=32; printf(\"\\ii%s\\n\) fclose(fp); ) 运行结果:请输入字符串: I am a student / I AM A STUDENT 4 .从键盘输入10个整数保存到文件中,再把文件中的10个整数读出,并显示出 来。 【分析与提示】先以写的方式打开文件,运用fwrite()函数把键盘录入的数据写到文 件中;再以读的方式打开文件,运用fread。函数从文件中读取数据显示在屏幕上。 参考代码: # includeo # define N 10 main() ( FILE *fp; int data[N]j; printf(\"输入 10 个数:”); for(i=0:i printf(HFile has not been found!M); else {fread(data,2,N,fp); fclose(fp);} for(i=0;i 【分析与提示】运用fscanf()和fprintf()函数实现文件中信息复制。 参考代码: #include<> main() ( FILE *fpl,*fp2; char s[100]; if((fpl=fopen(\"\,,))==NULL) printf(n\\nFile has not been found!H); else fscanf(fpl/,%s,\\s); fclose(fpl); if((fp2=fopen(\"a2\n))==NULL) printf(H\\nFile has not been found!H); else {fprintf(fp2,,,%s\ ) 6 .有4个学生,每个学生有5门课的成绩,从键盘输入数据(包括学生学号,姓 名,5门课成绩),计算出平均成绩,将原有数据和计算出的平均分数存放在磁盘文件 “B2” 中。 【分析与提示】运用结构体数据类型存储学生成绩信息。 参考代码: # inckideo struct student ( char num[10]; char name[8]; int score[5]; float ave; )stu[4]; main() ( int ij,sum; FILE *fp; for(i=0;i<4;i++) { printf(H\\ninput score of student %d”,i+l); printf(HnoH); scanf(,,%s,1,stu[i].num); printf(Hname:\"); scanf(H%s'\\stu[i].name); sum=0; for(j=0;j<5;j++) ( printf(nscore %d'\\j+l); scanf(H%d'\\&stu[il.score[j]); sum=sum+ stu[i].score[j]; ) stu[i].ave=sum/; ) fp=fopen(,,B2H;,wH); for(i=0;i<4;i++) if(fwrite(&stu[ i],sizeof(stnjct student)[,fp)!=l) printf(nfile write error!”); fclose(fp); fp=fopen(',B2\''); for(i=0;i<4;i++) ( fread(&stu[i],sizeof(struct student)J,fp); printf(n%s,%s,\\stu[i].num, stu[i].name); for(i=0;i<5;i++) printf(\"%d\printf(n%f\\stu[i].ave); } ) 7.统计文件中的单词个数。 【分析与提示】以空格、换行、回车符为标志判断是否为一个单词。 参考代码: #include o niain(int argc,char*argv[]) FILE *fp; char ch; int white=l; int count=0; if((fp=fopen(argv[ 1 ]/,f'))==NULL) ( J printf(Hcanrt open file%s. H,argv[l]); exit(O); ) while((ch=fgetc(fp)) !=EOF) switch(ch) ( case ' case '\': case '\\n': white++; break; default: if(white) {white=0; count++;} ) fclose(fp); printf(nfile,%s,contains%d words. '\\argv[ 1],count); ) 说明: (1)一般情况下,程序中的主函数不带形参,该程序中使用了带形参的主函数,目的 是为了在执行程序时,我们可以带参数,假设该程序名为countw,而要统计单词的文件 名为word,要想用该程序统计word中单词的个数,可以将该程序编译形成可执行文件 countw,在DOS方式执行:countw word.,这样编程的好处是可以用countw统计任一个 文件中单 词的个数,只要执行程序时,加带被统计文件的文件名即可。 (2)主函数形参中的argc,用于统计执行程序时,命令行参数的个数,而*argv 口 是具 体的命令行参数,例如:执行countw word.时,argc=2, argv [0]为countw即程序 本身,而 argv [1]为 word。 第10章图形与动画 一・简答题 1 .文本模式下的窗口有什么特点 【解答】文本模式下的窗口与目前我们所使用的Windows下的窗口有很大的不同: 文本下的窗口大小只能以字符为单位设置,看起来跳跃性大;文本下的窗口没有边框、 滚动条等可视元素,只有在操作时才能感觉边界的存在;文本下的窗口由于显示驱动程 序,可支持的颜色数较少,不可能达到很好的色彩过渡等效果;文本方式下的窗口 也不可移动,扩张大小等。 2 .请解释图形模式与文本模式。 【解答】图形模式与文本模式是计算机的显示系统工作的两种不同的工作方式。在 文本方式下,整个屏幕被格式化成一个个矩形块,每个矩形块内只能显示一个字符。无 论是编辑还是存储,都以字符为单位,以ASCII码为存储形式。而图形工作方式则以像 素点为单位,每个像素点都可控制显示内容。因此,图形方式显示能力比较强,内 容丰富,层次较多。但处理速度比不上文本方式。 3 .图形和文本模式下输出文本有什么异同 【解答】文本模式下输出的文本默认采用系统默认的一种字体,输出时可用的坐标 范围受显示模式的,比较有限。图形方式下输出的文本可采用多种字体和大小,且 输出点坐标控制相对灵活,但控制相对于文本方式比较繁琐。 二.运行程序写结果 ______________ 1 .以下程序的执行结果是一o #include o #include<> main() int graphdriver=VGA; /*设置成 VGA 模式*/ int graphmode=VGAHI: H . H /*采用 0*480 高分辨率显示模 1 initgraph(&graphdriver5 &graphmode, ,M,); cleardevice(); rectangle( 100, 20, 150, 50); /*画矩形图*/ bar(100, 80, 200, 260); getch(); closegraph(); /*画画条形图*/ 【分析与提示】本题是图形部分的基础练习题,主要用来让读者进 -步熟悉图形编程的步骤及相关语句。包括设置图形工作模式、初始化 显示方式、关闭图形系统的方法等。 【解答】运行结果如图10-1所示。 2 .以下程序的执行结果是 ______ o 图10- #include o #include<> main() { int graphdriver=DETECT, graphmode, x; initgraph(&graphdriver, &graphmode, nn); cleardevice(); ellipse(320, 100, 0, 360, 75, 50); circle(320, 220, 50); pieslice(320, 340, 30, 150, 50); ellipse(320, 400, 180, 360, 50, 50); getch(); closegraph(); } 【分析与提示】本题也是一个基础练习题,用来让读者了解自动检测(DETECT) 法。同时也包括画圆、椭圆,饼图等基础函数的应用内容。 【解答】运行结果如图10-2所示。 3 .以下程序的执行结果是 ______ o include \"\" main() {int driverjnode; drivei-DETECT; mode=2; initgraph(&drivei;&mode/M,); cleardevice(); setbkcolor(l); /* 背景为兰色*/ 的用setcolor(15); /*前景为白色”/ eHipse(300,200,0,360,80,40); /*画椭圆弧线 */ setfillstyle(l,4); 尸填充模式1实填充,4红色*/ /*300, 200为图形的任意点,边界颜色为白色*/ floodfill(300,200,15); getch(); closegraph(); ) 【提示】本题是一个练习用填充函数,画椭圆实填充。请观察背景色、填充色及图 案边界颜色。 【解答】运行结果如图10-3所示。 4 .以下程序的执行结果是 ______ #includeo main() { int i,gd.gm; gd=VGA; gm=VGAHI; initgraph(&gd,&gm,,H,); for(i=0;i getch(); closegraph(); ) movebar(int x) { setviewport(x,0,639.199J); setcolor(5); bar3d(10,120,60,150,40,1); floodfill(70J30,5); noodfill(30J10,5); deIay(60000); clearviewport(); 图 10-4 【提示】本题是一个移动方块的简单动画程序,练习通过设置视图区操作实 现动画效果。 思考:可实验验证一下,不使用clearviewport ()的情况,观察运行结果。 【解答】运行结果如图10-4所示。 三.编程题 1 .编写程序,实现亮条式菜单的功能(类似Turbo C的某个子菜单)。 【分析与提示】亮条式菜单在 DOS 环境下应用非常广泛,在 Windows 下的下 拉菜单 也属此形式。这种菜单要解决下面几个问题: (1)菜单的显示分为正常显示和反显两个状态,通用要用颜色来区分; (2)在菜单项间移动时,要不断改变当前项的状态。即刚才选中的项要恢 复成正 常显示状态,新选择的项要变成选中状态,以模拟亮条的功能。 (3)菜单中要用到不少热键、快捷键等,都需要在选中某项菜单的情况下 进行处 理。 下面提供的参考代码采用了模块化的程序设计思想。当然,限于篇幅,某些 方面也进行了删减。 参考代码: #include o #include o #inckide o #define Key.DOWN #define KeyJJP #define Key.LEFT #define Key.RIGHT #define Key_ENTER #define Key_ALT_X 0x5000 0x4800 0x4b00 0x4d00 OxlcOd 0x2d00 /*定义一组键*/ void box(int stxjnt styjnt endxjnt endy); /* 显示一个菜单框 */ void dispitem(char *s,int normal); /*显示一个菜单项*/ /* 显示菜单 */ void dispwin(char *menu[], int pos); main() ( int key,pos=0; /* 键值 */ char *menu[] ={/* 定义菜单项 */, \"Load F3 \\"Write to \"Directory\u;'OS shell”,“Quit Alt-X \"); textbackground(B LACK); textcolor(WHITE); clrscr(); dispwin(nienu, pos); while(l) ( key=bioskey(0); switch(key) { case Key_ALT_X: /*如果是退出键,则结束程序*/ exit(O); case Key_UP: case Key_LEFT: /*向左及向上方向键,用于选择上一条菜单*/ pos-; if (pos=-1) pos=8; /*如果已经在第一菜单项上,上移时移到最后一项*/ dispwin(nienu.pos);break; case Key_DOWN: case Key_RIGHT: /*向下及向右方向键,用于选择上一条菜单*/ pos++; if (pos=9) pos=0; dispwin(nienu.pos); break; case Key_ENTER: /*回车键执行菜单功能*/ if(pos==8) exit(O);/*选中第1菜单的第9项,退出*/ break; ) /*如果已经在最后一菜单项上,下移时移到第一项*/ 1 } void box(int stxjnt sty,int endxjnt endy) ( int i; textbackground(LIGHTGRAY);textcolor(BLACK); gotoxy(stx,sty); putch(Oxda); /* 画「*/ for (i=stx+l ;i gotoxy(stx,endy); putch(OxcO); /* 画 L */ for (i=stx+l ;i textbackground(LIGHTGRAY);textcolor(BLACK); cprintf(\" \"); /*黑色显示一前导空格*/ textcolor(RED); cprintf(n%cf\\*s); /* 以红色显示首字符*/ textcolor(BLACK); cprintf(\"%s\以黑色显示其它字符*/ ) else {textbackground(BLACK); textcolor(WHITE); cprintf(H %sM,s); /* 加黑显示当前项 */ ) ) void dispwin(char *menu[], int pos) ( int i, lx=20Jy=5,rx=35,ry=15; box(lx,ly,rx,ry); /* 调用作框函数 */ for(i=0;i<9;i++) /*显示子菜单各项*/ { gotoxy(lx+1 ,ly+i+1); dispitem(menu[i], 1); } gotoxy(lx+1 Jy+pos+1); dispitem(menu[pos],0); } /* 画」*/ 2 .画出5个不同颜色的环组成一个奥运标志。 【分析与提示】奥运五环标志看起来比较简单,但用C做起来还是需要费点 时间的。需要解决的问题主要是各环的色彩及环之间的交叉问题。C的填充是以 边界的颜色为标志的。因此,需要在颜色方面做文章。下面的参考代码中使用了 比较笨的方法,用黑色的矩形框打破交叉形成的连接边界。当然,这种填充方式 并不完美,读者可以想出更好的办法来。 参考代码: #inckide o void doublecircle(int x,int y); /*画两个同心圆,参数为圆心坐标*/ main() { int gdriver= VGA,gmode= VGAHI, i; initgraph(&gdriver,&gmode/M,); cleardevice(); setcolor(8); doublecircle(220,200); /* 画 5 个环 */ doublecircle(300,200); doublecircle(380,200); doublecircle(2605235); doublecircle(340,235); setcolor(0);rectangle(252,198,254,207);/*以黑色边框画一个矩形的目的是为了突破两 个 环交叉的部分,使下面的填充到位,下面的矩形作用与此相同*/ setfillstyle(l,9);floodfill(l85,200,8); /* 以蓝色填充 */ setcolor(O); rectangle(332J 98,335,207); rectangle(290,231,297,233); setfillstyle(l,6); floodfill(300,165,8); floodfill(297,233,8); /* 以紫色填充 */ setcolor(O); rectangle(370,231,382,233); setfillstyle(l,4); floodfill(380,165,8); /* 以红色填充 */ setcolor(O); rectangle(225,230,228,237); rectangle(260,201,272,202); setfillstyle(l,14); floodfill(260,270,8); floodfill(272,202,8); /* 以黄色填充 */ setcolor(O); rectangle(3O5,227,307,237); rectangle(340,201,353,203); setfillstyle(l,2); floodfill(340,270,8); floodfill(353,203,8); /* 以绿色填充 */ getch(); closegraph(); } void doublecircle(int x, int y) { circle(x,y,30); circle(x,y,37);) 3 .用实心球实现例的功能。 【分析与提示】本题与例类似,只是以实心球代替了原来的圆,因此不再重 复。 参考代码: include o #inckide o #inckide o void main() ( int driver=VGA, mode=VGAHI, i; initgraph(&driver,&mode/M,); line(0,330,639,330); 小画水平线和斜线,表示一个平面*/ for (i=8;i<=632;i+=8) {line(i,330,i-4,340); } setfillstyle(l,15); for (i=l;i<=18;i++) /*分段画出一个正椭圆球*/ {sector(320,50,(i-1 )*20,i*20+2,30,30); de!ay(40000); } for (i=50;i<=300;i+=10) ( setfillstyle( 1,0); setcolor(O); pieslice(320,i-10,0,359,30);/*隐去上一个圆球*/ setfillstyle(l,15); setcolor(15); pieslice(320,i,0,359,30); delay(40000); } for (i=l;i<=4;i++) ( setfillstyle( 1,0);setcolor(0);fillellipse(320,300+(i- l)*2,30,30-(i-1 )*2)J* 隐去上一个椭 /*让圆球下落*/ /*在下面画一个新圆球*/ /*圆球变为真正的椭圆球*/ 圆 球*/ setfillstyle(l,15); setcolor( 15);fillellipse(32O,3OO+i*2,3O,3O-i*2);/*在下面画一新椭圆 球 delay(40000); /小椭圆变为圆球*/ setfillstyle(hO); setcolor(0);fillellipse(320,300+i*2,30,30-i*2); /*隐去上一个椭圆 球*/ setfillstyle(l,15); setcolor(15); /* 在上面画一个新椭圆球 fillellipse(32O,3OO+(i-1 )*2,30,30-(i- l)*2);delay(40000); ) getch(); closegraph(); ) 4 .为例图中的各部分组成加上文字说明。 【分析与提示】本题的关键点是控制输出文字的位置,需要通过多次实验, 积累经验后才能比较准确地定位。 参考代码: include\"\" main() { int driver=VGAjnode=VGAHI; int xcenter,ycenter,r,x,y; initgraph(&driver,&mode/M,);cleardevice(); xcenter=300; ycenter=200; i-lOO; /* 中心点坐标及饼图半径*/ settextstyle(0,HORIZ_DIR, 1); outtextxy(220,60/This is a Pie Chart11);/* 饼图标题 */ setfillstyle(l,RED);pieslice(xcenter,ycenter,0,40,r);/* 饼图第一份及标题 */ outtextxy(400J 65,\"%\"); setfillstyle( 10,GREEN);pieslice (xcenter,ycenter,40,90,r);/* 饼图第二份及标题 */ outtextxy(340J 00/1%M); setfillstyIe(9,YELLOW);pieslice(xcenter,ycenter,90,120,r);outtextxy(260,90/f%\"); setfillstyle( 7,BLUE);pieslice (xcentenycenter, 120, 170j);outtextxy( 180,130,H%H); setfillstyle(2,RED);pieslice(xcenter,ycenterJ 70,220j);outtextxy( 160,220,\"%”) setfillstyle(3,RED);pieslice(xcenter,ycenter,220,280j);outtextxy(240,300/1%H); setfillstyle(6,RED);pieslice(xcenter,ycenter,280,320,r);outtextxy(340,295/1%H); setfillstyle(8,RED);pieslice(xcenter,ycenter320,360,r);outtextxy(395,230/1%H); getch ();closegraph (); ; 【分析与提 示】 本程序利用正弦三角函数和写点、画线及 填充功能,首先画出两幅旗帜飘动时的两个 态图(状态图越多,效果越逼真) 关函数以图像方式保存在内存中。 然后,通 在同一个位置不断循环显示它们, 旗帜飘动的效果。 参考代 码: #inckide o #include o #include o #inckide o void main() 5.编写程序绘制出一面飘动的红旗。 以模拟实 图 10-6 /*定义图形标准 */ char ch[20], *pl,*p2; /*存储图形所在位置的指针 */ int size, stx=200,endx=450,sty=50,endy=200; /*旗帜的标准大小 */ void horline(int x0, int yO, int x 1 ,int a, /*画水平曲线函数int k); */ void verline(int xO, int yO, int yl,int a, int /*画垂直曲线函数k); */ initgraph(&driven&mode/); /*初始化图形系统 */ setcolor(I4); /*线条颜色为黄色*/ int driver=VGA, mode=VGAHI; M, horline(stx,sty,endx,0,2); /*画旗帜上面的水平曲线*/ verline(endx,sty,endy, 10,3); /*画旗帜右边的垂直曲线*/ horline(stx,endy,endx,0,2); /*画旗帜下面的水平曲线刃 setfillstyle(l J4); bar(stx-3,sty-5,stx-l,endy+150); /*画旗帜左边的旗杆*/ setfillstyle(l,4); floodfill(stx+50,sty+50,14); size=imagesize(stx,sty-5,endx+5,endy+5); /*以红色填充旗帜*/ /*保存旗帜的这种状态于 pl 处*/ p I =(char *)malloc(size); getimage(stx,sty-5,endx+5,endy+5,p 1); setfillstyle(l,0);floodfill(stx+50,sty+50,14);/*取消旗帜的填充,变为填充黑色*/ setcolor(O); horline(stx,sty,endx,0,2); /* 把所有旗帜的边线变为黑色*/ verline(endx,sty,endy, 10,3); horline(stx,endy,endx,0,2); setcolor(14); */ horline(stx,sty,endx,0,4); verline(endx,sty,endy, 10,6); horline(stx,endy,endx,0,4); setfillstyle(l,4); floodfiH(stx+50,sty+50,14);/*旗帜内部依然填充为红色*/ size=imagesize(stx,sty-5,endx+5,endy+5); /*再画另一种旗帜的状态,边线为黄色 /*保存此种旗帜的图形于 p2 处*/ p2=(char *)malloc(size); getimage(stx,sty-5,endx+5,endy+5,p2); while(!kbhit()) ( putimage(stx,sty-5,p 1,0); putimage(stx,sty-5,p2,0); } getch(); delay (65000) ;/* 显示一种状态的旗帜 *7 delay(65000); /*显示另一种状态的旗帜*/ /*暂停,按任一键结束*/ free(p 1 );free(p2); closegraph(); /*释放占用的内存,关闭图形系统*/ } void horline(int xO,int y0, int xl, int a, int k) ( int i,rel,fcolor=getcolor(); for(i=xO;i /*从左到右画水平曲线*/ ( rel=(int)(5*sin((i*k+a)*180)); /*最大垂直飘扬偏差为 5 像素*/ putpixel(i,rel+yO,fcolor); /*逐点画出此水平曲线*/ moveto(ijel+yO); } lineto(xLyO); /*连接最后的线段,防止可能出现的断线*/ void verline(int xOJnt yOjnt yl,int ajnt k) ( int i,rel,fcolor=getcolor(); /*得到当前颜 色*/ for(i=yO;i { rel=(int)(5*sin((i*k+a)*180));/*最大水平飘扬偏差为 5 像素*/ putpixel(rel+xO,i,fcolor); ) moveto(rel+xO,i); lineto(xO,yl); /* 逐点画出此垂直曲线*/ /*连接最后的线段,防止可能出现的断 线*/ ) 6 .眼睛可以转动的小猫。 【分析与提示】本题的主要是练习用画圆、画圆弧、画直线及填充函数,来 画一个自己喜欢的图形。关键点是控制输出的位置,需要通过多次调整,熟练后 就能比较准确地定位。 #include <> #include <> #include <> #define PATH \"c:\\\c\" #define PI main() {int gdriver=VGA,gmode=VGAHI; int i,a,b,c,d; initgraph(&gdrivei;&gmode,PATH); ellipse(288,l ,0,360,96,72); circle(240,176J 8); circle(320,176,18); circle(250J76,6); circle(310,176,6); circle(280,200J0); floodfill(240J76,WHITE); floodfill(320,176,WHITE); arc(300,90,335,5,70); floodfill(360,85,WHITE); floodfill(280,242,WHITE); arc(350,300,265,0,70); arc(280,280,120,200,50); arc(230,330,235,330,20); floodfill(280,200,WHITE); arc(388,130,95,150,60); floodfill(220,90,WHITE); arc(280,310,325,65,85); arc(415,307,45,225,8); arc(230,330,80,155,30); line(248,340,255,330); arc(250,90,160,220,60); arc(388,130,110,150,50); arc(285,200,224,315,46); arc(350,300,270,350,60); arc(280,300,290,312,95); line(203,313,218,345); arc(265,340,330,135,13); arc(250,90,172,220,50); arc( 180,140,30,85,70); arc( 180,140,30,70,60); arc(300,90,330,15,80); line(245,380,278,346); arc(275,380,180,270,30); arc(310,430,,147,40); line(340,210,380,215); line(350,220,400,225); line(255,220,200,228); line(245,230,190,238); for(i=0;i<=2*PI;i++) {circle(250,176,6); circle(310,176,6); floodfill(250,176,WHITE); floodfill(250,176,WHITE); setcolor(BLACK); a=240+10*cos(i); circle(c,d,6); floodfill(a,b,BLACK); floodfill(c,d,BLACK); setcolor(WHITE); getch(); c=320+10*cos(i); b=176-10*sin(i); d=176-10*sin(i); circle(a,b,6); ) ) 要求:读懂该程序,将小猫的左眼珠的黑点位置找到并补画上。仿照该例题思 路,画出一个自己喜欢的小动物或山水画。由于篇幅,我们下面选了 4幅学生用C语言 所编写的动画图形,使人看起来赏心悦目。我们自己也动手作出1~2幅静态或动画图 形作品。 图 10-8 图 10\"9 {t=d5;d5=dl;dl=t;j if(d4Vd3)
{t=d4;d4=dl;dl=t;j if(d3
{t=d3;d3=dl;dl=t;j if(d2
{t=d2;d2=dl;dl=t;j switch(n)
因篇幅问题不能全部显示,请点此查看更多更全内容
Copyright © 2019- 517ttc.cn 版权所有 赣ICP备2024042791号-8
违法及侵权请联系:TEL:199 18 7713 E-MAIL:2724546146@qq.com
本站由北京市万商天勤律师事务所王兴未律师提供法律服务