C语言复习经典习题及其答案
C语言经典习题及其答案详解第一章C语言概述
1.1单项选择题
1.二进制语言是属于()
①面向机器语言②面向问题语言③面向过
程语言④面向汇编语言
「解」人们研制了许许多多计算机程序设计语
言,其中二进制语言直接来自计算机的指令系统,
与具体计算机紧密相关,所以是一种面向机器语
言。面向问题语言是为了易于描述和求解某类特定
领域的问题而专门设计的一种非过程语言。面向过
程语言是一种能方便描述算法过程的计算机程序
设计语言。有汇编语言,但没有面向汇编语言。汇
编语言也是一种面向机器的语言,与机器语言比
较,汇编语言用有助于记忆的符号来代表二进制代
码。所以解答是①。
2.下列语言中不属于面向过程的语言是()
①高级语言②低级语言③C语言④
PASCAL语言
「解」C语言和PASCAL等程序设计语言都
是高级语言,它们用于描述复杂加工的处理过程,
所以也称它们是面向过程语言。低级语言是指机器
语言和汇编语言,低级语言是面向机器的语言,而
不是面向问题的语言。所以解答是②。
3.下列字符中属于键盘符号的是()
①\②\n③\t④\b
「解」键盘符号是指键盘上有标记,并能在显
示器上直接以其标记字样显示的字符。有许多键盘
上有标记的符号,它们不是用于直接显示的,键入
这种字符用于表示特定的意义,如常用的回车符。
为了能让C程序标记这种符号,程序采用转义字符
的方式书写这种字符。如'\n'、'\t'、'\b'都不是键盘字符,在C语言中,它们都得用转义字符来表达。
只有字符\才是键盘字符。所以解答是①。但在C
程序中,反斜杠字符\已特别用作转义字符的引导
符,它也得用转义字符的表达形式书写,将它写成
‘\\’。
4.下列字符列中,不是用来表达转义字符是)(
①\\②\'③074④\0
「解」转义字符有三种书写形式:反斜杠字符
后接上某个规定的字符;反斜杠字符后接上13个
八进制数字符;反斜社字符和字符X之后接上1至
2个十六进制数字符。后两种分别八进制数和十六
进制数直接给出字符的ASCll代码值。而074是八
进制整数,不是转义字。所以解答是③。
5.不是C语言提供的合法关键字是()
①switch②begin③case④default
「解」因C语言的关键字表中没有begin,它
不是C语言的关键字。所以解答是②。
6.下列字符列中,能作为单个标识符是()
①?a②a=2③a.3④a_3
「解」在C语言中,规定标识符是这样一种字
符序列,由英文字母或下线字符开始,后接任1个
英文字母、下线字符和数字符组成。所以问题所列
的字符列只有a_3是标识符,其余都不是标识符,
一个是由字符‘?’开头、一个中间有字符‘=’,另一个有字符‘.’。所以解答是④。
1.2填充题
7.在C语言中,下列说法中错误的是()
①函数定义可以分为两个部分:函数说明部分
和函数体
②主函数可以调用任何非主函数
③任何非主函数可以调用其它任何非主函数
④程序可以从任何函数开始执行
「解」每个C函数的定义分两部分,函数说明
部分和函数体,所以叙述①是正确的叙述。语言C
中,函数可以递归调用,主函数可以调用程序中的
任何函数,当然可以调用任何非主教的其它函数,
所以叙述②是一个正确的叙述。同样理由,叙述③
也是正确的。C语言规,C程序只有一个主函数,
并总是从主函数开始执行,不能从非主函数开始执
行。所以,说程可以从任何函数开始执行是错误的。
所以解答是④。
1.汇编语言属于面向________语言,高级语言
属于面向________语言。
「解」汇编语言与具体计算机密切有关,是属
于面向机器的语言;而高级语言用来描述求解题的
算法,所以是面向过程的语言。所以解答是:面向
机器和面向过程。
2.用高级语言编写的程序称为________程序,
它可以通过________程序翻译一句执一句的方式
执行,也可以通过________程序一次翻译产生
________程序,然后执行。
「解」用高级语言编写的程序称为源程序,源
程序不能在计算机上直接运行,运行源程序有种方
式:一种是通过解释程序,对源程序逐句解释执行;
另一种是先让编译程序将源程序一翻译产生目标
程序(目标程序是计算机可直接执行的机器语言程
序,它是一种二进制代码程),然后执行目标程序。
3.转义字符是由________符号开始,后接单个
字符或若干字符组成。
4.C语言词类主要分为____、_____、_____和
_____等。
「解」语言的基本词汇是指直接由字符序列组
成,有确定意义的最基本单位,所以C语言词汇有:
字面形式常量、特殊符号(主要是运算符)、保留
字和标识符等四类。而表达式、函数调用等是更高
级的语言成分,如表达式中还可分运算分量和运算
符等;函数调用也是一种表达式,它有函数名标识
符、圆括号和实际参数表等。利用基本词汇,按照
给定的C语言的句法规则,就可命名程序对象,描
述表达式计算、构造语句、函数,直至整个程序。
5.C语言的语句主要分为_____语句、_____语句、
_____语句_____语句、______语句和_____语句等。
「解」C语言有多种不同功能的语句,有用于
定义数据的,有用于各种存储和计算的,有用于程
序流程控制的,有多种分类方法。C语言的语句主
要有:数据定义语句、表达式语句、流程控制语句、
复合语句、空语句和其它语句。程序中经常使用的
赋值表达式语句和函数调用表达式语句都是典型
的表达式语句。
6.C程序是由函数构成的。其中有并且只能有
_____个主函数。C语言程序的执行总是由_____函
数开始,并且在_____函数中结束(如别的函数未
调用终止程序执行的库函数)
「解」C程序是由若干函数构成的。其中有并
且只能有1个主函数(用main命名)程序的执。C
行总是由主函数开始执行,通常在主函数中结束
(如没有在别的函数中调用终止程序执行的库函
数的话)。
第二章基本数据类型和表达式
2.1单项选择题
1.下列字符列中,可以作为“字符串常量”的是
()
1ABC②“ABC“③‘abc’④‘a’
「解」C程序中,一个字符率常量是表示一个
字符序列,书写时,用双引号字符前后括住这个字
符序列。所以只有“ABC”是一个正确的字符率常
量,其余都不是。其中,ABC可作为标识符,字符
列‘abc’不能出现在C程序中,‘a’是一个字符常量。所以解答是②。
2.在以字节存储字符的系统中,‘\n’在内存占
用的字节数是()
①1②2③3④4
「解」一般来说,一个字符在内存中只占1个
字节,‘\n’是转义字符,其意义是换行符,它作为
一个字符存储,在内存也只占1个字节。所以解答
是①。
3.字符串“xyz”在内存占用的字节数是()
①3②4③6④8
「解」字符串中的每个字符占1个字节,但C
程序在存储字符串时,要在最后一个有效字符后面
接上1个字符串结束的标记符‘\0’。这样,存储字
符串常量“xyz”需要4个字节。所以解答是②。
4.在以下字符列中,合法的长整型常数是()
①0L②4962710③0.054838743④
2.1869el0
「解」为表示不同范围的整数,整型数据分短
整型、基本型和长整型,并对三种整型内部表示的
最高位的不同理解,又分别分成无符号和带符号两
种。若要明确指明一个整数是长整型的,必须在整
数之后接上字符‘L’。所以0L是一个长整型的整型
常量,而4962710是基本整型数据,而对于用2个
字节表示一个基本整型数据的系统来说,该整数将
因超出范围而是一个错误的整数;0.054839743和
2.1869el0都是double型的实数。所以解答是①。
5.一个char型数据,它的值在内存中存放的是
()
①ASCll代码值②BCD代码值③内码值④
十进制代码值
「解」计算机存储字符,通常是存储字符的某
种代码值。有许多种字符编码的方法,最流行的是
ASCII代码。在C语言中,Char型数据也用ASCII
2代码表示。所以解答是①。
6.设变量m,n,a,b,c,d的初值均为0,执
行(m=a==b)||(n=c==d)后,m,n的值是
()
①0,0②0,1③l,0④1,1
「解」计算(m=a==b)||(n=c==d)的过程
是先计算逻辑或的左运算分量(m=a==b)的值,由
低,又先计算a==b.因a,b均为0后,所以比较
结果值为1.将1赋给变量m,使变量m的值变为1.
同时这个赋值运算的结果也是1,这样逻辑运算的
左运算分量的值为1.由于逻辑或运算的左运算分量
值为1,按照C语言对逻辑或运算优化计算的规定,
不再计算逻辑或的右运算分量,而直接得到逻辑或
运算的结果为1.由于逻辑或的右运算分量不曾计
算过,所以变量n的值也不为变化。这样,上述表
达式计算后,变量m的情为1,变量n的值为0.所
以解答是③。
7.设a为5,执行下列计算后,b的值不为2的
是()
①b=a/2②b=6-(--a)③b=a%2④b
=a<3?3:2
「解」因两个整型数据相除,结果是整数,当
a的值为5时,计算表达式b=a/2后,使b的值为
2.计算表达式b=6-(--a)是先计算子表达式(--a)
的,先让a的值减1变成4,并以减1后的a为子
表达式的结果,所以子表达式的结果为4,最后使
b的值为2.在计算表达式b=a%2时,求余运算a%
2的结果为1,最后使变量b的值为1.计算表达式b
=a<3?3:2时,先计算条件表达式a<3?3:2,
以2为结果,最后也使变量b的值为人所以解答是
③。
8.执行语句“x=(a=3,b=a--);”后,X,a,
b的值依次为()
①3,3,2②2,3,2③3,2,3④2,3,3
「解」计算表达式x=(a=3,b=a--)时,先计
算赋值号右端圆括号内的逗号表达式。逗号表达式
要求各子表达式顺序计算,并以最后予表达式的值
为整个逗号表达式的结果。所以该表达式计算时,
先让变量a的值为3,a--的值是a当时的值,以该
值为结果赋给变量b,并以该值为逗号表达式的值
赋给变量x,然后a的值被减少1.所以计算该表达
式后,使变量x,a,b的值依次为3,2,3.所以解
答是③。
9.设整型变量m,a,c,均为1,n,b,d执行“m(=a>b)&&(n=a>b)”后m,n的值是()
①0,0②0,l③1,0④1,l
「解」表达式(m=a>b)&&(n=a>b)
是一个逻辑表达式,它的计算过程是先计算逻辑与
的左分量(m=a>b,其中又是先计算a>b.因a>b
不成立,结果为0,将0赋给变量m,最后逻辑与
的左分量结果为0.由于逻辑运算采用特别的优化计
算规则,当逻辑与的左分量结果为0时,不再计算
逻辑与的右分量,而直接以0为逻辑与的结果。所
以,上述表达式计算使m的值变为0,而n的值没
有变,依旧为l.所以解答是②。
10,设有代码“int a=3;”,则执行了语句
“a+=a-=a*a;”后,变量a的值是()
①3②0③9④-12
「解」由于赋值运算符的结合性自右至左,语
句“a+=a-=a*a;”的执行是先计算a*a,得到值9,
再计算a-=a*a,使a的值为-6,接着计算a+=a,
使a的值为-12.所以解答是④。
11.在以下一组运算符中,优先级最高的运算符
是()
①<=②=③%④&&
「解」常规运算符的优先级自高到低的排列顺
序是算术运算符、移位运算符、关系运算符。按位
运算符、逻辑运算符、条件运算符、赋值运算符、
逗号运算符。所以问题所给的四个运算符按优先级
12.设整型变量i的值为3,则计算表达式i---i
后表达式的值为()
①0②l③2④表达式出错
「解」有些运算符只有一个字符,也有许多运
算符由两个字符组成。特别是有些字符既可是单个
字符的运算符,又能组成双字符的运算符。编译系
统在识别源程序时,通常是尽量多地读八字符,能
组成多字符单词的先尽量组成多字符单词。所以表
达式i---i,被编译器理解为(i--)-i.另外,当表达
式中某变量有后缀自增和自减运算时,先按变量的
原值计算表达式,然后再对变量进行自增和自减运
算。同样地,当表达式中某变量有前缀自增和自减
运算时,先对变量进行自增和自减运算,然后再按
变量的新值计算表达式。按这个约定,求表达式
(i--)-i是计算i-i的值为0,然后再对i作自减运算。这样,表达式(i--)-i的值为0.所以解答是①。
13.设整型变量a、b、c均为2,表达式a+++b+++c++的结果是()
①6②9③8④表达式出错
「解」与上一小题解答的理由相同,表达式
a+++b+++c++被系统理解成:(a++)+(b++)()
+c++)。表达式“变量++”的值是变量的原来值,所
以在变量a、均为2的前题下,b.c执行上述表达式,
得到结果为6.所以解答是①。
14.若已定义x和y为double类型,则表达式:
x=l,y=x+3/2结果是()
①l②2③2.0④2.5
「解」由于变量x和y都是double类型,表达
式x=l,y=x+3/2是先计算x=1,由于1是
整型的,x是double类型的,该计算先将整数1转
换成double类型的1.0,并将1.0赋给变量x.计算y
=x+3/2是先求3/2的值,因是两整数相除,
结果是整型值1,然后在计算x+1时,也先将1
转换成1.0,然后求得x+l的值为2.0,最后将该
值赋给变量y,并得到整个表达式的值为2.0.所以
解答是③。
15.设a=1,b=2,c=3,d=4则表达式a<b?
a:c<d?a:d的结果为()
①4②3③2④1
「解」条件运算符的优先级比关系运算符的优
先级低,并且它的结合性是自右向左的,所以表达
式a<b?a:c<d?a:d可用圆括号等价地写成(a
<b?a:(c 结果为A的值1.所以解答是④。 16.设a为整型变量,下列C表达式中,不能表 达数学关系式:10<a<15的是() ①10<a<15②a==11||a==12||a==13||a ==14 ③a>10&&a<15④!(a<=10)&&!(a >=15) 「解」数学关系式10<a<15表示。只能是 11,12,13,14四个值之l. 用C表达式表示这个条件,可写成a>10&& a<15,或!(a<=10)&&!(a>=15),或a== 11||a==12||a==13||a==14等。若写成10<a<15,该算式的计算顺序是先求出10<a的结果0或1, 然后以这个结果与15比较,是否小于15,显然这与数学式子的意义是不一致的。所以解答是①。 17.下列表达式中,正确的C赋值表达式是)( ①a=7+b+c=a+7②a=7+b++=a+7 ③a=(7+b,b++,a+7)④a=7+b, c=a+7 「解」赋值运算符是运算符之一,赋值运算也 可以出现在一般表达式中。赋值运算时,出现在赋式a=7+b+c=a+7因算术运算符比赋值运算符 的优先级高,要把a+7的结果赋给7+b+c,这是 错误的。同样理由,表达式a=7+b++=a+7 也是错误的。而表达式a=(7+b,b++,a+7) 就是正确的赋值表达式,它是先计算赋值号左边的 括号内的表达式,括号表达式内是一个逗号表达 式,远号表达式要求顺序逐一计算各子表达式,并 以最后一个子表达式的值作为远号表达式的结果, 最后将该结果赋给变量a.而表达式a=7+b,c=a +7则不是一个赋值表达式,而是一个逗号表达式, 它由两个赋值子表达式组成。所以解答是③。 18.若有以下定义:char a;int b;float c;double d;则表达式a*b+d-c值的类型为() ①float②int③char④double 「解」基本类型的数据可以混合运算,但运算 时,对要求运算分量类型相同的运算来说,如运算 分量的类型不是全相同,则会有自动类型转换发 生。类型自动转换规则规定类型低(简单)的向类 型高(复杂)的转换。各类型由高到低的排列顺序 是:long double、float、unsigned long、long、unsigned int、int这样,若有定义:char a;int b;float c;double d;则表达式a*b+d-c的值的类型是double 的。首先计算a*b,得到int类型的值,接着计算 a*b+d,得到double类型的值,最后计算a*b+d-c, 得到double类型的值。所以解答是④。 19.表达式“9!=7”的值是() ①true②非0值③0④1 「解」关系运算的结果只有0和1,若关系成 立,则结果为1;若关系不成立,则结果为0.因关 系式9!=7成立,所以表达式的结果为1.虽然1 也是非0值,在供选择的答案中有1,所以最确切 的解答是④。 21.设字符型变量a=3,b=6,计算表达式C =(a^b)<<2后C的二进制值是() ①00011100②00000111③00000001④00010100 「解」a的值为3,写成8位二进制数形式是00000011,b的值为6,写成8位二进制数形式是00000110.表达式c=(a^b)<<2,先计算a与b 的按位加,得到结果00000101,将这结果向左移2 位,得到二进位的位串信息是00010100.所以解答 是④。 22.设a,b和c都是int型变量,且a=3,b =4,c=5,则下面的表达式中值为0的是() ①‘a’&&‘b‘②a<=b③a||b+c&&b-c④!((a 「解」对于表达式‘a’&&‘b’,两个非O运算 分量的逻辑与结果为1.对于表达式a<=b,由于关 系式成立,结果也为此又由于变量a为非0,表达 式a||b+c&&b-c的结果也为1.对于表达式!((a<b)&&!c||1),先是计算(a<b)得到结果1;计算! C得到结果为0;再计算它们的逻辑与,结果为0. 继续与1求逻辑或,得到结果为1.最后,对1求逻 辑非,得到结果为0.所以解答是④。 23.设ch是char型变量,其值为‘A’,则下面表 达式的值是() ch=(ch>=‘A’&&ch<=‘Z’)?(ch+32):ch ①‘A’②‘a’③‘Z’④‘z’ 「解」由于字符型变量ch的值为‘A’,计算表 达式ch=h>=‘A’&&ch<=‘Z’)?(ch+32):ch,先计算其中条件表达式,由于条件(ch>=‘A &&h<=’Z‘)成立,该条件表达式以ch+32=97 为结果,将该值赋给变量ch,以字符表达这个值 2.2填充题 1.在内存中,存储字符串“X”要占用______个字节,存储字符‘X’要占用_____个字节。 「解」计算机存储一个字符用1个字节,存储 字符串时,每个字符要占用1个字节,另在字符串 的有效字符之后存储1个字符串的结束标记符。所 以存储字符率“X‘要占用2个字节,存储字符’X‘只要1个字节。 2.在C程序中,判逻辑值时,用_____表示逻辑 值“真”,又用_____表示逻辑值‘假“。在求逻辑值时,用_____表示逻辑表达式值为”真“,又用_____表示 逻辑表达式值为”假“。 「解」在C程序中,判逻辑值时,用非0值表 示真;而判逻辑值时,用值0表示假。但逻辑表达 式计算结果,逻辑表达式值为真是用1表示的,而 逻辑表达式的值为假,则用0表示。 3.定义符号常量的一般形式是_____. 「解」定义符号常量用预处理命令的宏定义, 其定义的一般形式是: #define符号常量名常量 4.在函数内,说明变量时,若省略存储类型符, 系统默认其为_____存储类别,该存储类别的类型 符为_____. 「解」在函数内,说明变量时,若省略存储类 型符,系统就默认其为自动存储类别,该存储类别 用auto标识。 5.无符号基本整型的数据类型符为_,双精度 实型数据类型符为_,字符型数据类型符为_。 「解」无符号的基本整型的类型符为unsigned int,或简写成unsigned.双精度实型数据类型符为double,字符型数据类型符为char. 6.定义指定数据类型的变量时,较完整的一般 形式是。 「解」要指定变量的存储类型,定义指定类型 的变量,其一般形式是:存储类型符数据类型符变 量名1,变量名2,……; 7.设有下列运算符:<<、+、++、&&、 <=,其中优先级最高的是_____,优先级最低的 是_____. 「解」对运算符<<、+、++、&&、<=, 按它们的优先级自高到低的顺序排列为:++、+、 <<、<=、&&所以,优先级最高的是++,优先 级最低的是&&。 8.设二进制数A是0A101111,若想通过异或运 算A^B使A的高4位取反,低4位不变,则二 进制数B应______. 「解」按位加运算的一个重要应用是让某个整 型变量的二进位位串信息的某些位信息反向,0变 成1,而1变成0.这只要设计这样一个位串信息, 让要变反的位为1,不要改变的位为0,用这个位 串信息与整型变量按位加就能得到希望的结果。要 使字节的高4位取反,低4位不变,则需要位串信 息是11110000,写成八进制数是0360,写成十六进 制数为0xF0. 9.设a=3,b=2,c=l,c>b的值为______.,则 a>b>c的值为______. 「解」因a的值为3,b的值是2,条件a>b 为真,其值为1.表达式a>b>c的求值顺序是计算 a>b,结果为1,接着计算1>c,因c的值为1, 条件1>c为假,结果为0. 10.已知a=10,b=20,则表达式!a<b的值 为_____. 「解」计算表达式!a<b,先计算!a,因a 的值为10,的值为0.关系表达式0<20为真,!a 11.设x和y均为int型变量,且x=l,y=2, 则表达式1.0+x/y的值为_____. 解」计算表达式1.0+x/y,先求x/y,因x 和y是整型变量,其中的除运算是整除,1/2的 结果为0.接着计算1.0+0,计算时,先将右分量转 换成0.0,最后得到结果1.0. 12.设整型变量x、y、z均为5: ①执“x-=y-x”后,x=__________, ②执行“x%=y+z”后,x=__________. ③执行“x=(y>z)?x+2:x-2,3,2后, x=____________. 「解」在变量x、y、z的值均为5的情况下, 计算各表达式。由于表达式x-=y-z等价于表达式 x=x-(y-z)所以计算后x的值为5.表达式x%=y,+z等价于表达式x=x%(y+z),所以计算后x的 值也为5.表达式x=(y>z)?x+2:x-2,3, 2的计算过程用圆括号描述其计算顺序是: ((x=(y>z)?x+2:x-2),2,3) 即这是一个逗号运算表达式,由一个赋值表达 式和两个数值构成,逗号表达式要求顺序求各子表 达式的值。表达式x=(y>z)?x+2:x-2的 计算是先求赋值号右边的条件表达式,因条件(y >z)为假,求出x-2的值为3,将该值赋给变量 x,使x的值为3. 13.能表述“20<x<30或x<-100”的C语言 表达式是_____. 「解」首先表述20<x<30的C表达式可写成 20<x&&x<30.所以表述“20<x<30或x<-100” 的C表达式为20<x&&x<30||x<-100. 14,请写出数学式x/y*z的C语言表达式 _______. 「解」数学式子表述的是x除以y乘z的积, 写成C表达式可以写为x/(y*z),或可等价地写 成x/y/z. 15.C语言中运算结果可以当成逻辑值使用的 表达式有:_____表达式、_______.表达式、________ 表达式、____________表达式、_________表达式、 ________表达式。 「解」在C语言中,逻辑判断以非0值为真,以0 值为假。所以,几乎所有的表达式的运算结果都可 以当成逻辑值使用,如算术表达式、关系表达式、 逻辑表达式、赋值表达式、逗号表达式、条件表达 式等。 第三章C程序结构 3.1单项选择题 1.设a=3,b=4执行“printf(“%d,%d’,(a,b)(b,a);”的输出是(),) ①3,4②4,3③3,3④4,4 「解」在调用格式输出函数的语句中,其中每 个格式符对应一个输出项,格式符d要求输出项内 容以十进制整数形式输出。第一个输出项(a,b) 是一个逗号表达式,该表达式的值是b的值,输出 4.接着输出字符逗号。第二个输出项(b,a)的值 是a的值,输出3.所以语句执行将输出4,3.正解 的选择是②。 2.使用“scanf(”x=%f,y=%f“,&x,&y)”,要使x,y均为1.25,正确的输入是() ①1.25,1.25②1.251.25③x=1.25,y=1.25 ④X=1.25y=1.25 「解」格式输入函数的格式字符串中的字符可 以分成三类:空格类字符、其它普通字符和格式转 换说明。其中空格类字符用来跳过一个空格类字符 序列,直至下一个非空格类字符。普通字符要求输 入字符与其完全相同。格式转换说明对输入字符列 按格式转换说明进行转换,得到内部值存储到对应 输入项所指定的存储位置中。函数调用scanf(“x =%f,y=%f,&x,&y)以普通字符x=开头,输 入时也要先输入x=。接着是一个浮点数输入格式, 所有能构成一个浮点数1.25的字符序列都能满足 要求。接着是普通字符列”,y=“,在输入的浮点数 之后也要有字符列”,y=“。最后又是浮点数输入格 式,同样所有能构成一个浮点数1.25的字符序列都 能满足要求。问题给出的供选择答案中只有 x=1.25,y=1.25是能满足上述要求的。所以正确选 择是③。 3.设有int i=010,j=10;则执行“printf(”%d, %d\n“,++i,j--);”的输出是() ①ll,10②9,10③010,9④10,9 「解」变量i和j的初值分别为八进制数010 和十进制数10,函数调用Printf(“%d,%d\n”, ++i,j——)中,++i的值是变量i增1后的值,原 来值是八进制数010,等于十进制数8,输出9.j—— 的值是变量j减1之前的值,输出10.格式字符申中 的逗号是普通字符照原样输出。所以问题给出的格 式输出函数调用将输出9,10.正确的解答是②。 4.设a,b为字符型变量,执行“scanf(”a=%c, b=%c“,&a,&b)”后使a为‘A’,b为‘B’,从键 盘上的正确输入是() ①‘A“B’②‘A’,‘B’③A=A,B=B④a=A,b =B 「解」函数调用scanf(“c=%c,b=%c”,&c, &b)中,普通字符必须按格式字符串要求照原样输 入,c格式对紧接的任何字符都输入。所以实现问 题的要求,输入字符列应为“a=A,b=B”。另外要 特别指出,在程序中,为表示字符常量,字符前后 需加单引号。但用字符格式输入字符时,在要输入 字符前后不必另键人单引号。若键人单引号,则这 个单引号也将作为字符被输入。正确的解答是④。 5.设x、y、z、t均为int型变量,则执行以下 语句后,t的值为() x=y=z=1;t=++x||++y&&++z; ①不定值②2③l④0 「解」语句序列“x=y=z=l;t= ++x||++y&&++z;”使变量x的值为1,变量t是赋 一个逻辑表达式的值。在C语言中,由逻辑与和逻 辑或构成的逻辑表达式有特别的计算规则,顺序计 算各逻辑子表达式,并当一旦能得到逻辑表达式的 结果时,就立即结束逻辑表达式的计算,不再计算 后继逻辑子表达式。本题的逻辑表达式是两个运算 分量的逻辑或,而且左运算分量++x的值为非0, 立即得到逻辑或运算的结果为1,并将1赋给变量 t,所以变量t的值为1.正确解答为③。 6设x、y、z均为int型变量,则执行以下语句 后,x、y,z的值为() x=1;y=0;z=2;y++&&++z||++x; ①2、l、3②2、0、3③2、l、3④2、1、2 「解」语句序列“x=l;y=0;z=2;y++&&++z||++x;”先使变量x的值为1,变量y的 值为0,变量z的值为2.由逻辑与和逻辑或构成的 逻辑表达式的特别计算规则,顺序计算各逻辑子表 达式,并当一旦能得到逻辑子表达式的结果时,就 立即结束逻辑子表达式的计算,不再计算该逻辑子 表达式。计算y++因y的值为0,使y++&&++z的 结果为0,立即去计算++x,这次计算使变量y的值变成1,而变量z的值本改变。接着计算++x,使x 的值变为2.所以经上述语句执行后,x、y、z的值 依次为2、1、2.正确解答为④。 7.假定所有变量均已正确定义,下列程序段运 行后x的值是() a=b=c=0;x=35; if!x--;else if b)if c)(a)(;(x=3;else x=4; ①34②4③35④3 「解」以变量a,b,c的值均为0,变量x的 值为35,语句: if(!a)x--;else if(b);if(c)x=3;else x =4; 由两个if语句组成。首先执行前一个if语句“if (!a)x--;else if(b);”,因变量a的值为0,条 件!a成立,执行x--使x的值变为34.接着执行后 继的if语句“if(c)x=3;else x=4;”,因变量c 的值为0,条件不成立而执行x=4,最终使变量x 的值为4.正确解答是②。 注意前一个if语句的else部分的成分语句只有 “if(b);”,这是一个单分支if语句,且其成分语 句为空语句。 9.下列语句中,句法错误的是(不考虑语义) () ①while(x=y)5;②do x++while(x= =10); ③while(0)④do2;while(a==b);; 「解」while语句的一般形式是: while(表达式)语句 这里的表达式可以是任何合理的表达式,语句 可以是任何语句,包括空语句,或表达式语句。可 能书写的while语句没有任何意义,如供选择的① while(x=y)5;和③while(0),但这两个语句; 的句法没有任何错误。do-while语句的一般形式是:do语句while(表达式); 其中的成分语句也可以是任何语句,但供选择 答案②do x++while(x==10);中的代码x++是一 个表达式,不是语句,语句必须要以分号结束,所 以是错误的。正确解答是②。 10,循环语句“for(x=0,y=0;(y!=123) ||(x<4);x++);”的循环执行() ①无限次②不确定次③4次④3次 「解」for循环语句的初始化部分置变量x和y 的初值为0,循环条件是(y!=123)||(x<4), 每次循环后变量X的值增1.由于循环过程中变量y 的值未被修改过,循环条件又是一个逻辑或,其左 分量(y!=123)永远成立,也就是循环条件永远 成立。所以该循环语句将循环执行无限次。正确解 答是①。 11.若i、j已定义为int类型,则以下程序段中 的内循环体的执行次数是() for(i=5;i;i--) for(j=0;j<4;j++){……} ①20②24③25④30 「解」问题所给的程序段的外循环是一个阶循 环语句,它的初始化部分置变量i的初值为5,循 环条件简写成i,即i!=0,每次循环后变量i的值 减1.所以外循环共控制5次循环。内循环也是一个 for循环语句,它的初始化部分置变量j的初值为0, 循环条件是j<4,每次循环后变量j的值增1.所以内 循环共控制4次循环。这样,如内循环的体内未曾 对变量i和j有修改,在内、外循环一起控制下, 内循环体共被重复执行20次。正确解答是①。 12.假定a和b为int型变量,则执行以下语句 后b的值为() a=1;b=10; do{b-=a;a++; }while(b--<0); ①9②-2③-1④8 「解」在这个程序段中,循环开始前变量a的值为1,b的值为10,每次循环从变量b减去a, 并让a增1,并在循环条件判定时,又让b减去1. 第一次循环后,变量b的值变成9,变量a的值变 为2,循环判断时,因b的值大于0,循环条件不 成立,结束循环。但在循环判断时,让b减去了1, 所以循环结束时,变量b的值为8.正确的解答是④。 13.设x和y为int型变量,则执行下面的循环 后,y的值为() for(y=l,x=l;y<=50;y++) { if(x>=10)break; if(x%2==1)x+=5;continue;}{ x-=3; } ①2②4③6④8 「解」for循环语句的初始化部分置变量x和y的初值为1,循环条件是(y<=50),每次循环 后变量y的值增1,控制循环最多执行50次。循环 体有三个语句:首先在发现变量x的值大于等于10 时,结束循环;接着是当变量x除2的余数为1(即变量x是奇数)时,让变量X值增5,让x变成偶 数,并直接进入下一轮循环;如变量x是偶数,则 从变量x减去3,让变量x变成奇数。由上述分析 知,每两次循环使变量x的值增加2.第一次循环后,变量x的值变成6.第二次循环后,变量x的值变成 3.第三次循环后,变量x的位变成8.第四次循环后, 变量x的值变成5.第五次循环后,变量x的值变成 10.第六次循环时,因变量x的位大于等于10,直 接跳出循环,这次循环是非正常结束,对变量y的 修正只执行了5次。所以循环结束后,变量y的值 增至6.正确的解答是③。 14.在C语言中,下列说法中正确的是() ①不能使用“do语句while(条件)”的循环 ②“do语句While(条件)”的循环中必须使用 “break”语句退出循环 ③“do语句while(条件)”的循环中,当条件 非0时将结束循环 ④“do语句while(条件)”的循环中,当条件 为0时将结束循环 「解」do-while语句的一般形式是: do语句 while(表达式); 其语义是重复执行其成分语句,直至表示条件的表达式值为0时结束。do-while语句是正常使用 的一种循环结构之一。do-while语句的循环结束条 件由while后的表达式值为0所控制,并不一定要 有break语句跳出循环来结束循环。do-while语句 在条件值非0时,将继续循环,而不是结束循环。 条件值为0时,才结束循环。所以正确的选择是④。 3.2填充题 1.结构化程序设计规定的三种基本结构是________结构,选择结构和_______结构。 「解」结构化程序设计的三种基本控制结构是 顺序结构、选择结构和循环结构。 2.若有定义“int a=25,b=14,c=19;”,以 下语句的执行结果是______. if(a++<=25&&b--<=2&&c++) prinif(“***a=%d,b=%d,c=%d\n”,a, b,c); else printf(“###a=%d,b=%d,c=%d\n”, a,b,c); 「解」问题所给的if语句中,条件a++<=25 &&b--<=2&&c++是先求逻辑与的第一个运算 分量,它是一个关系式,关系成立。接着判定第二 个逻辑与运算分量,又是一个关系式,由于变量b 的值是14,b不小于等于2,运算分量的关系式不 成立,导致if语句的条件为假,执行else部分。在 求且语句的条件时,计算了2个逻辑与分量,使变 量a的值增了1,变量b的值被减了1.所以输出内 容是:###a=26,b=13,c=19. 3.以下两条if语句可合并成一条if语句为 _____________. if(a<=b)x=1; else y=2; if(a>b)printf(“****y=%d\n”,y); else printf(“####x=%d\n”,x); 「解」在以上两条if语句中,两个条件刚巧相 反。若将前一个if语句的第一个成分语句与第二个 if语句的第二个成分语句合并;第一个if语句的第 二个成分语句与第二个if语句的第一个成分语句合 并,写成一条if语句如下: if a<=b)({x=1;printf“####x=%d\d,;(x)} else{y=2;printf(“****y=%d\n”,y);} 4.设i,j,k均为int型变量,则执行完下面的 for语句后,k的值为_______. for(i=0,j=10;i<=j;i++,j--)k=i+j; 「解」该for语句以i为0、j为10初始化, 循环条件是i<=j,每次循环后i增1、j减1, 循环体是将i与j的和赋给k.这样变量k将保存的 是最后一次赋给它的值。一次循环后i为l.j为9, 二次循环后i为2.j为8,……,五次循环后i为 5.j为5,继续第六次循环,i与j的和10存于k将 后,i为6、j为4,结束循环。所以循环执行后k 为10. 5.下列程序的功能是输入一个整数,判断是不 是素数,若为素数输出1,否则输出0,请为程序 填空。 main() {int i,x,y=1; scanf(“%d”,&x); for(i=2;i<=x/2;i++) if________________{y=0;break;} printf(“%d\n”,y); } 「解」为判数x是否是素数,预置变量y的值 为1(x可能是素数),然后用循环,用2至x/2 的整数i测试对x的整除性,若能被其中的某个整 数整除,则x是合数,置y的值为0(不是素数), 结束测试循环。若都不能整除,则x为素数。i能 否整除x,可用求余运算x%i等于0来判定。所以 程序中的空框可填x%i==0.测试X为素数的代 码可写成: y=l; for(i=2;i<=x/2;i++) if(x%i==0){y=0;bleak;} 3.3程序分析题 1.阅读程序,写出运行结果。 main() {int a=10,b=4,c=3; if(a<b)a=b; if(a<c)a=c; printf(“%d,%d,%d\n”,a,b,c); } 「解」程序中,第一个if语句if(a 当a 小。同样第二个IF语句if(a<c)a=c,当a<c 时,让C值置A,使A的值不比C小。实际;情 况是a本来就比b和c都大,所以a的值没有变, 程序输出a、b和c的原来值:10,4,3. 2.阅读下列程序,写出程序的输出结果。 main() {int x=100,a=10,b=20,ok1=5,ok2 =0; if(a<b)if(b!=15)if(!ok1)x=1; else if(ok2)x=10; else x=-l; printf(“%d\n”,x); } 「解」程序预置变量x的值为100,a的值为 10,b的值为20,ok1为5,ok2为0. 程序中给出的if语句可以写成更结构化的形式 如下: if(a<b){ if(b!=15){ if(!ok1)x=1; else{ if(ok2)x=10; else x=-l; } } } 由于条件a<b成立,并且条件b!=15也成立, 而ok1不等于0,执行else后的语句。又因ok2等 于0,执行else后的语句赋-1给x.所以程序输出-l. 3.阅读下列程序,写出程序的输出结果。 main() {int y=9; for(;y>0;y--) if(y%3==0)printf{(“%d”,;--y)continue;}} 「解」循环前,变量y的值为9,其中的循环 语句在y大于0情况下循环,每次循环后y的值减 1.循环体是当y能被3整除时输出表达式--y,输出 的是减1后的y值。这样,第一次循环因y为9, 能被3整除,输出8,y也变成8.又经两次循环,y 的值变为6,又让y减1变成5,并输出5;又经两 次循环,y的值变成3,让y减至变成2,输出2; 再经两次循环后,y的值变成0,结束循环。所以 程序输出852. 3.4程序设计题 1.编一个程序,输入华氏温度(F),按下列公 式计算并输出对应的摄氏温度(C):C=5(F- 32)/9 「解」利用公式:C=5(F-32)/9,输入F 氏温度,计算并输出对应的C氏温度,程序要引入 两个变量,分别用于存储F氏温度和C氏温度,计 算时应采用浮点型,包括公式中的常数也应写成浮 点数,不能采用整型和把常数写成整数。因采用整 型编写,公式中的除运算变成整除,会得出与实际 #include main() {float f,c;/*变量定义*/ printf(“输入F氏温度”); scanf(“%f,&f); c=5.0*(f-32.0)/9.0; printf(“对应的C氏温度%6.2f\n”,c); } 2.编一个程序,输入一个整数,输出其符号(若 ≥0,输出1;若<0输出-1)。 「解」程序可用if语句判断输入数的符号,并 控制输出1或-l.程序如下: #include main() {int c;/*变量定义*/ printf(“输入一个整数”); scanf(“%d”,&c); if(c>=0)printf(“1\n”); else printf(“-l\n”); } 3.编一个程序,输入X的值,按下列公式计算 并输出y的值。 x(x≤l) y=2x-l(l<x<10) 3x-11(10≤x) 「解」输入x,按公式计算y.这可用一个嵌套 的if语句分段判断并计算出y的值。然后输出y值。程序如下: #include<stdio.h> main() {int x,y;/*变量定义*/ printf(“输入一个整数”); scanf(“%d”,&x); if(x<=l)y=x; else if(x<10)y=2*x-l; else y=3*x-11; printf(“y=%d\n”,y); } 4.编一个程序,输入三个单精度数,输出其中最 小数。 「解」设最小数存于变量min中,为求三个数 中的最小数,可分以下多步完成,先预置min为x, 然后分别将其余两个数逐一与min比较,当它们中 的某个值比存于min中的值更小时,就用它们更新 min.写出程序如下: #include main() {float x,y,z,min;/*变量定义*/ printf(“输入三个单精度浮点数”); scanf(“%f%f%f”,&x,&y,&z); min=x; if(min>y)min=y; if(min>z)min=z; printf(“浮点数%f,%f中的最小值是%f\n”,%f,x,y,z,min); } 5.编一个程序,求出所有各位数字的立方和等 于1099的3位数。 「解」找出所有各位数字的立方和等于1099 的3位整数。3位整数是100至999范围内的整数, 设分别用a,b,c存储3位数的百位、十位和个位 的数字,程序用三重循环求出a,b,c的立方和为1099的3位数a*100+b*10+c.程序如下: #include main() {int a,b,c;/*变量定义*/ for(a=1;a<=9;a++) for(b=0;b<=9;b++) for(c=0;c<=9;c++) if(a*a*a+b*b*b+c*c*c==1099) printf(“%d\n”,(10*a+b)*10+c); } 若用一个变量i表示3位数,循环体将3位数 变量i分拆出它的百位、十位和个位共3个数字, 然后判这三个数字的立方和是否是1099,若是就输 出该变量的值。程序如下: #include main() {int i,a,b,c;/*变量定义*/ for(i=100;i<=999;i++){ a=i/100; b=(i%10)/10;/*或b=(i/10)%l0*/ c=i%10; if(a*a*a+b*b*b+c*c*c==1099) printf(“%d\n”,i); } } 6.编一个程序,输入10个整数,统计并输出其中正数、负数和零的个数。 「解」输入10个整数,统计其中正数、负数 和零的个数。程序引入3个计数器变量,用于统计 大于以小于0和等于0的整数的个数。开始时,这 3个计数器都置0,然后用循环逐一输入10个整数,并判定当前输入的整数是大于0,或小于0,或等 于0,并按判定结果累加相应计数器。最后,程序 输出这3个计数器的值。程序如下: #include main() {int i,d,n,z,p;/*变量定义*/ n=z=p=0; for(i=1;i<=10;i++){ print(“输入第%d个整数”,i); scanf(“%d”,&d); if(d<0)n++; else if(d>0)p++; else z++; } printf(“负数有%d个,正数有%d个,零有%d 个。\n”,n,p,z); } 7.编程序,按下列公式计算e的值(精度为 1e-6): e=1+1/1!+1/2!+1/3!+…+1/n!+… 「解」按e的幂级数展开式计算e的值。这是 典型的求级数和计算问题。通常采用逐项计算,并 累计的方法。计算新的项时,可用上一轮循环计算 出的项,这能提高程序的效率。循环直至当前项的 值小于精度要求结束。程序如下: #include main() {double e,t,i;/*变量定义*/ e=0.0;t=1.0;i=1.0; while(t>=1.0e-6){ e+=t; t/=i; i+=1.0; } printf(“e=%.6f\n”,e); 8.编程序,按下列公式计算y的值(精度为 1e-6): y=∑1/r*r+1 「解」按所给公式计算数列的和。类似上一小 题的解,逐项计算并累计。程序如下: #include main() {double y,r,t;/*变量定义*/ y=0.0;r=1.0; while((t=1.0/(r*r+1.0))>=1.0e-6){ y+=t; r+=1.0; } printf(“y=%.6f\n”,y); } 9.编一个程序显示ASCII代码0x20至ox6f的十进制数值及其对应字符。 「解」显示ASCII代码为十六进制0x20至ox6f 的字符的十进制代码值与其字符。程序可用一个循环,让变量i顺序地取0X20至OX6f的值,并逐一输出其十进制代码和对应的字符,程序如下: #include main() {int i,k=0; for(i=0x20;i<=0x6f;i++){ if(k++%10==0)/*每行十个*/ printf(“\n”); printf(“(%c)=(%d)”,i,i); } printf(“\n”); } 10.用三种循环语句分别编写程序显示1至100 的平方值。 「解」用三种循环语句分别编写显示1至100 的平方值的程序。直接写出3个程序如下: (1)用输循环实现的程序 #include main()/*用for循环*/ {int i,k=0; for(i=l;i<=100;i++){ if(k++%5==0)/*每行五个*/ printf(“\n”); printf(“%d*%d=%d”,i,i,i*i); } printf(“\n”); } (2)用while循环实现的程序 #include main()/*用while循环*/ {int i,k=0; i=1; while(i<=100){ if(k++%5==0)/*每行五个*/ printf(“\n”); printf(“%d*%d=%d”,i,i,i*i); i++; } printf(“\n”); } (3)用do-while循环实现的程序 #include main()/*用do-while循环*/ {int i,k=0; i=1; do{ if(k++%5==0)/*每行五个*/ printf(“\n”); printf(“%d*%d=%d”,i,i,i*i); i++; }while(i<=100); printf(“\n”); } 第四章数组 4.1单项选择题 1.若有下列说明,则数值为4的表达式是() int a[12]={l,2,3,4,5,6,7,8,9,10, 11,12};char c=‘a’,d,g; ①a[g-c]②a[4] ③a[‘d’-‘c’]④a[‘d’-c] 「解」数组元素的下标自0开始顺序编号,值 为4的元素是a[3].所以只有下标表达式的值为3的 才是正确的。下标表达式g-c中的的变量g和c的 值是还未被设定的,其值不确定。a[4]的值为5,下 标为4是不对的。‘d’-‘c’的值为1,a[l]的值是2,所以也是不对的。变量c的值为‘a’,‘d’-c=3,所 以正确解答是④。 2.设有定义:“char s[12]={”string“};”则printf (“%d\n”,strlen(s);的输出是()) ①6②7 ③11④12 「解」在C语言中,字符串是指在有效字符之 后有字符列结束标记符的字符列,并约定字符串的 长度是指字符列中有效字符个数,不包括字符串的 结束标记符。存放于字符数组s中的字符串是 “string”,该字符串的长度为6,所以输出该字符串 的长度应是6.正确的解答是①。 3.下列语句中,正确的是() ①char a[3][]={‘abc“,’1‘};②char a[][3]={’abc‘,’l‘}; ③char a[3][]={‘a’,“1”};④char a[][3]={“a”,“1”}; 「解」如定义数组时有初始化,其最高维的长 度可以省缺,由系统根据初始化时的初值个数确 定,而其它维的长度是不可以缺省的。对二维字符 数组的初始化,可以按行用字符串对其初始化,也 可以按二维数组元素的存储顺序逐一用字符对其 元素初始化。在供选择解答①和③中,有不是最高 维的长度被缺省,所以是错误的。在供选择解答① 和②中,还将字符串常量写作‘abc’,这也是错误的。 只有④,用字符列按行给二维字符数组初始化,这 才是正确的。正确构解答是④。 4.合法的数组定义是() ①int a[]={“string”}②int a[5]={0,1,2,3,4,5}; ③char a={“string”}④char a[]={0,1,2,3,4,5}; 「解」①错误的原因是整数数组不可以用字符 串对其初始化。②错误的原因是,数组初始化时, 初始化指定的值的个数多于数组的元素个数。③错 误的原因是,能用字符串初始化的只;有字符指针 初始化,包括字符变量。④是正确的,因为字符数 组可以用小整数(作为字符的ASCII代码值)对其 元素初始化。 5.语句“printf”%d\n“,(”ats\nol2\1\\“);(strlen)”的输出结果是() ①11②10③9④8 「解」字符串中的字符可以是一般的普通字符, 也可以是由反斜杠字符开头的转义字符。在字符串 “abs\no12\1\\”中,有三个转义字符,它们是\n、\1、 \\,所以该字符串的有效字符个数是9.所以正确的 回答是③。 6.函数调用“strcat(strcpy(strl,str2),str3)”的 功能是() ①将字符串strl复制到字符串str2中后再连接 到字符串str3之后 ②将字符串strl连接到字符串str2中后再复制 到字符率str3之后 ③将字符串str2复制到字符串strl中后再将字 符串str3连接到字符串strl之后 ④将字符串str2连接到字符串strl之后再将字 符串strl复制到字符串str3中 「解」函数调用strcat(s1,s2)是将s2字符 串复制连接到s1字符串之后,使s1字符串变得更 长。函数调用strcpy(s1,s2)是将s2字符串复制 到s1,s1字符串的内容与s2字符串的内容相同。使 函数调用strcat(strcpy(strl,str2),str3)是先 执行strcpy(strl,str2),然后再执行strcat(strl, str3)所以其功能是将字符串str2复制到字符串strl, 中,然后再将字符串str3复制连接到字符串strl之 后。正确的选择是③。 7.设有如下定义,则正确的叙述为() char x[]={“abcdefg”}; char y[]={‘a’,‘b’,‘c’,‘d’,‘e’,‘f’,‘g’}; ①数组x和数组y等价 ②数组x和数组y长度相同 ③数组x的长度大于数组y的长度 ④数组x的长度小于数组y的长度 「解」不指定数组长度的字符数组定义,其所 需要的字节数可由初始化中给出的值的个数确定。 字符数组可以用字符串初始化,也可用字符逐个给 字符数组的元素初始化。但用字符初始化时,尽管 给出了字符串中的全部字符,还是不会自动有字符 率结束字符。但字符串初始化自动会含有字符串的 结束标记符,字符串初始化所需要的字节个数会比 用同样多的字符初始化多1个字节。所以只有③才 是正确的。 4.2填充题 1.根据变量定义“static int b[5],a[][3]={1,2, 3,4,5,6};”,b[4]=_____,a[1][2]= 「解」系统规定,静态变量定义时,若末初始 化,系统自动给定二进制代码全0的值。所以静态 数组b的元素全为0,当然包括b[4]也为0。静态 数组a是二维数组,每行有三个元素,在初始化中 结出了六个初值,所以数组a有2行。由于数组的 元素按行顺序存储,并按行顺序初始化。前三个值 是第一行,后三个值是第二行。a[1][2]是第二行的 第三列元素,也是a的最后一个元素,所以其值是 6. 2.设有定义语句“static int a[3][4]={{1},{2},{3}};”则a[l][l]值为_,a[2][1]的值为_。 「解」给二维数组初始化时,可按行给出初值, 并且每行可以只给前面部分的元素给出初值。系统 规定,对那些未给出初值的部分元素,系统自动置 二进制代码全0的值。由于定义语句只给a[0][0]给 定初值l、a[l][0]给定初值2、a[2][0]给定初值3.这样,其它元素都为0值。所以,a[1][1]=0,a[2][1]=0. 3.若在程序中用到“putchar()”函数时,应在程序开头写上包含命令_____,若在程序中用到 “strlen()”函数时,应在程序开头写上包含命令 ______。 「解」putchar()是系统提供的头文件stdio.h 中定义的宏,所以程序要使用它,必须写上包含命 令:#include 的字符串处理函数之一,字符串处理函数的函数原 型说明和它们用到的有关常量、数据结构等,在系 统提供的头文件string.h中定义,所以使用该函数 的程序应在程序开头写上包含命令 #include 4.下面程序的功能是输出数组s中最大元素的 下标,请填空。 main() {int k,p; int s[]={1,-9,7,2,-10,3}; for(p=0,k=p;p<6;p++) if(s[p]>s[k])____________ printf(“%d\n”,k); } 「解」为要寻找数组中的最大元素的下标,需 先预设1个临时最大元素的下标,并顺序逐一考察 数组的元素,当发现当前元素比临时最大元素更大 时,就用当前元素的下标更新临时最大元素下标。 直至考察了数组的全部元素后,这临时最大元素下 标就是数组的最大元素下标。通常预设的最大元素 下标是数组的首元素下标,考察是从首元素开始顺 序向后继元素考察。程序中,存储临时最大元素下 标的变量是k,变量p控制顺序考察的循环控制变 量。当发现当前元素s[p]比临时最大元素s[k]更大 时,应该用p更新k.所以在空框处应填入代码“k=p;”。 5.下面程序的功能是将一个字符串str的内容颠 倒过来,请填空。 main() {int i,j,_____________; char str[]={“1234567”}; for(i=0,j=strlen(str);i printf(“%s\n”,str); } 「解」颠倒一个字符串中的字符,就是首尾对 应的元素两两交换。简单地可用两个游标变量i和 j,i是前端元素的下标,j是后端元素的下标,交 换以这两个变量值为下标的元素str[i]和str[j].开始时,i的值为0,j的值为字符串末元素的下标(字 符串长度减1)。每次交换后,i增1,j减1.继续交换的条件是str[i]还位于str[j]的前面,即i 处应填入-1.程序为了交换str[i]和str[j],使用了变量k,该变量应在程序的变量定义部分中一起定义, 所以在第一个空框处应填入k. 6.以下程序可把输入的十进制数以十六进制数 的形式输出,请填空。 main() {char b[17]={“0123456789ABCDEF”}; int c[64],d,i=0,base=16; long n; printf(“Enter a number:\n”); scanf(“%ld”,&n): do{c[i]=________;i++;n=n/base;} while(n!=0); printf(“Transmite new base:\n”); for(--i;i>=0;--i) {d=c[i];printf(“%c”,);} printf(“\n”); 「解」程序中,字符数组b存储十六进制的16 个数字符,整型数组c存储译出的十六进制数的各 位数值。从整数n译出它的各位十六进制数值,需 采用除16取余的方法,即求n除16的余。得到它 的十六进制的个位数,接着将n除以16.在n不等 于0的情况下循环,能顺序求出n的十六进制的个 位数、十位数、百位数等等。程序中变量base已预 置16,所以在第一个空框处可填代码n%base。n当 的十六进制数的个位、十位、百位等数字依次存放 于数组c中后,就从最高位至最低位,参照数组c 的内容d(以其内容为下标),取十六进制数字符表 中的字符b[d]输出。所以在第二个空框处可填入代 码b[d]. 4.3程序分析题 1.阅读程序,写出程序运行结果。, main() {static int a[][3]={9,7,5,3,l,2,4,6, 8}; int i,j,sl=0,s2=0; for(i=0;i<3;i++) for(j=0;j<3;j++) {if(i==j)s1=s1+a[i][j]; if(i+j==2)s2=s2+a[i][j]; } printf(“%d\n%d\n”,sl,s2); } 「解」已知数组共有3行3列,第一行依次是 9,7,5;第二行是3,1,2;第三行是4,6,8. 程序引用数组元素的游标变量是i和j,外循环控制 变量i是数组的行下标,内循环控制变量j是数组 的列下标。循环体的工作是将数组的某些元素累计 到sl,某些元素累计到s2.将行下标i和列下标j相 同的元素累计到sl,sl=a[0][0]+a[l][1]+a[2][2].将行下标i与列下标j的和为2的元素累计到s2,s2 =a[0][2]+a[l][l]+a[2][0].所以sl是18,s2是10.程序输出: 18 10 2.说明下列程序的功能。 main() {int i,j; float a[3][3],b[3][3],x; for(i=0;i<3;i++) for(j=0;j<3;j++) {scanf(“%f”,&x)a[i][j]=x;; } for(i=0;i<3;i++) for(j=0;j<3;j++) b[j][i]=a[i][j]; for(i=0;i<3;i++) {printf(“\n”); for(j=0;j<3;j++) printf(“%f”,b[i][j]); } 「解」程序第一段两重循环,实现按行顺序输入数组a的全部元素的值。程序第二段两重循环是 将数组a转置复制到数组b.程序第三段两重循环 实现按行输出数组b的全部元素。所以程序的功能 是按行顺序输入3*3二维数组的全部元素,然后按 列顺序输出。 3.写出下列程序的运行结果。 main() {static char a[]={‘*’,‘*’,‘*’,‘*’,‘*’,‘*’};int i,j,k; for(i=0;i<5;i++) {printf(“\n”); for(j=0;j for(k=0;k<5;k++)printf(“%c”,a[k]); } printf(“\n”);} 「解」程序的外循环控制循环五次,每次开始 先输出一个换行符,共输出5行信息。对于i(自0 开始计算)行,先输出i个空白符,接着输出字符 数组a中的五个字符,由于a中的五个字符都是字 符。,所以输出五个*字符。这样程序是输出以下形 式的图案: ***** ***** ***** ***** ***** 4.说明下列程序的功能。 main() {int i,j; float a[3][3],b[3][3],c[3][3],x; for(i=0;i<3;i++) for(j=0;j<3;j++) {scanf(“%f”,&x)a[i][j]=x;; } for(i=0;i<3;i++) for(j=0;j<3;j++) {scanf(“%f”,&x);b[i][j]=x; } for(i=0;i<3;i++) for(j=0;j<3;j++) c[i][j]=a[i][j]+b[i][j]; for(i=0;i<3;i++) {printf(“\n”); for(j=0;j<3;j++) printf(“%f”,c[i][j]); } printf(“\n”); } 「解」程序第一段的功能是按行顺序输入数组 a的元素。程序第二段的功能是按行顺序输入数组 b的元素。程序第三段的功能是顺序累加数组a和 数组b的对应元素,并将和存于数组c的对应元素 中。最后,按行顺序输出数组c的全部元素。 4.4程序设计题 1.编程序,输入单精度型一维数组a[10],计 算并输出a数组中所有元素的平均值。 「解」为了计算数组元素的平均值,首先要累 计它的全部元素的和,然后除以数组元素的个数, 即得数组元素的平均值。写成C程序如下: #include main() {int i,n=10; float s,a[10];printf(“Enter%d numbers!\n”,n);for(i=0;i {scanf(“%f”,&s)a[i]=s;; } for(s=0.0,i=0;i s+=a; s/=n; printf(“平均值是%.2f\n”,s); } 2.编程序,输入10个整数存入一维数组,再按逆 序重新存放后再输出。 「解」将数组的元素逆序重新存放,就是将数 组的首尾对应元素两两交换。简单地可用两个游标 变量i和j,是前端元素的下标,是后端元素的下ij 标,交换以这两个变量值为下标的数组元素。开始 时,i的值为0,j的值为末元素的下标。每次交换 后,i增1,j减1.继续交换的 条件是i #include main() {int a[10],i,j,t,n=10; printf(“Enter%d numbers!\n”,n); for(i=0;i scanf(“%d”,&a[i]); for(i=0,j=n-1;i t=a[i];a[i]=a[j];a[j]=t; } for(i=0;i printf(“%d\t”,a[i]); printf(“\n”); } 3.编程序,输入两个字符串(<40个字符), 连接后输出(不准用系统函数). 「解」将字符串s2连接到字符串s1的计算过 程可分两个步骤完成。首先找到字符串s1的末尾, 然后参照字符串s2,将字符串s2的全部有效字符 逐一复制到字符串s1,最后在字符串s1的末尾接 上字符串结束标记符。完整程序如下: #include #define N40 main() {char s1[N],s2[N]; int i,j; printf(“Enter stringl!\n”); scanf(“%s”,s1); printf(“Enter string2!\n”); scanf(“%s”,s2); for(i=0;sl[i]!=‘\0’;i++); for(j=0;s2[j]!=‘\0’;i++,j++) s1[i]=s2[j]; s1[i]=‘\0’ printf(“sl=%s\n”,sl); } 4.编程序按下列公式计算s的值(其中x1、 (x2) xn由键盘输入): s=∑(xi-x0)(xi-x0)(其中x0是x1、 (x2) xn的平均值) 「解」输入数组x的n个元素的值,按公式计 算。程序首先输入n,设n<100,然后输入n个数 据,接着求它们的平均值,最后按计算公式求出s, 并输出。程序如下: #include #define N100 {double x[N+1],s; int i,n; do{ printf(“Enter n(<100)”); scanf(“%d”,&n); }while(n<=0||n>=100); for(i=1;i<=n;i++){ scanf(“%lf”,&s); x[i]=s; } for(s=0.0,i=1;i<=n;i++) s+=x; x[0]=s/n; for(s=0.0,i=1;i<=n;i++) s+=(x[i]-x[0])*(x[i]-x[0]); printf(“s=%f\n”,s);} 5.输入一个3X5的整数矩阵,输出其中最大值、 最小值和它们的下标。 「解」输入一个二维数组,寻找二维数组的最 大值和最小值。其中寻找最大值和最小值的工作可 用两重循环实现,即按行按列考察二维数组的元 素。程序如下: #include main() {int a[3][5],i,j,t,n=3,m=5,min, max,minrow,mincol,maxrow,maxcol; printf“Enter%d*%d numbers!,n,;(\n”m)for(i=0;i for(j=0;j scanf(“%d”,&t); a[i][j]=t; } min=max=a[0][0]; minrow=mincol=maxrow=maxcol=0; for(i=0;i for(j=0;j if(a[i][j]>max){ max=a[i][j];maxrow=i;maxcol=j; } if(a[i][j] min=a[i][j];minrow=i;mincol=j; } } printf(“MAX=a[%d][%d]=%d MIN= a[%d][%d]=%d\n”,maxrow,maxcol,max, minrow,mincol,min); } 6.输入一个字符串,将其中的所有大写字母改为 小写字母,而所有小写字母全部改为大写字母,然 后输出。 「解」程序先输入字符串,然后顺序考察输入 字符串中的字符,当发现是大写字母时,将它改写 成对应的小写字母,而当它是小写字母时,就将它 改写成对应的大写字母。若变量ch中的字符是大 写字母,则与它对应的小写字母的表达式可以写成 ch-‘A’+‘a’;类似地,若变量ch中的字符是小写 字母,则与它对应的大写字母的表达式可以写成ch -‘a’+‘A’.完整程序如下: #include #include #define N200 main() {char s[N]; int i; printf(“Enter string!\n”); gets(s); for(i=0;s!=‘\0’;i++) if(s[i]>=‘A’&&s[i]<=‘Z’) s[i]=s[i]-‘A’+‘a’; else if(s[i]>=‘a’&&s[i]<=‘z’) s=s-‘a’+‘A’; printf(“s=%s\n”,s); } 7.设某班50名学生的三科成绩表如下: 课程一课程二课程三 ……………… 试编一个程序,输入这50个学生的三科成绩, 计算并输出每科成绩的平均分。 「解」程序定义一个50行3列的二维数组, 用于存储全班学生的成绩。程序顺序输入各个学生 的三科成绩,然后按列的顺序,累计各科总分,并 计算平均分。完整程序如下: #include #define N50 #define M3 main() {int score[N][M],i,j,t; double a[M]; printf(“Enter scores!\n”); for(i=0;i for(j=0;j scanf(“%d”,&t); score[i][j]=t; } for(j=0;j for(j=0;j for(i=0;i a[j]+=score[i][j]; a[j]/=N; } for(j=0;j printf“课程%d的平均分是%.2f\n”,j+1,(a[j]); } 8.编一个程序,输入一个整型数据,输出每位 数字,其间用逗号分隔。例如,输入整数为2345, 则输出应为:2,3,4,5. 「解」程序的主要工作是从输入整数分拆出它 的十进制整数的各位数字,将分拆出来的各位数字 存于数组中,然后将这些数字自高位到低位的顺序 逐位输出。要将一个整数按十进制数的要求分拆, 需用一个循环,每次循环求出被分拆数除以10的 余数的办法来求出它的个位,每分拆出一位就将被 分拆的数除以10.循环过程直至被分拆的数为0结 束。完整程序如下: #include main() {int a[20],i,base=10; int n; printf(“Enter a number!\n”); scanf(“%d”,&n);/*整数输入*/ i=0;/*对n进行分拆,各位数字自低位到高 位存于数组a*/ do{ a[i++]=n%base; n/=base; }while(n); for(i--;i>=0;i--)/*自高位到低位输出*/ printf(“%d%c”,a[i],i>0?’,’:’\n’);} 9.编一个程序,输入一个字符串,将其中所有 的大写英文字母的代码+3,小写英文字母的代码-3. 然后输出加密后的字符串。 「解」程序的主要工作是输入字符串,并顺序 考察输入字符串中的字符,分别对其中大小写英文 字母完成问题要求的更改,而跳过不是英文字母的 字符。完整程序如下: #include #include #define N200 main() {char s[N]; int i; printf(“Enter string!\n”); gets(s); for(i=0;s[i]!=‘\0’;i++) if(s[i]>=‘A’&&s[i]<=‘Z’) s[i]+=3; else if(s[i]>=‘a’&&s[i]<=‘z’) s[i]+=3; printf(“s=%s\n”,s); } 第五章指针 5.1单项选择题 1.设有定义“int a=3,b,*p=&a;”,则下列语句中使b不为3的语句是() ①b=*&a;②b=*p; ③b=a;④b=*a; 「解」定义有int a=3,b,*p=&a;对b赋 值的表达式有*&a、*p、a、*a.引用变量a的值有 两种方法,一是直接引用a,二是通过a的指针间 接引用a.对于后者,又有多种表达方法,通过指 向a的指针p,间接引用a的内容,如*p.或通过求地址运算符由变量a得到其指针&a,再由这指针表 达式间接引用a的内容,如*&a.所以表达式*&a、 *p和a都能引用变量a的值,而使b的值为3.而表达式b=*a是错误的,因为a不是指针变量,不 能对它施行取内容运算符……所以解答是④。 2.设指针x指向的整型变量值为25,则“printf (”%d\n“,++*x);”的输出是() ①23②24③25④26 「解」若指针变量x指向某个变量,例如指向 变量v,并且变量v的值是25,则表达式++*x的 值是26.这是因为表达式的计算顺序可加圆括号表 达成(++(*x),首先是*x,是对x所指变量v的)引用,所以++*x就是++v.++v是先让变量v增1,并以增1后的v的值为表达式++v的结果,所以其 值是26.所以解答是④。 3.若有说明:“int i,j=7,*p=&i;”,则 与“i=j;”等价的语句是() ①i=*p;②*p=*&j; ③i=&j;④i=**p; 「解」指针变量p指向变量i时,表达式i=*p 等价于i=i;表达式*p=*&j等价于i=j;而表达 式i=&j企图将整型变量的指针赋给整型变量,这 是错误的;表达式i=**p也是一种错误的表达式。 p是指针,*p是p所指变量j,**p是企图将整型 变量j当作指针,并想通过j间接引用某个变量。 所以解答是②。 4.若有说明语句“int a[10],*p=a;”,对数组 元素的正确引用是() ①a[p]②p[a] ③*(p+2)④p+2 「解」在C语言中,约定数组名单独出现在表 达式中时,它表示数组首元素的指针。int a[10],有 则a可以作为&a[0]使用。另有整型指针变量p,代 码p=a实现p指向数组a的首元素。则表达式*(p +2)是引用数组元素a[2].表达式a[p]和p[a]都是不 正确的,下标必须是整型表达式,不可以是指针表 达式。表达式p+2是指针表达式,它的值是&p[2]. 所以只有表达式*(p+2)引用数组a的元素a[2]. 所以解答是③。 5.下面各语句中,能正确进行赋字符串操作的 语句是() ①char s[5]={“ABCDE”};②char s[5]={‘A’, ‘B’,‘C’,‘D’,‘E’}; ③char*s;s=“ABCDE”;④char*s;scanf (“%s”,&s); 「解」字符串最终存储于字符数组中,存储字 符串的字符数组可以是程序主动引入的(定义或动 态分配),也可以是字符串常量,由系统分配。其 中字符数组用字符串初始化就是字符串存储于由 程序引入的字符数组的例子。给字符指针赋字符串 则是系统自动分配字符串存储空间的例子。给字符 指针赋字符串并不是将一个长长的字符串存于字 符指针变量中,而是将字符串常量存储于常量区, 并将存储这个字符串的首字节地址赋给指针变量, 让指针变量指向字符串常量的首字符。对于以字符 串作为字符数组初值的情况,要求字符数组足够的 大,能存得下字符串常量。这里有一个特别的规定, 若数组的大小少于存储字符串有效字符的字节个 数,系统将报告错误;当字符数组的大小只能存储 字符串的有效字符,而不能存储字符率结束标记符 时,则存储于字符数组中的内容是字符序列,因没 有存储字符串结束标记符,存储的内容就不是字符 串。如代码char a[5]=“ABCDE”。 另外,给字符数组元素逐一赋字符初值,并在 字符初值中没有字符串结束标记符,则存于字符数 组中的内容也不是字符串。如代码char s[5]={‘A’, ‘B’,‘C’,‘D’,‘E’}.特别要注意当字符指针还未指向某个字符数组的元素时,不可以通过字符指针 输入字符串。如代码char*s;scanf(“%s”,s)。若 写成char*str;scanf(“%s”,&str)更是错误的了。由于C语言规定数组不能相互赋值,所以只能将字 符串常量赋给某字符指针。如代码char*s;s=“ABCDE”是正确的。实际上,字符串“ABCDE”被 存储于常量区中,向指针变量赋的是字符指针,让 s指向其中的字符‘A’。所以解答是③。 6.若有以下定义,则不能表示a数组元素的表 达式是() int a[10]={1,2,3,4,5,6,7,8,9,10}, *p=a; ①*p②a[10]③*a④a[p-a] 7.若有以下定义,则值为3的表达式是() int a[]={1,2,3,4,5,6,7,8,9,10}, *p=a; ①p+=2,*(p++)②p+=2,*++p ③p+=3,*p++④p+=2,++*p 「解」数组a有10个元素,分别有值1至10, 指针变量p指向a[0]①逗号表达式p+=2,* (p++)先是p+=2使p指向a[2],,接着是*p++)(,以当时P所指变量a[2]取内容3为表达式的值,同 时使p指向a[3].②逗号表达式p+=2,*++p,先 是p+=2使p指向a[2],以后是*++p,又使p增 1,让它指向a[3],并取指针p所指变量a[3]的内容 4作为表达式的值。③逗号表达式p+=3,*p++, 先是p+=3使p指向a[3],以后是*p++,表达式的 值是a[3]为4,而使p指向a[4].④逗号表达式p+ =2,++*p,先是p+=2,使p指向a[2],以后是 ++*p,因当时的*p就是a[2],++a[2]使a[2]增1, 变成4,并以4为表达式的值。所以只有p+=2, *(p++)的值是3.所以解答是①。 8.设有定义“char a[10]={”abcd“},*p=a;”,则 *(p+4)的值是() ①“abcd”②‘d’ ③‘\0’④不能确定 「解」若有char a[10]=“abcd”,*p=a,则指 针变量p指向a[0].在表达式*(p+4)中,p+4 指向a[4],*(p+4)就是a[4].由于用字符串“abcd” 给字符数组a赋初值,a[4]的值是字符串结束标记 符‘\0’。所以解答是③。 9.设有代码“int(*ptr)[10];”,其中的ptr是() ①10个指向整型变量的指针 ②指向10个整型变量的函数指针 ③一个指向具有10个元素的一维数组的指针 ④具有10个指针元素的一维数组 「解」代码“int(*ptr)[10];”的分析过程是, 因圆括号,括号内的ptr先与字符*结合,字符*修 饰标识符ptr是一种指针;接着与后面的一对方括 号结合,表示是这样的一种指针,是指向一维数组 的;再有方括号中的10,说明这种数组有10个元 素。至此,ptr是指向含10个元素的一维数组的指 针。最后,是最前面的int,表示数组元素是int类 型的。所以,是一个指向具有10个int型元素的ptr 一维数组的指针。所以解答是③。另外,要是①, 10个指向整型变量的指针,就是一个指针数组,上 述代码应写成“int*ptr[10];”,即ptr是一个有10 个指向整型变量的数组。要是②,返回值是指向10 个整型变量的函数的指针,上述代码应写成“int(* (*ptr))[10];”,即ptr是指针,指向一种函数,()函数的返回值又是一种指针,指向10个元素的数 组,数组的元素是整型的。下面的代码是这样的函 数指针和函数的例子: #include int a[][10]={{1,2,3,4,5,6,7,8,9,0},{0,1,2,3,4,5,6,7,8,9}}; int(*(*ptr)(int))[10]; int(*f(int n))[10] {return a+n; } void main() {int(*p)[10],*q; ptr=f;/*让ptr指向函数f*/ p=(*ptr)(0); q=*p; printf(“%d\n”,*q); p=(*ptr);(l) q=*p; 在上述代码中,函数有一个int型的形参。要 是④,其意义与①相同,上述代码应写成“int* ptr[10];”,即ptr是一个有10个元素的数组,数 组元素是指向整型变量的指针。 10.若有以下定义,则数值为4的表达式是)( static int w[3][4]={{0,1},{2,4},{5,8}}; int(*p)[4]=w; ①*w[1]+l②p++,*(p+1)③w[2][2]④ p[1][1] 「解」二维数组定义有多种赋初值的办法,问 题给出的代码是按行给数组的部分元素赋初值。它 们分别是w[0][0]=0,w[0][1]=1,w[1][1]=2, w[1][1]=4,w[2][0]=5,w[2][1]=8.根据约定,未 指定初值的元素自动置全0值。指针变量p是一个 指向具有四个int型元素的一维数组的指针,定义 时的初值使它指向数组W的第一行。①的代码, *w[1]+1中的w[l]是指向w[l][0]的指针,*w[1]就 是w[1][0],其值是2,*w[1]+l的值是3.②的代 码是逗号表达式,“p++,*(p+1)”先使p指向 数组w的第二行,*(p+l)中的p+l是指向数组 w的第三行,*(p+1)是指针值,指向数组w的 第三行的第一个元素,即&w[2][0].③的代码w[2][2] 引用数组w第三行的第三列元素,其值是0.④的 代码p[1][l]引用数组w第二行的第二列元素 w[1][1],其值是4.所以解答是④。 11.若有下面的程序片段,则对数组元素的错误 引用是() int a[12]={0},*p[3],**pp,i; for(i=0;i<3;i++)p[i]=&a[i+4]; pp=p; ①pp[0][1]②a[10] ③p[3][l]④*(*(p+2)+2) 「解」上述代码定义变量a是有12个整型元 素的数组,它的初值全是0.p是有三个元素的指针 数组,每个指针能指向整型变量。是指针的指针,pp 它能指向一个指向整型变量的指针,i是一个整型 变量。执行代码for(i=0;i<3;i++)p=&a[i+4] 使指针数组p的元素p[0]指向a[4],p[l]指向 a[5],p[2]指向a[6].代码pp=p使指针变量pp指 向p[0].①代码pp[0][l]用指针表达可等价地写成* (*pp+l)。其中*pp就是p[0],p[0]的值是&a[4], *pp+1的值是&a[4]+1=&a[5],(*pp+1)*就是a[5]. ②代码a[l0]当然是引用数组a的元素。③代码 p[3][1]数组p只有三个元素,没有p[3],所以是错 误的。④代码**p+2)((+2)(p+2)&p[2],中的是 *(p+2)是p[2],其值是&a[6],*(p+2)+2的 值是&a[8],*(*(p+2)+2)引用的是a[8].所以 解答是③。 12.若有如下定义和语句,则输出结果是() int**pp,*p,a=10,b=20; pp=&p;p=&a;p=&b;printf“%d%d\n”,( *p,**pp); ①10,20②10,10 ③20,10④20,20 「解」上述代码定义变量pp是指针的指针, 它能指向一个指向整型变量的指针。定义变量p是 指针,它能指向一个整型变量。a是一个整型变量, 它有初值10.b也是一个整型变量,它有初值20.代 码pp=&p使pp指向p,p=&a使p指向a,p= &b又使p指向b,不再指向a.所以*p是引用b, 其值为20.**pp是通过pp间接引用p,再通过p间 接引用b,所以也是20.所以解答是④。 13.若有以下定义和语句,则对w数组元素的 非法引用是() int w[2][3],pw)[3];pw=w;(* ①*(w[0]+2)②*pw[2] ③pw[0][0]④*(pw[l]+2) 「解」上述代码定义2行3列的二维数组w, 定义能指向有3个整型元素一维数组的指针pw, 并让pw指向数组w的第一行。①代码*(w[0]+2) 中的w[0]是&w[0][0],w[0]+2是&w[0][2],所以* (w[0]+2)就是w[0][2].②代码*pw[2]中的pw[2] 是&w[2][0],该数组w只有2行,没有w[2][0],所 以代码*pw[2]是对数组W元素的非法引用。③代码 pw[0][0]就是w[0][0].④代码*pw[l]+2)(中的pw[1]就是*(pw+l)即&w[l][0],,pw[l]+2就是&w[l][2],所以*(pw[1]+2)就是w[1][2].所以解答是②。 5.2填充题 1.“*”称为___________运算符,“&”称为_________运算符。 「解」单目运算符“*”称为取内容运算符,单目 运算符“&”称为取地址运算符。 2.若两个指针变量指向同一个数组的不同元 素,可以进行减法运算和___________运算。 「解」若两个指针变量指向同一个数组的不同 元素,可以进行减法运算求它们所指元素相差多少 元素。进行关系运算,判定它们所指元素的前后, 或是否指向同一个元素等。 3.设int a[10],*p=a;则对a[3]的引用可以 是p[______________]和*(p_________)。 「解」若指针p指向数组a的首元素,则引用 a[3]用指针p可以写成p[3]和*(p+3)。 4.若d是已定义的双精度变量,再定义一个指 向d的指针变量p的代码是___________. 「解」若d是一个双精度变量,定义能指向它 的指针变量p可以用以下代码double*p=&d. 5.&后跟变量名,表示该变量的________;*后 跟指针变量名,表示该指针变量_______.&后跟的 是指针变量名,表示该指针变量的_____________. 「解」单目运算符&是取地址运算符,&后跟 变量名,就表示该变量的地址。单目运算符*是取 内容运算符,*后跟指针变量名,表示该指针变量 所指变量的内容。若&后跟的是指针变量名,就表 示该指针变量的地址。若知道指针变量的地址,欲 通过指针变量的地址引用指针变量所指变量的内 容,需要连续两次取内容运算。 6.设有char*a=“ABCD”,则printf(“%s”,a)的输出是_______;而printf(“%c”,*a)的输出是 ______. 「解」若给字符指针变量a赋一个字符串常量“ABCD”,实际上是给a赋指向字符串常量首字符 ‘A’的指针。程序通过它访问字符串中的各字符。如 用代码printf(“%s”,a)输出这个字符串常量“ABCD”的字符列ABCD,用代码printf“%c”,(*a) 输出a所指的字符A. 7.设有以下定义和语句,则*(*(p+2)+l)的 值为__________. int a[3][2]={10,20,30,40,50,60},(*p)[2]; p=a; 「解」上述代码定义3行2列的二维数组a, #include #include main() {char str[81],*sptr; int i; for(i=0;i<80;i++) {str[i]=getchar(); if(str[i]==‘\n’)break; } str[i]=____________; sptr=str; while*sptr)putchar*sptr______________)((; } 「解」从键盘输入字符行,通过循环逐一输入 字符,当发现输入字符是换行符时,结束循环。为 了使输入的字符列变成字符串,必须在输入字符列 之后,原存储换行符的元素改为存储字符串的结束 标记符,需用代码str=‘\0’,所以在第一框填入代 码‘\0’。当要将存于字符数组str中的字符串通过循 环逐一输出字符串的字符时,可以用字符指针sptr, 让sptr遍历整个字符串,每次循环时,输出sptr所 指字符,并让sptr增1,即可用代码*sptr++实现, 所以在第二框填入代码++. 5.3程序分析题 1.阅读下列程序,写出程序的输出结果。 main() {char *a[6]={“AB”,“CD”,“EF”,“GH”,”U“,”KL“}; int i; for(i=0;i<4;i++) printf(“%s”,a[i]); printf(“\n”); } 「解」程序定义了有六个元素的字符指针数组 a,数组a的各元素指向字符率常量。 程序的for循环遍历了a的前四个元素,用字 符串输出格式,输出指针数组a前四个元素所指的 字符串。所以程序输出:ABCDEFGH. 2.阅读下列程序,写出程序的主要功能。 main() {int i,a[l0],*p=&a[9]; for(i=0;i<10;i++)scanf(“%d”,&a[i]); for(;p>=a;p--)printf(“%d\n”,*p); } 「解」程序定义了有10个元素的整型数组a, 另定义指针变量p,并让它指向a的最后一个元素 a[9].执行代码的第一个循环是顺序输人数组a的 10个元素。第二个循环利用指针p逆序遍历数组a, 将数组a的各元素逆序输出。所以程序的功能是输 入10个整数,并逆序输出这10个整数。 3.阅读下列程序,写出程序运行的输出结果。 char s[]=“ABCD”; main() {char*p; for(p=s;p } 「解]程序定义了一个字符数组s,由给它所 赋的字符串初值知,该数组只有五个元素。程序另 定义了字符指针变量p.循环开始时,先让p指向数 组的首元素。循环每次输出以p所指字符为首字符 的字符串,并让它指向下一个字符。如此反复循环 四次,所以程序输出以下内容: ABCD BCD CD D 4.阅读下列程序,试写出程序运行的结果。 main() {int i,b,c,a[]={1,10,-3,-21,7,13}, *p_b,*p_c; b=c=1;p_b=p_c=a; for(i=0;i<6;i++) {if b<*a+i){b=*a+i)p_b=&a[i];}(()(; if c>*((a+i){c=*)(a+i)p_c=&a[i];};} i=*a; *a=*p_b; *p_b=i; i=*(a+5); *(a+5)=*p_c; *p_c=i; printf“%d,(%d,%d,%d,%d,%d\n”,a[O],a[1],a[2],a[3],a[4],a[5]); } 「解]程序定义了一个整型数组。,由给它所 赋的初值知,该数组有六个元素。程序另定义了三 个整型变量i、b、c和两个指针变量p_b、p_c.程 序首先置变量b和c都为1,和p_c都指向数组p_b a的首元素a[0].接着执行六次循环,循环体由两 个if语句。第一个if语句是当b的值小于*(a+i)(就是a[i])时,将*(a+i)的值复制到b,并让 p_b指向a[i].这是在a中找最大值,将最大值存于 b,最大值元素的指针存于指针变量p_b.第二个if 语句是当c的值大于*(a+i)(就是a[i])时,将* (a+i)的值复制到c,并让p_c指向a[i].这是在 a中找最小值,将最小值存于c,最小值元素的指针 存于指针变量p_c.循环结束后的前三个语句实现 最大元素与a[0]交换。接着三个语句是在已经过前 面交换的基础上,将最小元与a[5]交换。最后程序 顺序输出数组a的六个元素。所以程序输出内容 是: 13,10,-3,l,7,-21. 若数组a的初值由输入任意指定,上述程序对 一种特殊情况不能完成功能的要求,即最小元素若 是a[0],p_c所指元素已被移到p_b指针所指位置, 实际与a[5]交换的不再是数组中的最小元素,而是 最大元素。 5.4程序设计题 1.输人3个整数,按从大到小顺序输出。 「解」存储输入的三个整数可用三个简单变量, 也可用数组。设用三个简单变量x,y,z存储输入 的三个整数。另设若干个指针变量指向存储输入数 据的变量。实现从大到小输出三个整数有多种方 案,如通过比较交换变量的值,多次比较交换使变 量满足条件x>=y>=z.这样,变量的输入值可能会 与它的输出值不一样。如通过比较交换指针变量, 当比较后发现要交换时,就交换变量的指针,而不 交换变量的值,则在比较结束后,变量的值没有改 变,但从指针方向来看,它们的值是从大到小排列 的。下面的程序就采用这种方案。 #include main() {int x,y,z; int*big=&x,*mid=&y,*sma=&z;/*置三个指 针变量分别指向x,y,z*/为变量x,y,z输入值*/ if(*big<*mid){temp=big;big=mid;mid =temp;} /*使*big>=*mid*/ if(*big<*sma){temp=big;big=sma;sma =temp;}/*使*big>=*sma*/ if(*mid<*sma){temp=mid;mid=sma;sma=temp;}/*使*mid>=*sma*/ printf(“%d\t%d\t%d\n”,x,y,z);/*按输入顺序输出x,y,z*/ printf(“%d\t%d\t%d\n”,*big,*mid,*sma);/*按从大到小的顺序输出*/ } 2.编一个程序,输入15个整数存入一维数组,再 按逆序重新存放后再输出。 「解」输入数组的元素,并重新颠倒存放后输 出。将存储于数组中的元素颠倒存储,只要首尾相 对应的元素两两交换即可。若用指针实现,可让一 个指针p指向前端的元素,另一个指针q指向与前 端元素对应的后端的元素。循环前,让p指向数组 的首元素,让q指向数组的末元素。循环时,让p 和q所指两个元素交换,并让p增1,q减l.循环条件是p所指元素在前,q所指元素在后,即p<q. 程序如下: #include main() {int a[15],*p,*q,temp; printf(“Enter15numbers.\n”); for(p=a;p<a+15;p++) scanf(“%d”,p); for(p=a,q=a+14;p<q;p++,q--) { temp=*p;*p=*q;*q=temp; } for(p=a;p printf(“%d\t”,*p); printf(“\n”); } 3.输入一个字符串,按相反的次序输出其中的 全部字符。 「解」要相反的次序输出字符串的全部字符, 可用一个字符指针变量,从指向字符串的本字符开 始,逆序遍历字符串,输出指针所指字符即可。但 为了让字符指针指向字符串的末字符,若不用字符 串处理库函数,得用一个循环,让它从字符串的首 字符开始,顺序移至字符串的结束标记符,然后倒 退一个字符,就能让它指向字符串的末字符。程序 如下: #include #define N200 main() {char s[N],*p; printf(“Enter a string.\n”); scanf(“%s”,s); for(p=s;*p;p++); for(p--;p>=s;p--)printf(“%c”,*p); printf(“\n”); } 4.输入一个一维实型数组,输出其中的最大值、 最小值和平均值。 「解」设实型数组的元素个数n不超过20.程 序输入n,并用循环输入数组的元素,再用循环遍 历数组,求出数组的最大值和最小值、数组元素的 和。然后求出数组元素的平均值,最后输出结果。 #include #define N20 main() {double a[N],max,min,ave,*p,t; int n; printf(“Enter n(0<n<20)。\n”); do{ scanf(“%d”,&n); if(n>0&&n<20)break; printf“n值不合要求,(请重新输入!;\n”)}while(l); printf(“输入%d个实数\n”,n); for(p=a;p scanf(“%lf”,&t); *p=t; } max=min=ave=*a; for(p=a+l;p if(max<*p)max=*p; if(min>*p)min=*p; ave+=*p; } ave/=n; printf(“最大值:%f\t最小值:%f\t平均值: %f\n”,max,min,ave); } 5.输入一个3×6的二维整型数组,输出其中的 最大值、最小值及其所在的行列下标。 「解」找出其最大值和最小值,及它们的行列 位置。采用按行按列顺序遍历数组的方法找出数组 的最大值、最小值,以及它们在数组中的位置指针。 输出时,将位置指针转换成行下标和列下标。程序 如下: #include #define N3 #define M6 main() {int a[N][M],*maxp,*minp,*q,t; printf(“输入%d个整数\n”,N*M); for(q=a[0];q<*a+N*M;q++){ scanf(“%d”,&t);*q=t; } maxp=minp=*a; for(q=a[0];q<*a+N*M;q++){ if(*maxp<*q)maxp=q; if(*minp>*q)minp=q; } printf(“最大值:%d它的行下标是%d它的列 下标是%d\n”,*maxp,(maxp-*a)/M,maxp-*a)(%M); printf(“最小值:%d它的行下标是%d它的列 下标是%d\n”,*minp,(minp-*a)/M,(minp-*a)%M); } 6.输入三个字符串,找出其中最大的字符串。 「解」将输入的三个字符率分别存于三个一维 字符数组中,另用一个字符指针数组,分别指向这 三个字符串,然后用循环控制这三个字符串的比 较,找出最大的字符串。两字符串比较时,程序不 用标准库函数,而用两字符串的对应字符比较来实 现。完整程序如下: #include #define N120 #define M3 mian() {char s1[N],s2[N],s3[N],*strs[M]={s1,s2,s3},*p,*q,*ms; int i; printf(“输入%d个字符串\n”,M); for(i=0;i scanf(“%s”,strs[i]); ms=strs[0]; for(i=1;i for(p=ms,q=strs[i];*p!=‘\0’&& *p==*q;p++,q++);if(*p<*q)ms=strs[i]; } printf(“最大字符串:%s\n”,ms); } 7.输入两个字符串,将它们连接后输出。 「解」程序设有两个存储字符串的数组,先输 入两个字符串,然后找到第一个字符串的末尾,接 着将第二个字符串复制在第一个字符串的后面,然 后输出。程序如下: #include #define N120 main() {char s1[N+N],s2[N],*p,*q; printf(“输入2个字符串\n”); scanf(“%s%s”,s1,s2); for(p=sl;*p!=‘\0’;p++); for(q=s2;*p++=*q++;;) printf(“两字符串连接后:%s\n”,sl); } 8.比较两个字符串是否相等。 「解」程序设两个存储字符串的数组,先输入 两个字符串,两字符率比较时,直接用两字符串的 对应字符比较来实现。完整程序如下: #include #define N120 main() {char sl[N],s2[N],*p,*q; char*result[]={“小于”,“相等”,“大于”}; int comp; printf(“输入2个字符串\n”); scanf(“%s%s”,s1,s2); for(p=sl,q=s2;*q!=‘\0’&&*p==*q; p++,q++); comp=*p<*q?0:*p==*q?l:2; printf(“字符串1与字符串2比较:%s\n”,result[comp]); } 9.输入10个整数,将其中最大数与最后一个 数交换,最小数与第一个数交换。 「解」程序设一个一维数组存储输入的10个 整数。然后遍历数组,找出最大元素和最小元素的 指针。接着按要求先将最大元素与最后一个元素交 换,然后将最小元素与第一个元素交换。最后,输 出数组中的全部整数。程序应考虑到这样一种特殊 情况,即最后一个元素正是最小元素,它在与最大 元素交换后,位置已移到原先存储最大元素的位 置。程序应保证最大元素移到末尾,最小元素移到 最前端。 程序如下: #include #define N10 main() {int a[N],*maxp,*minp,*q,t; printf(“输入%d个整数\n”,N); for(q=a;q scanf(“%d”,&t); *q=t; } maxp=minp=a;