文章教程

全国计算机等级考试二级C语言真题汇编与专用题库二、二级C语言程序设计选择题参考答案及解析

8/24/2020 9:04:40 PM 人评论 次浏览

二、二级C语言程序设计选择题参考答案及解析

(一) C语言概述

(1)A 【解析】使用顺序、选择(分支)、循环3种基本结构构成的程序可以解决所有问题,而不只是解决简单问题,所以A选项错误。

(2)B 【解析】滥用GOTO语句将使程序的流程毫无规律,可读性差,对于初学者来说尽量不要使用,所以A选项错误。一个结构化程序可以包含顺序、分支和循环结构中的一种或多种,所以C选项错误。由3种基本结构构成的程序可以解决任何复杂的问题,所以D选项错误。

(3)D 【解析】计算机能直接执行的程序是二进制的可执行程序,扩展名为.exe,所以选择D选项。

(4)A 【解析】程序模块化思想中,可以采用自顶向下、逐步细化的方法,所以A选项中“自底向上”的说法是错误的。

(5)A 【解析】C语言中的非执行语句不会被编译,不会生成二进制的机器指令,所以A选项错误。由C语言构成的指令序列称C源程序,C源程序经过C语言编译程序编译之后,生成一个后缀名为.obj的二进制文件(称为目标文件);最后要由“连接程序”把此obj文件与C语言提供的各种库函数连接起来生成一个后缀为.exe的可执行文件。

(6)B 【解析】在一个C语言程序中可以进行多种算法的实现,对算法的个数没有规定,所以B选项错误。

(7)B 【解析】C语言中注释语句的注释方法是:/*注释内容 */ 或 //注释一行。所以A选项与C选项错误。D选项中预编译命令include<stdio.h>前丢掉了“#”号,所以选择B选项。

(8)C 【解析】任何一个C程序都是从主函数main开始,至主函数main结束,所以选择C选项。

(9)A 【解析】C语言中的主函数唯一为main()函数,不能任意指定,所以B选项错误。C语言从主函数main()开始,到主函数main()结束,所以C选项错误。主函数必须写成小写的main,不能混淆大小写,所以D选项错误。

(10)C 【解析】算法的特征:①有穷性,一个算法(对任何合法的输入)在执行有穷步后能够结束,并且在有限的时间内完成;②确定性,算法中的每一步都有确切的含义;③可行性,算法中的操作能够用已经实现的基本运算执行有限次来实现;④输入,一个算法有零个或者多个输入,零个输入就是算法本身确定了初始条件;⑤输出,一个算法有一个或者多个输出,以反映出数据加工的结果,所以C选项错误。

(11)D 【解析】C语句可以跨行来写,但是必须以分号结束,所以A选项错误。C程序中的一行可以有多条语句,所以B选项错误。C语言中的注释语句可以与原语句放在一行,也可以不放在一行,所以C选项错误。

(12)D 【解析】C语言编写的程序可以放置于多个程序文件中,所以A选项错误。C程序中的一行可以有多条语句,所以B选项错误。C语言中的注释语句可以与原语句放在一行,也可以不放在一行,所以C选项错误。

(13)D 【解析】C语言的数值常量中不能夹带空格,所以A选项错误。C语言中的变量都必须先定义再使用,对变量的定义通常放在函数体内的前部,但也可以放在函数外部或复合语句的开头,不能随便放置,所以B选项错误。在C语言中,运算符两侧的运算数据类型可以不一致,且结果与精度较高的保持一致,所以C选项错误。

(14)B 【解析】一个C语言程序可以实现多种算法,可以由多个程序文件共同构成。一个C语言程序可以由一个或多个函数组成,一个C函数可以单独作为一个C程序文件存在,被包含到其他程序中,所以选择B选项。

(15)A 【解析】C语言源程序名的后缀是.C,目标文件的扩展名是.obj,可执行文件的扩展名是.exe。

(16)C 【解析】C程序中主函数不能被其他函数调用,所以A选项错误。main函数可以放在程序开始,也可以放在中间,也可以放在最后,位置不固定,但程序执行时必须从main函数开始,所以B选项错误。在C程序的函数中不能定义另一个函数,可以声明或调用另一个函数,所以C选项正确。每个C程序中必须包含一个main函数,但不一定是每个C程序文件中都必须有,用户单独编写的某个函数也可以存储为一个C程序文件,所以D选项错误。

(17)A 【解析】C语言程序是由函数组成的,所以B选项错误。C语言函数可以单独进行编译,所以C选项错误。每个C程序中必须包含一个main函数,但不一定是每个C程序文件中都必须有,用户单独编写的某个函数也可以存储为一个C程序文件,所以D选项错误。

(18)D 【解析】注释语句不参与程序的运行,所以a与b没有被赋值,其值仍然为0,所以运行的结果为a+b=0。

(19)B 【解析】C程序在运行过程中的所有计算都以二进制方式进行,所以B选项错误。

(20)A 【解析】C语言中标识符由字母、下画线、数字组成,且开头必须是字母或下画线。另外,关键字不能作为标识符。因为C语言中区分大小写,所以B选项中的“FOR”可以作为标识符来用。A选项中含有非法字符&,所以其不合法。

(21)D 【解析】C语言中的标识符由字母、下画线、数字组成,且开头必须是字母或下画线,所以D选项中的连接符不合法。

(22)A 【解析】C语言中的标识符由字母、下画线、数字组成,且开头必须是字母或下画线。另外,关键字不能作为标识符。B选项中以数字8 开头,所以错误。C选项与D选项中用的是关键字void与unsigned,所以错误。

(23)D 【解析】C语言规定,变量命名必须符合标识符的命名规则。D选项中包含了非法字符“$”,所以错误。标识符由字母、数字或下画线组成,且第一个字符必须是大小写英文字母或者下画线,而不能是数字。大写字符与小写字符被认为是两个不同的字符,所以For不是关键字for。

(24)C 【解析】C语言规定,变量命名必须符合标识符的命名规则,C选项中包含了非法字符“-”,所以错误。标识符由字母、数字或下画线组成,且第1 个字符必须是大小写英文字母或者下画线,而不能是数字。

(25)A 【解析】C语言中标识符的定义中区分大小写,所以printF与printf不一样,可以作为标识符,而case是C语言中的关键字,不能作为变量名。scanf是标准的输入函数, printf是标准的输出函数,所以选择A选项。

(26)D 【解析】C语言中的标识符由下画线、字母和数字组成,且必须以下画线或字母开始,所以只有D选项正确。

(27)D 【解析】A选项中整型常量应表示为1200,不能包含“,”。B选项中E后面的指数必须为整数。C选项中转义字符以“\”开始,若要表示字符“\”,应写为“\\”。

(28)B 【解析】要想表示字符串常量,应该用双引号表示,即"cd",单引号用于表示字符常量,所以B选项中的表示方法错误。

(29)A 【解析】C语言中,常量是指在程序运行过程中其值不能被改变的量,变量是指运行过程中其值可以改变的量,二者不能混淆,所以A选项错误。

(30)A 【解析】A选项中E后面的指数必须为整型数据,所以错误。C选项中011 表示的是八进制常量,0xabcd表示的是十六进制常量。

(31)C 【解析】C选项中不能含有逗号,所以“1,234”不能用作C程序的合法常量。B选项表示的是八进制的常量,D选项表示的是十六进制的常量。

(32)B 【解析】\0,空值,其ASCII码值为0,所以B选项的值为1。字符0的ASCII码值为048,所以A、C、D选项的值均不为1。

(33)A 【解析】C语言中,八进制整型常量的开头数字是0,十六进制整型常量的开头数字是0x。C语言中的实型常量有两种表示形式:小数形式,表示的实型常量必须要有小数点;指数形式,以“e”或“E”后跟一个整数来表示以10为底数的幂数,且规定字母e或E之前必须要有数字,且e或E后面的指数必须为整数。B选项中028错误,八进制中没有数字8。C选项中4e1.5 中e后面的指数不是整数。D选项中3.e5小数点后面缺少数字。

(34)A 【解析】A 选项中115L 表示115 是长整型数据,合法。B选项是八进制常量的表示方法,但是在八进制中不能含有数字8,所以B选项错误。C选项中e后面应该是整数,而不能是小数1.5,所以C选项错误。D选项中八进制常量应该是数字“0”开始,而不是字母“o”开始。

(35)D 【解析】在C语言中,整型常量可以用十进制、八进制和十六进制等形式表示,但不包括二进制,所以选择D选项。

(36)B 【解析】A选项中E后面的指数必须为整数。C语言规定,E之前必须要有数字,所以C选项错误。E后面必须要有数字,且必须为整数,所以D选项错误。

(37)D 【解析】D选项中将字符串常量“aa”赋给字符变量a是错误的。

(38)C 【解析】转义字符中,八进制的表示形式为\ddd,但是八进制中不能包含数字8,所以C选项不合法。

(39)A 【解析】根据题意可知,小写字母比与之对应的大写字母的ASCII码大32。A选项中字符A加上c表示的大写字符再对字母个数26取余,本身这个表达式没有任何含义,所以选择A选项。

(40)B 【解析】C语言中,字符串是用一对双引号括起来的字符序列,并用字符型数组来存放,故C选项和D选项不属于字符串,A选项定义的是一个字符变量str,却用来存放字符串,显然也不正确,因此B选项正确。

(41)A 【解析】字符串比较大小是以第1 个不相同字符的大小为标准的,跟长度没有关系,B选项不正确;字符串比较大小除了使用库函数strcn3()以外,就只能靠自己写代码来实现了,而不能通过关系运算符来比较大小。因为字符串在表达式中相当于const char*,即常字符指针,代表的是字符串的首地址,关系运算符会将两个字符串的首地址值比较大小,这是毫无意义的,因此C选项不正确。C语言中只有字符串常量而没有字符串变量,D选项描述不正确。空串的长度为0,而以空格打头的字符串的长度至少为1,因此A选项正确。

(42)D 【解析】本题考查的知识点是字符串常量。在C语言中,字符串常量是以双引号括起来的字符序列,因此B选项和C选项不正确。字符序列中可包含一些转义字符,转义字符都是以“\”开头的。A选项中包含了3个“\”,前两个(\\)代表了一个“\”字符,后面一个和“"”一起(\")被看作一个“"”,所以该字符串缺少一个结束的“"”,因此不正确。D选项的两个“"”之间没有任何字符,代表的是一个空串,是合法的字符串常量,因此D选项正确。

(43)B 【解析】A选项语句中的b变量还没有定义,不能直接用于给a变量赋值。C选项语句中,*b、*c表示的是一个实型变量的地址,不能再将&b赋值给指针型变量c。D选项语句中,a=0.0后面应该为逗号,不能是分号。

(44)C 【解析】C语言中没有逻辑类型,所以C错误。若要保存带有多位小数的数据,可以用单精度类型,也可以用双精度类型。处理包含不同类型的相关数据可以定义为结构体类型。整数类型可以无误差地表示自然数。

(45)D 【解析】C语言中利用sizeof()函数判断数据类型长度,在VC 6.0平台中,int型数据占有4 个字节,double型数据占有8个字节。

(46)D 【解析】题中变量w定义为double型,函数fun2()定义为int型,按照各类数值型数据间的混合运算,整型数据被转换为实型数据,因此D选项正确。

(二) 运算符与表达式

(1)B 【解析】先将整型数据9 强制转换成double型,然后除以2,得到的结果与double型保持一致,即为4.5,然后将4.5强制转换成整型数据4,然后计算9% 2的值为1,最后计算4-1的值为3,所以选择B选项。

(2)A 【解析】条件表达式“x=表达式1?表达式2:表达式3”的含义是:先求解表达式1,若为非0(真),则求解表达式2,将表达式2的值赋给x;若表达式1的值为0(假),则求解表达式3,将表达式3的值赋给x。本题中与表达式1:(x-y)等价的是(x-y<0||x-y>0)。

(3)A 【解析】选项A是非法的表达式,C语言中没有< > 运算符。

(4)C 【解析】算术运算符+的优先级高于-=,且-=的结合方向为自右向左,所以表达式x-=x+x可以表示成x=x-(x+x)=10-(10+10)= -10,选择C选项。

(5)A 【解析】A选项中逗号表达式先计算第一表达式2*x,然后计算表达式x+=2的值,即x=x+2即4,整个逗号表达式为第二个表达式的值4,所以选择A选项。B选项中首先计算逗号表达式中第一表达式x++,此时x为3,再执行第二个表达式2*x=2*3=6,所以逗号表达式为第二个表达式的值6。C选项的赋值表达式可以表示为x=x*(1+x)=2*(1+2)=6。D选项中的表达式可以表示为x=x*(x+1)=2*3=6。

(6)A 【解析】先计算x/y,结果为1,然后计算0.9+1,结果为1.9,但由于变量z为整型,取值1,所以z的值为1。

(7)D 【解析】计算5/2,结果取整数值2。计算3.6-2,结果与高精度数据保持一致,即为1.6。计算1.6 +1.2,结果为2.8。计算5% 2,结果为1。计算2.8+1结果为3.8。所以选择D选项。

(8)B 【解析】C语言中没有“< >”运算符,所以A选项错误。“%”运算符的两个操作值必须为整型数据,所以B选项正确。a*y的结果为double型,所以C选项错误。不能将值赋给像x+y这样的表达式,所以D选项错误。

(9)A 【解析】B选项与D选项中取模运算符%的左右两个操作数均应为整数,所以错误。C选项中不能将x+y的值赋给表达式y*5,所以C选项错误。

(10)C 【解析】z=x++,y++,++y;因为赋值运算符的优先级高于逗号运算符的优先级,所以可以将上式表示成(z=x++),(y++),(++y)。然后从左向右先计算表达式z=x++,因为x++先使用后自增,所以z的值为1,x的值为2。再计算逗号表达式第二个表达式y++,此时y的值为2,最后计算第三个表达式++y,y的值为3。

(11)A 【解析】“do{*t++=*s++;}while(*s);”不能因为当*s= '\0'时,while(*s)跳出循环,这样字符串结束标志'\0'没有复制给*t,造成*t不完整。注意,*t++=*s++是先执行t=*s,然后才进行t=t+1,s=s+1。B、C、D选项都能将'\0'复制过去。

(12)C 【解析】 ++k,先使得k的值自增1后再使用,k++是先取得k的值再将k的值自增1,所以C选项中表达式的值为0,而其他3个表达式的值均为1,所以选择C选项。

(13)B 【解析】由于自加运算符++的运算级别高于间接运算*的运算级别,所以B选项的表达式*p++不能使变量year中的值增至2010,因此选择B选项。

(14)B 【解析】取模运算符“%”、二元运算符具有左结合性,参与运算的量均为整型。B选项中的a变量是double实型,不符合规定。

(15)B 【解析】A选项中不能将变量y赋给表达式,C选项的错误与A选项一样,D选项中强制类型转换表达式应写成(double)x/10。

(16)A 【解析】B选项中运算符“%”的前后必须为整数,C选项中不能将变量赋给表达式x+n,D选项中不能将表达式4+1赋给常量5。

(17)D 【解析】A选项中变量类型符double后面不能有逗号。B选项中变量b不能先使用再定义,应该写成D选项中的格式。C选项中变量a后面应该是逗号而不是分号。

(18)A 【解析】不能将变量或常量赋给一个表达式,所以A选项中(b=4)=3是错误的。

(19)C 【解析】首先计算a=9,然后计算a-=9,即a=a-9,结果为0,然后计算a+=0,即a=a+0,所以最终结果为0。

(20)A 【解析】首先打印b=a+b=1+0=1的值1,此时已给b赋值为1,然后打印a=2*b=2*1=2的值2,所以结果是1,2。

(21)B 【解析】无符号整型变量a的值为8,二进制表示为00001000,右移3位后为00000001,即十进制的1,所以输出1。

(22)B 【解析】& 按位与,如果两个相应的二进制位都为1,则该位的结果值为1,否则为0。| 按位或,两个相应的二进制位中只要有一个为1,该位的结果就为1。2的二进制为00000010,4的二进制为00000100,所以做或运算的结果为00000110,该数与 5 即 00000101 做与操作的结果为00000100,即4。

(23)B 【解析】b为2,二进制为00000010,执行左移两位操作后为00001000,然后与a 00000001做异或运算的结果为00001001,即十进制的9。

(24)C 【解析】本题考查位运算,属于基础知识。题目中的整型变量 8,二进制表达为00001000,右移一位为00000100,即4,C选项正确。

(25)A 【解析】本题考查位运算符以及相关运算。^为按位或,&为按位与,那么a^b为3,再与c按位与仍然为3,所以答案为A选项。

(26)D 【解析】本题考查位运算符。题目中将a向左移两位,左移两位表示乘以4,所以答案为8,D选项正确。

(27)B 【解析】本题考查位运算。题目中将4 向左移一位然后重新赋值给a,4左移一位为8,程序运行结果为8, B选项正确。

(28)D 【解析】本题考查位运算以及按位或操作。将a左移两位相当于是将a乘以了4,所以a< <2等于20,二进制表示为00010100,与b按位或运算得到00010101,即21,所以D选项正确。

(29)B 【解析】本题考查逻辑异或运算。异或运算只有在两个比较的位不同时其结果为1,否则结果为0,题目中两个值相同,所以结果为0。

(三) 基本语句

(1)A 【解析】scanf按照格式字符进行输入,所以123与回车的值分别送入了c1、c2、c3、c4变量的存储空间。get-char()函数的功能是从键盘输入的字符串中读入一个字符,所以4送入了变量c5的存储空间,5送入了变量c6的存储空间,所以打印时结果为1245。

(2)D 【解析】按照从键盘输入的数据可以判断字符1给了变量a,字符2给了变量b,字符<CR>即回车给了变量c,字符3给了变量d,所以打印输出的结果为D选项。

(3)B 【解析】本题考查字符处理函数和文件做操函数,属于基础知识。其中B选项的getchar函数用于从终端读入字符。

(4)B 【解析】在C语言中,等于号用“==”表示,一个“=”表示赋值,所以A选项错误。C、D 选项的含义都是如果输入的字符为“N”,则打印输出,所以正好和题意相反。

(5)B 【解析】B选项输出的格式为%d,即为整型格式,所以输出字符A的ASCII码值65,而不是字符A。由于大写字母比和其对应的小写字母的ASCII码值小32,所以A选项正确。字符A的ASCII码值就是65,所以以% c格式输出可以输出字符A,所以C选项正确。由于字符A的ASCII码值比字符B的小1,所以D选项正确。

(6)D 【解析】打印时以%d整型格式打印输出,所以字符标量c1的值打印出来就是65,从c2-2的值打印出来就是68-2,即66,所以选择D选项。

(7)A 【解析】本题目中字符变量c1是字符A的ASCII码加上4,即69所对应的字符E。字符变量c2是字符A的ASCII码加上3,即68所对应的字符D。但是打印输出时,c1以% c的格式输出,所以是E,c2以% d的格式输出,所以是68。

(8)A 【解析】printf函数中格式字符“% 8.6”的含义是:变量y的输出宽度为8(包括小数点),小数点后面保留6位小数,且右对齐,所以选择A选项。

(9)D 【解析】scanf()的格式控制串可以使用其他非空白字符,如本题中的逗号,但在输入时必须输入这些字符,以保证匹配,所以逗号必须输入。

(10)C 【解析】输入数据的格式必须与scanf()的格式控制串完全匹配,如果A、B、C选项中在数字10后面均输入了空格,则会将空格赋给变量c1,而不是把X赋给c1,所以选择C选项。

(11)C 【解析】输入数据的格式必须与scanf()的格式控制串完全匹配,所以输入时必须在3和5之间输入“;”。

(12)C 【解析】本题重点考查的知识点是标准输入函数scanf()。scanf()函数要求,除了第一个参数为格式化字符串以外,其余参数均为相应变量的地址值。本题中,只有p是地址值,因此C选项正确。

(13)A 【解析】在格式字符前加入一个整数可以指定输入数据所占的宽度,所以赋值时会将87赋给变量a,把6.0赋给float型变量 b。

(14)D 【解析】在输入多个数据时,若格式控制串中无非格式字符,则认为所有输入的字符均为有效字符,所以应按D选项的顺序输入数据。

(15)A 【解析】它是格式输入函数,即按用户指定的格式从键盘上把数据输入到指定的变量之中。其中的格式命令可以说明最大域宽。在百分号(%)与格式码之间的整数用于限制从对应域读入的最大字符数。所以j的值为55,y的值为566.0,字符数组name为7777abc。

(四) 选择结构

(1)A 【解析】算术运算符的优先级高于关系运算符的优先级,所以当x为大于1的奇数时,A选项的值为假,即0。B选项的值为不定值,但绝对不是0。C选项的值为真,即1。D选项的值为真,即1。

(2)A 【解析】逻辑或“||”要求只要两边的运算对象有一个非零,结果就为真。虽然不知道a的值,但是若a为1,则左边运算对象为1;若a的值不是1,则右边运算对象的值为1,所以总能保证一边非零。

(3)D 【解析】逻辑或运算符中只要有一个运算量为真,结果就是真,当c>=2 && c<=6条件不成立时,c的值肯定不是2、3、4、5、6,所以c!=3与c!=5均成立,所以D选项的结果一定为真。

(4)B 【解析】else总是和最近的if配对,所以进入第一个if语句中进行条件判断时,因为是逻辑与操作,需要两边运算对象的值均为非零值才为真,所以需要逐个执行判断的结果为1,不再执行第二个case语句中的操作。进入第二个if语句条件判断,因为b!=2 条件成立,所以整个条件表达式的值为真,不再执行逻辑或的第二个运算对象(c--!=3)c的值不变,也不再执行第一个else语句。打印a的值1, b的值3,c的值3。

(5)A 【解析】C语言的逻辑运算符比较特别,它的操作数没有明确的数据类型,可以是任意合法的表达式,所以选择A。

(6)B 【解析】本题考查逻辑运算符的相关概念。逻辑与若要为真,那么两边都要为真,所以需要m能被5和7整除都余1,所以选项B正确。

(7)D 【解析】if语句中的表达式可以是任意合法的数值,如常量、变量表达式,所以D选项正确。

(8)C 【解析】公式的要求是无论x大于0还是小于0, y的值都为x绝对值的开方。选项C中,如果x值小于0,则y=sqrt(x)就要出错。

(9)C 【解析】A、B、D选项的含义均为:a的值如果为0,打印y的值,否则打印x的值。而C选项的含义是:a的值为0时打印x的值,不为0时打印y的值,与其他选项正好相反。

(10)C 【解析】本题中if(a=1)b=1;与else d=3;之间多了语句c=2;,所以会出现else语句的位置错误的编译失败提示。

(11)B 【解析】本题中a>b的条件不满足,所以不执行逗号表达式a=b,b=c;的操作,而是执行c=a操作,即c的值为10。

(12)C 【解析】由于a不小于b,所以所有选项中的条件都为假,A选项中实际执行了 a=b;b=c;两个操作。而B、C、D选项由于条件不成立,所以什么也没有做,所以选择C选项。

(13)D 【解析】根据代码可知,如果x的值小于3,执行空语句,不进行打印操作;如果x的值大于3,再判断x的值是否不等于10,如果不等于10,就打印x的值,所以选择D选项。

(14)D 【解析】在if else语句中,else总是与离它最近的if配对。本题中x为1,所以!x为0,所以执行else if语句中的内容,判断(x==0)是否成立,因为x为1,所以条件不成立,所以else if 内部的if…else语句不再执行,y的值还是初始值0。

(15)B 【解析】题目中嵌套语句的含义是当a<b且a<c成立时,将a的值赋给k,如果a<b成立而a<c不成立,则将c的值赋给k。如果a<b不成立而b<c成立,则将b的值赋给k,如果a<b不成立且b<c也不成立,则将c的值赋给k。判断条件表达式,只有B选项可以表示这个含义。

(16)A 【解析】else总是与离它最近的if配对,所以第一个if语句的判断条件不成立,不再执行第二个if语句和与第二个if语句配对的else语句,而是直接执行打印x++的操作,打印x的值1以后再加1。

(17)B 【解析】条件表达式的含义是,如果表达式1成立,结果为表达式2的值,如果不成立,则为表达式3的值。所以题干中k的值这样取值:如果a>b且b>c,k值结果为1,如果a>b且b<c,则值为0。如果a<b,k值为0,也就是只要a>b与b>c中只要有一个条件不成立,k的值就为0,所以选择B选项。

(18)B 【解析】case常量表达式只是起语句标号作用,并不使该处进行条件判断。在执行 switch 语句时,根据switch的表达式,找到与之匹配的case语句,就从此case子句执行下去,不再进行判断,直到碰到 break或函数结束为止。所以执行内层switch(y)时只执行了a++,此时a的值为1,然后执行外层case 2语句的a++;b++;,a为2,b为1,所以结果为B选项。

(19)D 【解析】case常量表达式只是起语句标号作用,并不使该处进行条件判断。在执行 switch 语句时,根据switch的表达式,找到与之匹配的case语句,就从此case子句执行下去,不再进行判断,直到碰到 break或函数结束为止。简单地说,break是结束整个循环体,而continue是结束单次循环。B选项中当产生的随机数n为4 时要执行打印操作。C选项中当产生的随机数为1和2时分别执行case3与case4后面语句的内容。由于存在break语句,所以for循环不是固定执行8次,执行次数与产生的随机数n有关系。

(20)A 【解析】B选项中switch((int)x);语句中不应该有最后的分号。switch(expr1)中的expr1不能用浮点类型或long类型,也不能为一个字符串,所以C选项错误。case后面常量表达式的类型必须与switch后面表达式的类型一致,所以D选项错误。

(21)D 【解析】第一次循环 i 为0,i% 2 为0,执行switch(a[0]% 2)中的case 0语句后内容即a[0]++,a[0]的值变成3;第二次循环i的值为1,i% 2为1,执行case 1:a[i]=0;,所以a[1]的值变成0;第三次循环i的值为2,i% 2为0,执行switch(a[2]% 2)中的case 1语句后的内容a[2]--, a[2]的值变成4;第四次循环i的值为3,i% 2为1,执行case 1:a[i]=0;,所以a[3]的值变成0。

(22)A 【解析】default语句在switch语句中可以省略,所以B选项错误;switch语句中并非每个case后都需要使用break语句,所以C选项错误;break语句还可以用于for等循环结构中,所以D选项错误。

(23)C 【解析】向switch语句块传送参数后,编译器会先寻找匹配的 case 语句块,找到后就执行该语句块,遇到break跳出;如果没有匹配的语句块,则执行default语句块。case与default没有顺序之分。所以第一次循环,k的值为1,执行c+=k,c的值为1,再执行case 2 后的语句c++,c的值为2,遇到break语句跳出循环;第二次循环,k的值为2,执行case 2 后面的语句c++,c的值为3,跳出循环。

(24)C 【解析】k的值为5,逐个对case语句进行匹配,均不匹配,执行 default 下的语句 n =0;k - -;,再执行case2:后面的空语句与 case4:后面的 n +=2;k --;,执行break语句跳出switch判断,打印n的值,即2。经过第一次循环后,k的值为3,然后进行k>0 && n<5条件判断为真,第二次执行循环体,执行case3:后面的n+=1;k- -;,再执行break语句跳出循环,此时打印n的值3,此时k的值为2。第三次执行循环体k的值为2,满足条件,执行case2:case4:后面的语句n+=2,k--,跳出循环体,打印n的值5。此时n不小于5,条件k>0 && n<5不成立了,所以结束循环。整个程序的打印结果为235。

(25)B 【解析】switch 语句的执行流程是:首先计算switch后面圆括号中表达式的值,然后用此值依次与各个case的常量表达式进行比较,若圆括号中表达式的值与某个case后面的常量表达式的值相等,就执行此 case后面的语句,执行后遇break语句就退出switch语句;若圆括号中表达式的值与所有case后面的常量表达式都不等,则执行default后面的语句,然后退出。所以输入1时打印65,输入2时打印6,输入3时打印64,输入4时打印5,输入5时打印6。

(26)A 【解析】if语句的含义是:如果a的值为1,将b的值赋给a,否则将a的值自增1。是switch(a==1)中表达式a= =1的结果如果为真,即为1,则从case1开始执行,直到遇到break语句跳出switch语句,如果a==1的结果为假,即0,则从case0开始执行,所以与题干含义执行操作相反的是选项A中的语句。

(五) 循环结构

(1)B 【解析】执行y--直到值为0,由于y--是先用再减,所以退出循环时,y的值为-1。

(2)A 【解析】 --k先自减再使用,所以第一次判断条件即为while(4),条件为真执行打印k的值k=4-3,结果为1,第二次判断条件即为while(0),条件为假,结束循环,打印回车换行符,所以选择A选项。

(3)A 【解析】首先 char *s 接受一个字符型数组的首地址,并将这个首地址赋给另一个字符型指针 char*t, while(*t++)不断循环直到 *t 为'\0',再将 t-1,这时字符指针 t 指向字符串的最后一个字符,又因为s 指向字符数组的首地址,即字符串的首地址,所以 return(t-s)便是返回字符数组中字符串的长度。

(4)C 【解析】本题重点考查的知识点是while循环语句的应用。aaa()函数中,首先定义了一个字符指针t指向形参s,然后通过一个while循环让指针t不断递增,直到t指向字符串结束标识处。当t指向结束标识处时,由于后缀++运算符的原因,它还会被再递增1,所以接下来的t--语句让它回到结束标识处。最后返回t-s,s还是指向字符串第一个字符处,而t指向了字符串结尾,故返回值为字符串的长度值,因此C选项正确。

(5)B 【解析】while语句中条件表达式 E的值不为0即为真,认为满足条件,所以与B选项中表达式的含义正好相反,选择B选项。

(6)C 【解析】在fun函数中,while循环的功能是:逐个取字符数组s的字符判断其是否为数字,若是,则将其作为个位数字保存到变量n中,n的原数据的各个数位将相应左移一个十进制位。当指针s指向数组的第三位时,循环条件不成立,循环结束,返回n的值,输出n的值为61,因此C选项正确。

(7)A 【解析】A选项中do后面的语句只执行了一次便结束了循环;B选项中条件while(1)永远成立,所以是死循环;C选项中n的值为10,而循环体为空语句,所以while(n)永远为真,进入死循环;D选项中for语句第二个表达式为空,所以没有判断条件,进入死循环。

(8)A 【解析】第一次首先执行循环体,打印i的值0,然后判断while的条件i++,先用后自增,所以判断时条件为假,跳出循环,但是仍执行了i的自增操作,i的值为1,在接下来的打印语句中进行打印。

(9)C 【解析】由于内层循环for(k=1;k<3;k++)后面直接跟了空语句“;”,所以在循环内部什么操作也不做,跳出外层循环后执行打印语句,所以打印了一个“*”,选择C选项。

(10)A 【解析】第1次for循环,y的值为9,y% 3的值为0,满足条件打印--y,即先减一后打印,所以打印8;第2次for循环,y的值为7,y% 3的值为1,不执行打印语句;第3次for循环,y的值为6,y% 3的值为0,满足条件打印--y,即先减一后打印,所以打印5;第4次for循环,y的值为4,不满足if条件,不执行打印语句;第5次for循环,y的值为3,满足if条件,打印输出2;第6次for循环,y的值为1,不满足条件,不执行打印语句。

(11)D 【解析】第1次循环,a的值为1,满足条件,执行b+=a,与a+=2,则b的值变为3,a的值变为3。执行a++,a的值为4,满足条件进入第2次循环,执行完循环体后, b的值为7,a的值为6。执行a++,a的值为7,满足条件进入第3次循环,执行完循环体后,b的值为14,a的值为9。执行a++,a的值变为10,所以选择D选项。

(12)D 【解析】coutinue语句的作用是跳出循环体中剩余的语句而进行下一次循环。第1次循环,x的值为8,循环体中if条件成立,打印x的值8后将x减1,再执行continue语句,跳出本次循环。第2 次判断循环条件时,x的值变为6,不满足循环体内if条件,执行打印--x的操作,即打印5后跳出循环。第3次判断循环条件时x的值为4,满足循环体内if条件,执行打印x--的操作,即打印4,后将x值减一,执行continue语句,跳出本次循环。第4次判断循环条件时x的值为2,满足循环体内if条件,打印x--,即打印2,后将x减1,执行continue语句,跳出本次循环。在进行for条件表达式中第3 个表达式x--的操作后,x的值为0,不满足条件,结束循环。所以打印结果为8,5,4,2,。

(13)A 【解析】外循环第1 次i的值为1,内循环第1次j的初值为1,打印1*1=1,内循环第2次j的值为2,打印1*2=2,内循环第3次j的值为3,打印1*3=3,打印回车换行,退出内循环。外循环第2次i的值为2,内循环第1次j的初值为2,打印2*2=4,内循环第2次j的值为3,打印2*3=6,打印回车换行,退出内循环。外循环第3次,i的值为3,内循环第1次j的初值为3,打印3*3=9,打印回车换行,退出内循环。

(14)D 【解析】do...while语句是先执行后判断,所以第1次先执行循环体,判断i% 3==1的条件,由于i为5,所以余数为2,条件不成立,执行i++,i的值为6,判断while条件为真。第2次执行循环体,同第1次循环体的执行过程一样,i的值变为7,判断while条件为真。第3次执行循环体,此时i%3==1条件成立,判断i%5==2也成立,打印*与i的值,即*7,然后执行break语句,跳出循环,所以选择D选项。

(15)B 【解析】第1次执行外循环,i的值为3,第1次执行内循环,j的值为1,j<=2条件成立,打印i+j的值,即4;第2次执行内循环,j的值为2,j<=2条件成立,打印i+j的值,即5;再判断条件不成立,打印回车换行符,跳出内循环。第2次执行外循环,i的值为2,内循环的执行同第1次一样,所以打印3和4,打印回车换行,结束内循环。第3次执行外循环,i的值为1。同理,内循环中打印2和3,打印回车换行符,结束内循环。

(16)C 【解析】第1次外循环i的值为1,第1次内循环j的值为3,不满足条件,执行m*=i*j,即m的值为3;第2次j的值为2,不满足条件,执行m*=i*j,即m的值为6;第3次j的值为1,不满足条件,执行m*=i*j,即m的值仍为6。第2次外循环i的值为2,j的值为3,满足条件,执行break语句,跳出循环。

(17)B 【解析】每次内循环只循环一次就结束,第1次外循环时,t=t+b[0][b[0][0]]=1+b[0][0]=1+0=1;第2次外循环时,t=t+b[1][b[1][1]]=1+b[1][1]=1+1=2;第3次外循环时,t=t+b[2][b[2][2]]=2+b[2] [2]=2+2=4。

(18)C 【解析】本题的含义是在1~40的整数范围中,只有当i的值能被5整除,且i+2的值能被8整除时,打印i的值,满足这个条件的只有32,所以选择C选项。

(19)D 【解析】函数的含义是如果i的值能被2整除,以字符格式打印输出i+c的值,如果i的值不能被2整除则打印i+b的值。第1 次i值为0,执行else语句,打印字符'A',第2次i值为1,打印1+b的值,即字符'b',第3次i值为2,打印字符'C',以此类推,所以选择D选项。

(20)B 【解析】coutinue语句的作用是跳出循环体中剩余的语句而进行下一次循环。第1 次执行外循环i的值为0,执行x++,x的值变为1。第1次执行内层循环j的值为0,不满足if条件,执行x++,x的值变为2;第2次内循环j的值为1,if条件成立,跳出本次循环;第3次执行内循环j的值为2,不满足if条件,x的值变为3;第4次执行内循环j的值为3,满足条件,跳出本次内循环,x的值加1,即为4,第1次外循环结束。第2 次执行外循环时,同理,i的值被加了4次,变为8,所以选择B选项。

(21)B 【解析】第1 次执行外循环i的值为1,满足条件,判断第1次内循环,j的值为3,不满足条件,跳出内循环。第2次执行外循环i的值为2,同理也不满足内循环条件,跳出内循环。第3次执行外循环i的值为3,此时进入内循环判断条件时,条件成立,执行m=m% j,m的值为1,跳出内循环,跳出外循环,打印m的值。

(22)B 【解析】continue语句的作用是跳过循环体中剩余的语句而进行下一次循环,所以A选项错误。break语句的作用是终止正在执行的switch流程,跳出switch结构或者强制终止当前循环,从当前执行的循环中跳出,所以C、D选项错误。

(六) 数组

(1)D 【解析】没有A选项的引用形式。*与&放在一起作用抵消,所以B选项错误。最大只能引用到x[9],而*(pt+i)表示引用指针pt所指元素后的第i个元素,所以C选项错误,最大只能为*(pt+9)。D选项正确。

(2)B 【解析】统计1~9这9个数中的奇数和,此题考查指向数组的指针。C语言规定数组名代表数组的首地址,也就是第一个元素的地址,因此*(t+i)代表数组的第i+1个元素。程序的运行结果是1+2+3+4+5+6+7+8+9=25。

(3)B 【解析】该程序首先给一维数组赋值,然后3 次调用fun函数,其中fun(a,0,3)的功能是将一维数组中第1个元素和第4个元素互换,第2个元素和第3个元素互换;fun(a,4,9)的功能是将一维数组中第5个元素和第10个元素互换,第6个和第9个元素互换,第7个元素和第8个元素互换;fun(a,0,9)的功能是将将一维数组中第1个元素和第10个元素互换,第2 个元素和第9 个元素互换……依次类推,因此B选项正确。

(4)B 【解析】在for(i=0;i<12;i++)c[s[i]]++中,数组元素s[i]的值作为数组c的下标,当退出循环时,数组c的4个元素的值分别为4、3、3、2,因此B选项正确。

(5)A 【解析】数组说明的一般形式为:类型说明符 数组名[常量表达式]。B选项中N是变量,不能用变量定义数组长度。C选项中数组长度是一串非法的数字。定义数组时必须为其指明长度,D选项中的数组长度为空,所以非法。

(6)D 【解析】C语言不允许定义动态数组,定义数组的大小必须为常量表达式。A选项错误,C语言中的数组没有此类型的定义方法;B选项错误,定义数组应指明数组大小,如果不指明数组大小,需要给定初值的个数;C 选项错误,N为变量,不能用来定义数组大小。D选项正确。

(7)B 【解析】一维数组的定义方式为:类型说明符 数组名[常量表达式];注意定义数组时,元素个数不能是变量,因此应该选择B选项。

(8)B 【解析】指针的赋值首先基类型必须一致,s二维数组名,是二维数组的首地址,其基类型是一个具有10个元素的字符数组。p是一个字符指针变量,其基类型是一个字符,k是一个行指针,其基类型是具有3 个元素的字符型数组。所以A、C、D选项中两项的基类型不一致。而B选项,s [0]是二维数组s的第一个元素,其代表第一行元素构成的数组的首地址,相当于一维数组的数组名,其基类型是一个字符类型,和p基类型一致,因此B选项正确。

(9)A 【解析】该程序首先在定义变量时,对二维数组x [][N]进行赋值操作;调用函数fun,函数fun的功能是将二维数组中的a[0][0]、a[1][1]、a[2][2]和a[3][3]赋值给一维数组,最后将一维数组1,0,7,0,输出。

(10)C 【解析】本题重点考查二维数组名作为实参进行参数传递。在主函数中调用了fun函数,实参为二维数组名a和两个整数4、0,这样对应定义fun函数首部也有3种形式。这里采用了第一种形式,也就是行指针,这样在fun函数对s[i][j]进行操作,实际上就是对主函数中的a[i][j]进行操作,再分析fun函数的作用便可知,是求二维数组第0列中最大的那个元素,因此C选项正确。

(11)D 【解析】首先对二维数组进行赋值操作,a[0] [0]、a[0][1]、…、a[3][2]、a[3][3]的值为1、4、…、6、1。通过for语句和if语句,对二维数组各列元素进行由小到大的排序操作,程序最后通过for语句输出二维数组对角线上的元素,因此D选项正确。

(12)A 【解析】二维数组t[][3]实际上指t[3][3]={{9,8,7},{6,5,4},{3,2,1}},通过循环语句for语句可以得到i=0,t[2][0]=3、i=1,t[1][1]=5、i=2,t[0][2]=7、i=3时循环结束,即t[2][0]=3、t[1][1]=5、t[0][2]=7,因此A选项正确。

(13)C 【解析】首先对二维数组进行赋值操作,a[0][0]、a[0][1]、…、a[3][2]、a[3][3]的值为1、4、…、6、1。通过for嵌套循环语句和if条件语句,对二维数组对角线元素进行由大到小的排序操作,程序最后通过for语句输出二维数组第1行的4个元素,因此C选项正确。

(14)B 【解析】二维数组定义的一般形式是:类型说明符数组名[常量表达式1][常量表达式2]。其中常量表达式1表示第一维下标的长度,常量表达式2 表示第二维下标的长度。如对二维数组的全部元素赋初值,则第一维的长度可以不给出。但如果对x[4][]赋值,只确定行数,而不确定列数,就无法正确赋值,因此B选项正确。

(15)D 【解析】D选项中x[2][3]定义的是一个2行3列的二维数组,而在给数组元素赋值时却赋成了3 行,所以错误。

(16)B 【解析】B选项中定义的数组为2行4列,而赋值时赋成了3行,所以出错。

(17)A 【解析】本题中输入的3个数据2、4、6分别赋值给了x[0][0]、x[1][0]、x[2][0]。x[0][1]仍为初始时的0,所以打印输出时的结果为A选项。

(18)A 【解析】strlen()函数是计算字符串长度时,遇到结束标识为止,且长度不包括结束标识。本题中的字符串从第一个字符开始,遇到第一个结束标识'\0'为止,注意'\0'不占字符串长度,所以字符串长度为7,因此A选项正确。

(19)C 【解析】strcpy:字符串复制函数;strlen:求字符串长度函数(注意:不包含字符串结束标记字符'\0');strcat:字符串连接函数。执行完语句strcat(p,r);后,p数组中存储的元素为a,b,c,d,a,b,c,d,e;执行语句 strcpy(p +strlen(q),q);得到的结果是将 q 所指向的字符串复制至 p +strlen(q)开始的存储位置,因为strlen的值为3,即p+3开始存储q中的元素,所以执行完strcpy(p+strlen(q),q)语句后,字符数组p[20]的存储元素为a,b,c,a,b,c;所以strlen(p)的结果为6,因此C选项正确。

(20)C 【解析】字符数组a中包含两个'\0',遇到第一个'\0'时就表示字符串a结束。字符串处理函数strcat(字符数组a,字符数组b),功能是连接两个字符数组中的字符串,把字符串b连接到字符串a的后面,结果放在字符数组a中。连接时将字符串a后的'\0'取消,只在新串最后保留一个'\0'。本题相当于将"ABCD"和"IJK"连接,因此C选项正确。

(21)D 【解析】在输入格式控制“name=% s num=% d”中,普通字符“name=num=”在输入时要原样输入,而格式控制符%s和%d对应各自的输入项,将输入的数据赋给相应的输入项。本题中输入“name=Lili num=1001 <回车>”后,将字符串Lili赋给字符数组name,整数1001赋给变量num,因此D选项正确。

(22)A 【解析】语句pc=ch;使得指针变量指向字符数组ch的首地址,即指向字符'u',则pc+5指向的是字符向后移动5位,指向字符'z',所以输出的*pc+5的值即为'z',因此A选项正确。

(23)B 【解析】程序首先给字符数组 s[]赋值为"012xy",for循环语句的功能是遍历字符串,通过if条件语句对字符串中的小写字母进行计数,字符串中小写字母为2个,即n=2,因此B选项正确。

(24)C 【解析】strlen函数返回字符串的长度,求字符串长度时,遇到结束标志 '\0 '为止,但是长度不包括结束标识。字符数组 s1的后 5 个元素没有赋值,都为'\0 ',即"abcd!"后为'\0',所以strlen(s1)的值为5。字符指针s2所指向的字符串中,\n为转义字符换行符,表示1个字符,\\也为转义字符,代表\,也是1个字符,其后为字符串结束标识'\0',所以strlen(s2)的值也为5,因此C选项正确。

(25)B 【解析】(*q)++是q所指的字符加1,q++就是指针移到下一个字符,因此B选项正确。

(26)D 【解析】在函数fun(char*a,char*b)中,while(*a== '*')a++的功能是:如果*a的内容为'*',则a指针向后移动,直到遇到非 '* '字符为止,退出循环进入下一个while循环,在while(*b=*a){b++;a++;}中,把字符数组a中的字符逐个赋给字符数组b。所以在主函数中,执行fun(s,t)语句后,字符数组t中的内容为“a*b****”,因此D选项正确。

(27)C 【解析】程序定义了字符数组s和字符型指针变量p,并且使得p指向数组,执行p=s;语句后,*p即表示s[0];s数组中元素的个数和 p所指字符串长度不相等,因为s数组中元素的个数包括字符串结束标志"\0",而p所指字符串长度不包括"\0";s是字符型数组,p是指针变量,数组s中的内容和指针变量p中的内容不相同,数组中存放的是字符串,而指针变量p存放的是数组的首地址,因此C选项正确。

(28)B 【解析】本题重点考查数组名的概念。在C语言中,数组名类似于一个指向数组首地址的指针常量,一旦定义就不能修改其内容。所以本题中的“s+=2”;语句让数组名s的内容加2 是错误的,编译无法通过,因此 B 选项正确。

(29)B 【解析】函数fun(char s[],int n)的功能是对字符串数组的元素按照字符串的长度从小到大排序,在主函数中执行 fun(ss,5)语句后,*ss[]= {"xy","bcc","bbcc","aabcc","aaaacc"},ss[0],ss[4]的输出结果为xy, aaaacc,因此B选项正确。

(30)B 【解析】此程序是统计一周7天中英文名称首字母为“T”的个数。P[i][0]是字符串的首字符,一共有两个“T”,所以n=2,因此B选项正确。

(31)B 【解析】本题重点考查while循环语句的简单应用。在函数fun()中,前一个while循环的作用是:如果形参指针t所指内容不为0,则让t增1,直到它指向0。后一个while循环的作用是:将s所指内容赋给t所指地址,然后两者同时增1,直到赋给t的内容为0。由此可见,函数fun()的作用就是将形参s所指字符串连接到形参t所指字符串末尾,相当于库函数中的strcat()。主函数中使用fun()将数组aa中的字符串连接到了数组ss中原有字符串之后,所以执行完后,ss中的字符串为“accbbxxyy”。程序最后输出的结果是:accbbxxyy,bbxxyy,因此B选项正确。

(32)D 【解析】主函数中调用fun(a,6)后,指针p1指向字符串中的“1”、p2 指向字符串中的“6”。while循环中,只要p1<p2,就把p1、p2所指向的字符互换,同时p1前移, p2后移,最终字符串逆序存放,因此D选项正确。

(33)B 【解析】主函数中循环执行2次,fun函数被调用2次。b是全局变量,整个程序均可使用。第1 次调用:fun(&a[2]),形参指针k获得a[2]的地址,则*k为a[2]的值,返回值b=a[2]+2 =3 +2 =5;主程序中:b =fun(&a [2])+b=5+5=10;第2次调用:fun(&a[3]),返回值b=4+10=14;主程序中:b=fun(&a[3])+b=14+14=28。因此B选项正确。

(34)A 【解析】根据题目中的定义可知道sizeof(p),计算的是数组p中所有元素所占用的字节数,而不是char型数据所占的字节数。

(35)C 【解析】字符串的输入不能使用scanf("% s", s),而应该使用gets(s)。

(36)B 【解析】本题中遇到"\"字符循环结束,所以只统计"\"之前的数字字符,所以为3。

(37)B 【解析】strcmp(s1,s2)是字符串比较函数,比较规则是两个字符串自左向右逐个字符相比(按照ASCII码值大小),以第一个不相同字符的大小作为比较结果。因为'OK'< 'ok',所以strcmp(s1,s2)为负值,只有B选项正确。

(38)C 【解析】scanf()语句中用“空格”间隔不同的字符串,空格将被全部忽略掉,所以用scanf()函数不能输入空格;getchar()函数用于输入字符,其调用格式为:ch=get-char(),getchar()函数从终端读入一个字符作为函数值,把读入的字符赋给变量ch。在输入时,空格、回车符都将作为字符读入,而且只有在用户敲入回车键时,读入才开始执行。gets()函数的调用形式为:gets(str_adr),其中str_adr是存放输入字符串的起始地址,可以是字符数组名、字符数组元素的地址或字符指针变量。gets函数用来从终端键盘读入字符串(包括空格符),直到读入一个换行符为止。getc()函数的调用形式为:ch=getc(pf),其中pf是文件指针,函数的功能是从pf指定的文件中读入一个字符,并把它作为函数值返回。因此C选项正确。

(39)D 【解析】在C语言中,要对两个字符串的大小进行比较,就需要调用字符串比较函数strcmp,如果这个函数的返回值等于0,说明两个字符串相等,因此D选项正确。

(七) 函数

(1)A 【解析】B选项中函数pow(x,e)错误,应该直接使用exp(x)函数。C选项中函数abs(n^x+e^x)错误,应该使用fabs()返回浮点数的绝对值。D选项中pow(x,n)参数顺序错误。

(2)A 【解析】不能将一个整数直接赋给指针变量作为地址,所以A选项是错误的。函数的返回值可以是地址,即指针。函数调用中形参值的变化不会传递给实参。

(3)D 【解析】在主函数main()中定义了两个变量s和i,同时给s赋初值。a=4,i赋初值0。当i=0时,执行“s+=f(i);”语句,调用f()并将i的初值0传递给形参n。首先执行if语句中内条件:n% 2,若条件为假,则执行else下的语句,a=7,t=7+0=7,使用return返回t,t=7+(a++)=7+5=12,此时a运算完后自增1,变为6;返回主函数中,s=4+12=16。当i=1时,执行“s+=f(i);”语句,调用f()并将i的初值1传递给形参n。首先执行if语句中的条件:n% 2,条件为真,执行if下面的语句,t=0,a=6 t=0+6=6,使用re-turn返回t,t=6+6=12,返回主函数中,s=16 +12 =28,最后输出的结果为28,因此D选项正确。

(4)B 【解析】在主函数main()中定义了两个变量s和i,同时给s和i赋初值0。当i=0时,执行“s+=f(i);”语句,调用f()并将i的初值0传递给形参n。首先执行if语句中内条件:n/2,条件为假,则执行else下的语句,a=7,t=7+0=7,使用return返回t,t=7+(a++)=7+5=12,此时a运算完后自增1,变为6;返回主函数中,s=0+12=12。当i=1时,执行“s+=f(i);”语句,调用f()并将i的初值1传递给形参n。首先执行if语句中的条件:n/2,条件为真,执行if下面的语句,t=0,a=6 t=0+6=6,使用return返回t,t=6+6=12,返回主函数中,s=12+12=24。最后输出的结果为24,因此B选项正确。

(5)A 【解析】本题重点考查的是函数的形参和实参。在定义函数时,函数名后面括弧中的变量名称为“形式参数”(简称形参),在主调函数中调用一个函数时,函数名后面括弧中的参数(可以是一个表达式)称为“实际参数”(简称实参)。C语言规定,实参变量对形参变量的数据传递是“值传递”,即单向传递,只由实参传给形参,而不能由形参传回来给实参。在内存中,实参单元与形参单元是不同的单元,因此A选项正确。

(6)D 【解析】形参是函数定义时由用户定义的形式上的变量。实参是函数调用时,主调函数为被调函数提供的原始数据。在C语言中,实参向形参传送数据的方式是“值传递”,因此D选项正确。

(7)B 【解析】本题重点考查函数的参数传递。函数的参数传递分为传值和传地址两种情况。本题就是结合数组考查参数传递的情形。函数f完成的功能是对数据进行排序,语句f(&a[2],5,0)的作用是对从a[2]开始的5个元素进行从大到小排序。注意:这里传递的是地址&a[2],所以排序操作可看作是直接对数组a进行操作,执行后的结果为5,4,7,6,3,2,1,8,9,10。语句f(a,5,1)对数组a的前5个元素进行从小到大排序,排序后的数组为:3,4,5,6,7,2,1, 8,9,10。因此B选项正确。

(8)B 【解析】在函数中允许有多个return语句,但每次调用只能有一个return 语句被执行,因此只能返回一个函数值,A选项描述错误。定义成void类型的函数,不允许从该函数取得返回值,也不允许使用return语句,C选项描述错误。没有return语句的函数在执行到函数的最后一条语句后会自动返回到调用处,D选项描述错误。因此B选项正确。

(9)A 【解析】返回值为指针变量指向的数据,该数据已被定义为整型,因此A选项正确。

(10)B 【解析】本题重点考查函数返回值的相关知识。函数的值只能通过return语句返回主调函数,在函数中允许有多个return语句,但每次调用只能有一个return 语句被执行,因此只能返回一个函数值。不返回函数值的函数,可以明确定义为“空类型”,类型说明符为void。因此选择 B选项。

(11)A 【解析】在调用子函数时,应对其进行说明。A选项中,调用时没有对子函数进行说明。B、C选项中,被调用函数在主调函数之前定义,不用说明;D选项中,在主函数中对被调用函数的返回值类型进行了说明。因此选择A选项。

(12)A 【解析】函数调用中发生的数据传送是单向的,即只能把实参的值传送给形参,而不能把形参的值反向地传送给实参。因此在函数调用过程中,形参的值发生改变,而实参的值不会变化,所以数组c中的元素值并没有变化,选择A选项。

(13)C 【解析】本题重点考查函数的定义和调用。第一次循环,a=0,i=0,返回值a=0*0+1=1;第二次循环,a=1,i=10,返回值a=10*10+1+1=102;第三次循环,a=102,i=20,返回值a=20*20+1+102=503;第四次循环,a=503,i=30,不符合i<30,跳出循环,最后结果输出a=503。

(14)D 【解析】int m=1,n=2,*p=&m,*q=&n,*r;即指针变量p指向m,指针变量q指向n,r=p;p=q;q=r;即通过指针变量r,将指针p和指针q的指向交换,因此最后输出1,2,2,1。

(15)A 【解析】本题考查的是函数的地址调用。将数组名作为数组首地址进行传递,然后取数据元素值进行加1运算,因此A选项正确。

(16)A 【解析】fun函数的功能是交换形参的值,即交换指针变量a和b的值,但是fun函数并不能够交换实参的值,因此fun(p,q)不能交换p和q的值,所以第一个printf语句的输出为3,5;第二个fun函数对x和y的地址进行了操作,同样不能交换x和y的值,并不能影响p和q指针指向的数据,因此第二个printf语句的输出也是3,5,因此A选项正确。

(17)A 【解析】该题目中fun函数的功能是将a所指数组元素从大到小排序,fun(c+4,6);即指排序从第5个元素开始进行从大到小排序,因此A选项正确。

(18)B 【解析】函数声明的一般形式为:类型说明符被调函数名(类型 形参,类型 形参……);或为类型说明符被调函数名(类型,类型……)。由于函数首部为int fun(double x[10],int *n),因此B选项正确。

(19)A 【解析】第一次调用m=f(f(f(1))),第二次为m=f(f(2)),第三次为m=f(4),即返回值为8。

(20)A 【解析】本题中第一次调用为fun(8,fun(5, 6)),因为fun(5,6)的返回值为5,所以第二次调用为fun(8, 5)=6,所以选择A选项。

(21)D 【解析】调用f(a,b)函数返回3,调用f(a,c)函数返回6,所以外层调用f(f(a,b),f(a,c));即调用f(3,6)函数返回9。

(22)B 【解析】首先 n=fun(3),3 被当作参数传递进去,这就进行了一次调用,3被当作参数传进去后,程序会执行这句 else return fun(k-1)+1;这就调用了第二次,而参数是3-1也就是2。2被当作参数传进去后,程序会执行这句 else return fun(k-1)+1;这就调用了第三次,而参数是2-1也就是1。1被当作参数传进去后,程序会执行这句 else if(k==1)return 1;不再递归调用,所以最终结果为3次。

(23)C 【解析】主函数中调用f函数,同时将数值3传递给变量x,执行条件与if(x==0||x== 1),此时条件不成立,跳过return(3);,直接执行语句y=x*x-f(x-2),这里f(x-2)为函数的递归调用,再次调用f函数,此时x=1,条件语句的条件成立,返回3给f(1),y=3*3-3=6,最后将6返回给主函数,并进行输出,因此C选项正确。

(24)A 【解析】该程序考查的是函数的递归调用,在调用一个函数的过程中又出现直接或间接地调用该函数本身,称为函数的递归调用,执行结果为1+2+3+…+8+9 +10=55,因此A选项正确。

(25)B 【解析】本题重点考查函数的递归调用。题目中给出的fun()函数直接调用了自身,所以是一个递归函数。其功能是:当参数b为0时,返回参数a的值,否则返回fun(--a,--b)的值。从这里可以看出,当b不断递减时,a也不断递减,直到b为0时返回a的值。那么a递减的总值就是b原来的值,所以整个递归函数的作用就是返回a-b的值,因此B选项正确。

(26)A 【解析】因为fun(int x)是一个递归函数,所以主函数中fun(7)经过3次递归调用,其过程可以描述为fun(7)=7 -fun(5)=7 -(5 - fun(3))=7 -(5 -(3 - fun(1)))=7-(5-(3-3))=7-5=2,所以最后的输出结果为2,因此A选项正确。

(27)B 【解析】数组名是常量,表示的是数组首元素的地址。当执行f(a)的时候,由于传递的是首地址,相当于直接对数组a进行操作,所以从数组a的第3个元素a[2]到元素a[5],每个元素值扩大两倍,因此B选项正确。

(28)B 【解析】本题考查的是变量的作用范围。如果在同一个源文件中,外部变量与局部变量同名,则在局部变量的作用范围内,外部变量被“屏蔽”,即不起作用。本题中,在fun1()和main()函数内访问的是全局变量a和b,在fun2()函数中访问的是形参变量a和b。main()函数中的printf()函数输出的是在fun1()函数中被改变的全局变量a和b的值C D,而fun2()函数中输出的是传递给它的实参值E F,因此B选项正确。

(29)A 【解析】全局变量的作用域是从声明处到文件的结束,所以选择A选项。

(30)C 【解析】auto:函数中的局部变量,动态地分配存储空间,数据存储在动态存储区中,在调用该函数时,系统会给它们分配存储空间,在函数调用结束后自动释放这些存储空间。register:为了提高效率,C语言允许将局部变量的值放在CPU中的寄存器中,这种变量叫“寄存器变量”,只有局部自动变量和形参可以作为寄存器变量。extern:外部变量(即全局变量)是在函数的外部定义的,它的作用域为从变量定义处开始,到本程序文件的末尾。如果外部变量不在文件的开头定义,其有效的作用范围只限于定义处到文件终了。static:静态局部变量,属于静态存储类别,在静态存储区内分配存储单元,在程序整个运行期间都不释放。

(31)A 【解析】声明静态局部变量:函数调用结束后,其占用的存储单元不释放,在下次调用该函数时,该变量保留上一次函数调用结束时的值。本题子函数fun中的变量 i和m均为静态局部变量。所以第1次调用fun函数时,返回m的值为5。第2次再调用fun函数时,i的值为3,m的值已经是5了,所以执行i+=m+1,i的值变为9,m=i+x+y=9+1+1=11。

(32)D 【解析】本题中静态局部变量x,在静态存储区内分配存储单元,在程序整个运行期间都不释放。所以第1次循环s的值为2;第2次循环中,返回的x值为4,所以s的值为8;第3次循环,返回的x值为8,所以s的值为64。

(33)A 【解析】题目中静态局部变量a,在静态存储区内分配存储单元,在程序整个运行期间都不释放。所以第一次调用函数执行n+=a++;时,a先与n相加再进行自增。n的值为4,a的值为2,且a变量执行完后空间没有释放。再执行 s=s+f(a)时,s的值为4,调用f(a)函数时,n的返回值为n=3+2=5,且此时a的值为3,所以s的值为9。

(34)D 【解析】fun函数中的变量x为静态局部变量,占用固定的内存单元,下一次调用时仍可以保留上次调用时的值。也就是说,如果多次调用fun函数,x的定义只在第一个调用时有效,从第二次调用开始,x的定义相当于不存在,直接使用上次x的值。fun函数被调用了5 次,每次调用后的返回值累加到s上。5次调用后,x的值为6,s的值为21,因此D选项正确。

(35)D 【解析】内部静态变量是始终存在的,当函数被调用退出后,内部静态变量会保存数据,再次调用该函数时,以前调用时的数值仍然保留着。fun(a,5)的值是15,再次调用后sum=15,所以fun(b,4)=45,s=45 +15 =60,因此D选项正确。

(36)D 【解析】该题目中首先区别++n和n++,第一次调用f函数时,将++n(n自增1后再参与运算)作为参数进行传递,此时变量m的值为1,执行n+=m;后,n=1,将1返回主函数,并输出。第二次调用f函数时,将n++(n参与运算后再自增1)作为参数进行传递,此时变量m的值为1,执行语句n+=m;,由于n是静态存储变量,因此n=2,将2返回主函数并输出,因此D选项正确。

(37)C 【解析】A选项描述正确,自动变量未赋初值,为随机值;B选项描述正确,变量定义除在函数开始位置外,在复合语句开始也可以;C选项描述是错误的,函数内的静态变量只在第一次调用时赋值,以后调用保留上次的值;D选项描述也正确,形参属于局部变量,占用动态存储区,而static型变量占用静态存储区。

(38)C 【解析】fun函数中的x为静态局部变量,占用固定的内存单元,下一次调用时仍可保留上次调用时的值。也就是说,如果多次调用fun函数,x的定义只在第一次调用时有效,从第二次调用开始,x的定义相当于不存在,直接使用x的值。主函数中调用两次fun函数:第一次调用时,x=1,x=x*2=2,s=2;第二次调用时(直接用上次x的值),x=x*2=4,s=4,因此C选项正确。

(八) 指针

(1)B 【解析】在f(int*p,int*q)函数中,执行p=p+1是将p所对应的地址加1,而*q=*q+1是将q所指向n的地址所对应的值加1,所以m的值所对应的值没有变,而n的值则为3了,因此B选项正确。

(2)B 【解析】指针是用来存放地址的变量,用(类型名 *指针变量名)的形式定义。赋值时应将某个变量地址即&x 赋给指针变量,所以选择B。

(3)A 【解析】在变量定义double a,*p=&a;中,*号是一个指针运算符,而非间址运算符,所以A错误。

(4)C 【解析】该程序中int *p1=&a,*p2=&b,*p=&c;指定义3个指针变量,并赋值,即使p1指向a;p2指向b;p指向c。*p=*p1*(*p2);语句是给p所指的存储单元c赋值,就是p1所指的存储单元的值,即a的值,与p2所指的存储单元b的值相乘,也就是c=a*b,等价于c=1*3=3,因此C选项正确。

(5)A 【解析】B选项的正确写法应为p=&n;C选项的正确写法应为scanf("% d",p);选项 D的正确写法应为printf("% d\n",*p)。

(6)A 【解析】因为x和y都是double型数据,所以输入时的格式字符应为% lf,所以B、C选项错误。D选项中的scanf("% lf % lf",x,y);应为scanf("% lf % lf",&x,&y);。

(7)C 【解析】A选项中错在没有对指针进行初始化,无效指针,并且在scanf("% d",&p)中无须再进行取地址操作;B选项中没有对指针进行初始化,无效指针;D选项中语句*p=&k;的左端*p 是指针所指内存空间的值,&k 是地址,应为p=&k。C选项正确。

(8)C 【解析】A选项错误,因为p是指向一个指针数组,作为数组名,不能指向别的地方。B选项错误,因为p[0]是一个int指针,也就是int*;而a是一个指向指针的指针int**。C选项正确,因为p[0]是一个 int*,a[1][2]是int,&a[1][2]是int*,类型吻合。D选项错误,因为a作为数组名,不能取地址,即使能取,p[1]是int*,&a是int***,类型不对。

(9)C 【解析】malloc(sizeof(int))的作用是开辟一个长度为sizeof(int)的存储空间,并通过强制类型转换(int*)将此存储空间的地址赋给一个整型的指针变量p。然后执行语句*p=n,使得*p的值为10,并通过return返回此值,即a的值为10。然后在主函数中输出a+fun(10)=10+10=20。

(10)D 【解析】字符串是一个特殊的数组,所以按照数组的规则,s1应该指向数组的首地址,即"abc"的第一个字符的地址。s2 指向的是"123"的第一个字符的地址。调用swap函数之后,交换的是两个字符串的第一个字符'a'和'1'的内容,所以打印输出为D选项。

(11)A 【解析】本题重点考查函数的调用。首先要了解字母对应的ASCII码,例如A为65,a为97,字母+1可得到下一个字母。其次是函数形参和实参的问题,运行过程如下:在fun(&b,a)中,*c = 'a',d=65。*c+1= 'b',d+1=66,printf("% c,% c,",*c,d);输出b,B;因为指针c指向地址的值为b,此时b=*c = 'b';函数返回执行printf("% c,% c\n",b,a);输出b,A,因此A选项正确。

(12)C 【解析】要按照每行8个输出数据的话,横线处语句的功能应该为:当i是8的倍数时(i% 8==0),输出一个换行符,因此C选项正确。

(13)C 【解析】主程序读取整个字符串存于s中,调用fun函数,字符指针c指向数组s。函数fun的功能是把指针c所指向的字符数组中的所有小写字符转换为大写。gets函数可以把空格作为字符串的一部分输入,以回车作为输入结束。如果*c为小写字符,则*c=*c-32(转大写),因此C选项正确。

(14)D 【解析】函数的参数可以是指针类型,它的作用是将一个变量的地址传送到另一个函数中。函数名代表函数的入口地址,指向函数的指针应该定义为void(*pf)()。如果定义为void *pf(),则表示函数pf的返回值是一个基类型为void的指针,因此D选项正确。

(15)A 【解析】while循环条件为:(*b=*a)!= '\0',执行时先把指针a所指向的字符赋给指针b所在的内存单元,如果该字符不是结束标识“\0”,执行循环体“a++;b++;”,指针a、b分别指向下一个字符单元。再判断循环条件,如果成立,继续把指针a所指向的字符赋给指针b所在的内存单元,直到遇到结束标识为止,因此A选项正确。

(16)A 【解析】本题中函数fun()的功能是将数组k中的前5个元素倒序,所以返回后,数组k中的元素排列是5, 4,3,2,1,6,7,8,9,10。打印输出k[2]到k[7]元素的值,即321678,所以选择A选项。

(17)A 【解析】本题由fun函数可知,b[0]=a[0][0]-a[0][3]=1-4= -3,b[1]=a[1][1]-[1][2]=6-7= -1,b[2]=a[2][2]-[2][1]=11 -10 =1,b[3]=a [3][3]-[3][1]=16-13=3,所以主函数中打印y数组元素的值为A选项。

(18)A 【解析】p 是指向二维字符数组第二行One*Dream!的数组指针,所以长度是10,打印输出的也是该字符串。

(19)D 【解析】A选项中*(&w[0][0]+1)表示w[0] [1];B选项中*(*w+3)表示w[0][3];C选项中*(*(w+1))表示w[0][1];而D选项中*(w+1)[4]的正确写法是(*w+1)[4],表示w[1][4],因此选择D选项。

(20)A 【解析】本题主函数中定义了一个指针数组a,可以将它看成一个以字符指针为元素的一维数组。和一般的一维数组名能赋给同类型的指针变量一样,该字符指针数组也可以赋给指向字符指针的指针,所以数组名a可以用作函数fun()的实参。在fun()函数中,++p操作使形参p往后移动一个字符指针的位置,即指针a[1]的位置,故最后通过printf()函数输出的字符串为“Afternoon”,因此A选项正确。

(21)D 【解析】调用fun函数后,实参数组名s1传给形参指针p,p也指向数组s1。fun函数的功能是遍历字符数组中的所有字符,如果某一个字符是空格,并且前一个字符是小写字母,就把前一个字符转换为大写。程序中的语句p[i-1]=p[i-1]- 'a'+ 'A';即p[i-1]=p[i-1]-32,意思是将p[i-1]中的字符转换为大写,因此D选项正确。

(22)A 【解析】字符型指针变量可以用A选项的赋值方法:char*s;s="Olympic"。C选项的写法:char*s,s={"Olympic"};是错误的。字符数组可以在定义的时候初始化:char s[]={"Olympic"};或者char s[]="Olympic",但是不可以在定义字符数组后对数组名赋值(数组名是常量,代表数组首地址),所以 B 选项和 D 选项都是错误的。对于本例,B、D选项中字符数组s的大小至少为8,才能存放下字符串(字符串的末尾都有结束标志“\0”)。

(23)A 【解析】因为小写字符a、b、c的ASCII码值分别为97、98、99,而在do while循环语句中,每次对字符的ASCII码值取余数并输出,所以分别输出7、8、9。

(24)A 【解析】选项A为正确用法,先将字符串存于字符数组中,然后将数组名赋给字符指针(数组名代表数组首地址,定义数组时为其分配确定的地址)。C选项错误,get-char()函数输入一个字符给字符型变量,而不是字符指针。B选项和D选项有类似的错误,两个选项并无语法错误,但运行时可能会出现问题。因为在B选项和D选项中,字符指针没有被赋值,是个不确定的值,指向一个不确定的内存区域,这个区域可能存放有用的指令或数据。在这个不确定的区域重新存放字符串,可能会发生无法预知的错误。

(25)B 【解析】本题中执行fun(a)时会取a的第一个字母B,因为B的ASCII码值为66,所以不会输出B,函数只会输出ASCII码值为奇数的字母,Y的ASCII码值为89,T的ASCII码值为84,E的ASCII码值为69,因此B选项正确。

(26)C 【解析】本题中由循环条件可知,遇到'\0'或x与y所指的字符的值不等中的一个条件时就结束,所以功能是统计x和y所指字符串中最前面连续相同的字符个数。

(27)B 【解析】A选项去掉大括号就正确了;C选项和D选项应在定义时赋初值。B选项正确。

(28)B 【解析】int(*f)(int);为指向函数的指针变量的定义方法,其中f为指向函数的指针变量,第一个int为函数返回值类型,第二个int为函数的形参类型,因此 B选项正确。

(29)D 【解析】D选项中,*f(a,b)表示调用后返回一个指向整型数据的地址指针,即该函数的返回值为指针类型,所以不能将其赋值给整形变量k。

(30)D 【解析】malloc函数动态分配一个整型的内存空间,然后把函数返回的地址用(int*)强制类型转换为整型指针,再把它赋给a,b,c,即让指针变量a,b,c都指向刚申请的内存空间。只有最后一个赋值语句*c=3的值保留在该空间内,因为a,b,c这3个指针变量均指向该空间,所以打印该空间内的数值为3。

(31)A 【解析】数组定义后,不可以对数组整体赋值,s是二维数组,因ss[1]是一维字符数组,即字符串,字符串赋值可以使用“strcpy(ss[1],"right");”这样的形式,而 A选项中对二维数组中的第“1”维(相当于一个一维数组)赋值是不可以的。B选项和D选项是定义时对数组初始化,这是可以的。在C选项中,将字符串在内存中的首地址赋给指针数组的一个元素,这是可以的。

(九) 编译预处理和动态存储分配

(1)A 【解析】预处理命令是以“#”号开头的命令,它们不是C语言的可执行命令,这些命令应该在函数之外书写,一般在源文件的最前面书写,但不是必须在起始位置书写,所以B、C选项错误。C语言的预处理能够实现宏定义和条件编译等功能,所以D选项错误。

(2)A 【解析】宏定义写在函数的花括号外边,作用域为其后的程序,通常在文件的最开头,所以B选项中“宏定义必须位于源程序中所有语句之前”是错误的。宏名一般用大写,但不是必须用大写,所以C选项错误。宏展开不占运行时间,只占编译时间,函数调用占运行时间(分配内存、保留现场、值传递、返回值),所以D选项错误。

(3)C 【解析】宏定义不是C语句,末尾不需要有分号,语句printf("% 4.1f\n",S(a+b));展开后为printf("% 4.1f\n",3.5;*a+b*a+b;);,所以程序会出现语法错误。

(4)B 【解析】本题考查预编译相关知识,宏定义在编译程序时做了一个简单的替换,所以B选项正确。

(5)C 【解析】本题考查带参数的宏定义,S为带参数的宏定义,运行S(k+j)为4*(k+j)*k+j+1=143,C选项正确。

(6)C 【解析】本题考查宏定义。宏定义只是做简单的替换,本题中SUB(a+b)*c=(a+b)-(a+b)*c= -20,所以C选项正确。

(7)A 【解析】本题考查宏定义的用法,宏定义只是做简单的替换,本题中执行f(a+1)=a+1*a+1*a+1=3*a+1=10,f((a+1))=(a+1)*(a+1)*(a+1)=64,所以A选项正确。

(8)D 【解析】本题考查宏定义的用法。宏定义只是做简单的替换,本题中执行f(2)=(2*N+1)=11,执行f(1+1)=(1+1*N+1)=7,所以D选项正确。

(9)A 【解析】本题考查预处理命令行。预处理是在程序编译之前进行的,所以A选项错误。

(十) 结构体与共用体

(1)B 【解析】本题考查typedef重新声明一种结构体类型。那么T为结构体类型,而不是结构体变量,所以B选项正确。

(2)D 【解析】本题考查typedef重新声明一种结构体类型。其中CIN为结构体类型名,而不是结构体变量,所以D选项正确。

(3)B 【解析】本题考查typedef的用法。typedef并不是增加一种新的类型,而是对已存在的类型用一个新的名字来代表,所以B选项错误。

(4)B 【解析】本题考查结构体初始化操作。本题中可以直接将结构体a赋值给b,所以输出的结果和a一样,B选项正确。

(5)B 【解析】本题考查结构体的相关知识。选项A中struct REC后面不能有分号,C选项中typedef struct REC的后面也不能有分号,选项D中REC已经是结构体变量,不能当作结构体类型来使用。

(6)A 【解析】A选项错误,不能在定义结构体的同时,又用结构体类型名定义变量,应该写成B选项或者D选项的格式。

(7)A 【解析】A选项中可以在声明变量的同时为da-ta2赋值,但是 data2=(2,6);应写作data2={2,6};,所以选择A选项。

(8)B 【解析】本题考查结构体变量的引用以及作为函数参数。题目虽然看似复杂,其实比较容易。f函数的参数是结构体变量,然后对参数重新赋值并返回,所以选择B选项。

(9)A 【解析】本题考查结构体数组初始化以及结构体变量的引用。题目中定义了一个结构体数组c并初始化,指针pt指向c的第一个元素,那么pt->x为10,++pt->x为11,*pt->y为1,(pt++)->x为20,所以选择A选项。

(10)C 【解析】题目中定义了一个结构体类型S,然后定义了一个结构体变量s并初始化,执行f函数后,将s中元素a的每个元素都加上i。这里需要注意,最后一个元素没有加i,所以选择C选项。

(11)D 【解析】本题考查结构体的相关操作以及传值、传址的区别。该题中调用f函数后,会生成参数c的一个副本,而不会改变c的值,所以c值维持原值,D选项正确。

(12)D 【解析】本题考查结构体的相关操作以及传值、传址的区别。该题中调用f函数后,会生成参数a的一个副本,而不会改变a的值,所以a值维持原值,D选项正确。

(13)C 【解析】本题考查结构体变量的引用。题目中定义了一个结构体,其中结构体中的变量又是一个结构体,w为外层结构体,如果给内层结构体赋值,先要得到内层结构体变量,即w.s,若要给year赋值,表示为w.s.year即可,选项C正确。

(14)D 【解析】本题考查结构体变量的引用以及结构体数组。p指向a数组的第一个元素,所以p->x为20,然后p=p->y后,p指向数组a的第二个元素,所以输出15,选项D正确。

(15)C 【解析】本题考查结构体变量的引用。C选项中mark 为结构体中的数组,不能直接赋值,所以 C 选项错误。

(16)D 【解析】声明 data 是结构 S 数组,初始化 data [0].a=10;data[0].b=100;data[1].a=20;data[1].b=200。主函数中p=data[1];即 p.a=data[1].a;p.b=data [1].b;,执行语句printf("% d\n",++(p.a));,打印输出时,p.a 先增1 再打印,p.a = data[1].a =20,先增1 等于21。

(17)C 【解析】本题考查结构体数组的相关操作。dt为结构体数组,那么指针p指向了结构体数组的一个元素,p->x为1,p->y为2,所以结果为2,3,选项C正确。

(18)D 【解析】本题考查结构体的相关知识。题目中需要输入一个变量,scanf要求参数为指针,而D选项中ps->age为一个变量,不是指针,所以错误。

(19)B 【解析】结构体变量可以作为函数的参数和返回值。作为函数的实参时,可以实现函数的传值调用。当使用结构体变量作为函数的形参时,实参也应该是结构体变量名,以实现传值调用,实参将副本给形参,在被调用函数中改变形参值对于调用函数中的实参没有影响,所以选择 B选项。

(20)C 【解析】本题中子函数f的功能是对结构体变量s中第二个成员数组中的所有数据进行从小到大的冒泡排序,所以结果是C选项。

(21)A 【解析】本题考查的是函数调用时的参数传递问题。程序在调用函数f时,传给函数f的参数只是结构变量c在栈中的一个副本,函数f所做的所有操作只是针对这个数据副本进行的修改,这些都不会影响变量c的值。

(22)D 【解析】本题考查链表的操作。本题中首先是s指向了它的下个结点,题目中说明了s总是指向链表的第一个结点。然后while循环找到链表的最后一个元素,最后一个元素指向了之前链表的头结点,之前头结点指向了空结点,所以本题实现的效果是使首结点成为尾结点,选项 D正确。

(23)A 【解析】本题考查删除链表中的结点操作。其方法是将要删除结点的上个结点的下个结点指向要删除结点的下个结点,然后释放该要删除的结点,所以选项A正确。

(十一) 文件

(1)C 【解析】本题考查文件的概念。文件由数据序列组成,可以构成二进制文件或文本文件,所以答案为C选项。

(2)A 【解析】B选项中打开一个已存在的文件并进行写操作后,原有文件中的全部数据不一定被覆盖,也可以对源文件进行追加操作等。C选项中在一个程序中对文件进行写操作后,不是先关闭该文件然后再打开才能读到第一个数据,用fseek()函数进行重新定位即可。D选项中,C语言中的文件可以进行随机读写。

(3)D 【解析】程序首先将数组a[10]中的元素1、2、3分别写入了文件d1.dat文件中,然后又将d1.dat文件中的数据123整体写到变量n的空间中,所以打印n时输出的数据为123。

(4)A 【解析】考查文件操作函数 fopen的基础知识。以w方式打开文件时只能写不能读。

(5)B 【解析】本题考查文件操作函数。执行 fprintf(f,"abc");后,f文件的内容就变为了abc,所以B选项正确。

(6)D 【解析】fread(void *buffer,size t size,size t count,FILE *stream)的功能是从一个文件流中读数据,读取count个元素,每个元素 size 字节,如果调用成功,返回count。buffer用于接收数据的内存地址,大小至少是 size*count 字节;size是单个元素的大小,单位是字节;count是元素的个数,每个元素是size字节;stream是输入流。

(7)B 【解析】本题考查文件操作函数:fwrite和rewind函数。题目中先是将s2字符串写入adc.dat中,然后将写指针回到文件开头,然后写入s1字符串,那么s1字符串就将前5个字符覆盖,所以最终结果为Chinang,B选项正确。

(8)D 【解析】本题考查文件操作函数。两次fwrite后, fp文件中已经写入1,2,3,0,0,1,2,3,0,0然后将文件fp中的内容重新写入数组a中,最后输出a为1,2,3,0,0,1,2,3, 0,0,所以D选项正确。

(9)D 【解析】fprintf()函数向文件输出,将输出的内容输出到硬盘上的文件,或是相当于在文件的设备上执行两次fprintf后,文件中有123 456,所以D选项正确。

(10)C 【解析】本题考查文件操作函数:fprintf()函数。fprintf()函数向文件输出,将输出的内容输出到硬盘上的文件,或是相当于在文件的设备上执行两次fprintf后,文件中有abc28,所以C选项正确。

(11)C 【解析】本题考查文件的定位。feof函数的用法是从输入流读取数据,如果到达文件末尾(遇文件结束符), eof函数值为非零值,否则为0,所以C选项正确。

教程类别