c语言易错题库-(精选)

一、选择题

一、文字类

1.下面是有关 C 语言字符数组的描述,其中错误的是( )。

A.不可以用赋值语句给字符数组名赋字符串

B.可以用输入语句把字符串整体输入给字符数组

C.字符数组中的内容不一定是字符串

D.字符数组只能存放字符串

【答案】 D
【解析】 C 语言中,字符数组可以用来存放单个的字符或者字符串。答案选择 D 选项。

2.以下叙述中正确的是( )。
A.赋值语句是一种执 行语句,必须放在函数的可执行部分
B.scanf printf C 语言提供的输入和输出语句
C.由 printf 输出的数据都隐含左对齐
D.由 printf 输出的数 据的实际精度是由格式控制中的域宽和小数的域宽来完全决定的
【答案】 A
【解析】 A 项正确,赋值语句是一种可执行语句,应当出现在函数的可执行部分。但需要注意,不要把变量
定义时的赋初值和赋值语句混为一谈。 B 项错误, C 语言本身没有提供输入输出功能, scanf printf 属于标准库
函数; C 项错误,数据都隐含右对齐,如果想左对齐,可以在格式控制中的“ % ”和宽度之间加一个“ - ”号来实
现; D 项错误,若给出的总宽度 n1 小于 n2 加上整数位数和小数点( e E 格式还要加上指数的 5 位),则自动
突破 n1 的限制。答案选择 A 选项。
3.以下不能输出字符 A 的语句是( )。(注:字符 A 的 ASCII 码值为 65,字符 a 的 ASCII 码值为 97。)

Aprintf("%c\n",'a'-32);

Bprintf("%d\n",'A');

Cprintf("%c\n",65);

Dprintf("%c\n",'B'-1);

【答案】 B
【解析】 A 项,字符 'a' ASCII 码值减去 32 'A' ASCII 码值,执行字符输出,即为 'A' B 项,执行整型
输出,结果为 65 C 项,字符型输出 'A' D 项,字符型输出 'A' 。答案选择 B 选项。
4.设有定义:double x=2.12;,以下不能完整输出变量 x 值的语句是( )。
Aprintf("x=%5.0f\n",x);
Bprintf("x=%f\n",x);
Cprintf("x=%1f\n",x);
Dprintf("x=%0.5f\n",x);
【答案】 A
【解析】 printf 函数控制字符 %f 输出 float 类型, %1f 输出 double 类型。格式控制 %m.nf ,表示数据输出总的
宽度为 m 位,其中小数部分占 n 位。当数据的小数位多于指定宽度 n 时,截去右边多余的小数,并对截去的第 一位小数做四舍五入处理;而当数据的小数位少于指定宽度 n 时,在小数的右边补零;当 m 小于有效位数时,
整数部分输出所有有效数字并且自动对齐,小数部分按照 n 指定位数输出。 A 项按照 float 格式输出数据,宽度
5 位,保留小数 0 位,输出为 2 ,不能完整输出 x B 项按照 float 格式输出数据,输出为 2.120000 C 项按照
double 格式输出数据,输出为 2.120000 D 项按照 float 格式输出数据,保留小数位数为 5 ,输出为 2.12000 。答
案选择 A 选项。
5.若有定义语句
double x,y,*px,*py;
执行了 px=&x;py=&y;之后,输入语句正确的是( )。
A scanf("%f%f",x,y);
B scanf("%f%f"&x,&y);
C scanf("%1f%1e",px,py);
D scanf("%1f%1f",x,y);
【答案】 C
【解析】 输入函数 scanf 的标准格式是: scanf( 格式控制 , 地址列表 ) AD 两项中地址列表格式不正确,应为
&x &y 。格式控制和地址列表间应该用逗号隔开, B 项也错误。 %f 用来输入 float 类型变量, %1f 用来输入 double
类型变量, %1e 表示用科学计数法输入 double 。答案选择 C 选项。
6.若有定义语句
char c='\101';
则变量 c 在内存中占( )。
A 2 个字节
B 1 个字节
C 3 个字节
D 4 个字节
【答案】 B
【解析】 字符型常量在内存中占一个字节。 '\101' 表示 8 进制数 101 ,即 10 进制中的 65 ,而 '65'=A ,所以, c
表示的字符是 A ,一个字符在内存中占一个字节,答案选择 B 选项。
7.以下选项中不属于字符常量的是( )。
A 'C'
B "C"
C '\Xcc
D '\072'
【答案】 B
【解析】 B 项, C 语言中用双引号表示字符串,在分配存储空间时需要包含 "\0" 作为结束标志。 CD 两项,分
别表示十六进制、八进制格式 ASCII 码值对应的字符常量。答案选择 B 选项。
8.以下不是合法 C 语言转义字符的是( )。
A '\c'
B '\a'
C '\b'
D '\r'
【答案】 A
【解析】 C 语言中, '\a' 表示响铃, '\b' 表示退格, '\r' 表示回车不换行,答案选择 A 选项。

9.若有说明语句:
char c='\72';
则变量 c 中存放的是( )。
A 2 个字符
B 1 个字符 C 3 个字符
D .说明语句不合法
【答案】 B
【解析】 用一对单引号括起来的单个字符为字符常量,以“ \ ”开头的转义字符也是字符常量。“ \ ”后可以为
单个字符,也可以为八进制或十六进制数字,故变量 c 中存放的是一个字符。答案选择 B 选项

10.以下不能输出小写字母 a 的选项是( )。
A printf("%c\n","a");
B printf("%c\n','A'+32);
C putchar(97);
D putchar('a');
【答案】 A
【解析】 printf 函数格式控制符 %c 以字符形式输出数据。 putchar 函数将括号中参数以字符形式输出。 A
a ”为字符串,不是单个字符,输出格式不正确,不能输出 a B 项字符 'a' ASCII 码为 97 ,字符 'A' ASCII
码为 65 'A'+32 即为 'a' ,能输出 a C D putchar 函数参数均为字符 'a' ,均可正确输出 a 。答案选择 A 选项
11.下面选项中关于位运算的叙述正确的是( )。
A .位运算符都需要两个操作数
B .位运算的对象只能是整型或字符型数据
C .左移运算的结果总是原操作数据 2
D .右移运算时,高位总是补 0
【答案】 B
【解析】 B 项正确, C 语言中,位运算的对象只能是整型或字符型数据,不能是其他类型的数据。 A 项错误,
位运算符中取反操作符只需要一个操作符; C 项错误,左移时,若左端移出的部分不包含有效二进制数 1 ,则每
左移一位,相当于移位对象乘以 2 ,如果端移出的部分包含有效二进制数 1 ,结论不成立; D 项错误,右移运算
时,对于无符号整数和正整数,高位补 0 ;对于负整数,高位补 1 。答案选择 B 选项
12.下面关于位运算符的叙述,正确的是( )。
A & 表示“按位与”的运算
B # 表示“按位异或”的运算
C || 表示“按位或”的运算
D ~ 表示“按位异或”的运算
【答案】 A
【解析】 C 语言提供的六种位运算符:“ ~ ”按位求反,“ << ”左移,“ >> ”右移,“ & ”按位与,“ ^ ”按位异
或,“ | ”按位或。答案选择 A 选项。
13.若有定义语句
int b=2;
则表达式(b<<2)/(3||b)的值是( )。
A 4
B 8
C 0
D 2
【答案】 B
【解析】 b=2 ,左移两位相当于乘以 4 2*4=8 3||b 的值为真即为 1 ,表达式的值是 8/1=8 。答案选择 B 选项。
14.以下关于逻辑运算符两侧运算对象的叙述中正确的是( )。

A.可以是任意合法的表达式
B.只能是整数 0 或非 0 整数
C.可以是结构体类型的数据
D.只能是整数 0 或 1

【答案】A
【解析】C 语言的逻辑运算符(如 &&|| 和 !)的操作数可以是任意合法的表达式,这些表达式在逻辑运算时会先被转换为布尔值(真或假)。在 C 语言中,任何非零值都被视为真(true),零值被视为假(false)。因此,逻辑运算符并不要求操作数必须是整数,也不要求必须是 0 或 1。答案选择 A 选项。

15.以下表达式的值与 x 无关、其值恒为真的是( )。
A 0<x<5
B x>10&&x<5
C x>10||x<5
D x<10&&x>5
【答案】 A
【解析】 逻辑与运算只有在“ && ”符号两边操作均为真时,逻辑表达式为真;逻辑或当且只当“ || ”符号两
边操作至少有一个为真时,逻辑表达式为真。 B C D 中,使得表达式恒为真,都跟 x 的取值有关,错误; A
项, 0<x<5 ,从左至右依次运算, 0<x 0 1 ,均小于 5 ,故恒真。答案选择 A 选项。
16.如有表达式(w)?(-x):(++y),则其中与 w 等价的表达式是( )。
A w==1
B w==0
C w!=1
D w!=0
【答案】 D
【解析】 条件表达式形式为 < 表达式 1>?< 表达式 2>:< 表达式 3> 。表达式 1 的值为真,结果为表达式 2 的值;
表达式 1 的值为假,结果为表达式 3 的值。可见表达式 w 等价于 w!=0 。答案选择 D 选项。
17.以下叙述中正确的是( )。
A .如果根据算法需要使用无限循环(即通常所称的“死循环”),则只能使用 while 语句
B .对于“ for( 表达式 1; 表达式 2; 表达式 3) 循环体”首先要计算表达式 2 的值,以便决定是否开始循环
C .对于“ for( 表达式 1; 表达式 2; 表达式 3) 循环体”,只在个别情况下才能转换成 while 语句
D .只要适当地修改代码,就可以将 do-while while 相互转换
【答案】 D
【解析】 D 项正确, C 语言中 do-while 语句和 while 语句作用是等价的,二者可以经过适当的修改互换。 A
项错误, do-while for 循环也能写成死循环; B 项错误, for 循环首先执行表达式 1 C 项错误, for 循环体经过
适当的修改都可以转换成 while 语句。答案选择 D 选项。
18.若 i k 都是 int 类型变量,有以下 for 语句:
for(i=0,k=-1;k=1;k++) printf("* * * * *\n");
下面关于语句执行情况的叙述中正确的是( )。
A .循环体执行两次 B .循环体执行一次
C .循环体一次也不执行
D .构成无限循环
【答案】 D
【解析】 本题中 for 循环判断条件为 k=1 ,这个语句是赋值语句,总是正确的,所以会陷入无限循环中。答
案选择 D 选项。
19.以下不构成无限循环的语句或者语句组是( )。
A n=0; do{++n;}while(n<=0);
B n=0; while(1){n++;}
C n=10; while(n); {n--;}
D for(n=0,i=1;i++) n+=i;
【答案】 A
【解析】 A 项,为 do-while 循环语句,首先执行 do 后面的语句 ++n ;得 n=1 while 条件表达式为假,退出
循环; B 项, while 条件表达式的值始终为 1 ,条件为真,构成无限循环; C 项, while(n); 语句循环体为空, n
值在循环中一直保持不变,构成无限循环; D 项, i=1 for 语句中条件判断语句为空,永远为真,构成无限循环。
答案选择 A 选项。

20.以下叙述中正确的是( )。
A .语句“ int a[8]={0}; ”是合法的
B .语句“ int a[]={0}; ”是不合法的,遗漏了数组的大小
C .语句“ char a[2]={"A","B"}; ”是合法的,定义了一个包含两个字符的数组
D .语句“ char a[3];a="AB"; ”是合法的,因为数组有三个字符空间的容量,可以保存两个字符
【答案】 A
【解析】 A 项正确,表示定义了长度为 8 int 型数组,它里面的每个元素都是 0 。当所赋初值少于所定义
数组的元素个数时,将自动给后面的元素补以初值 0 B 项错误, C 语言规定可以通过赋初值来定义数组的大小,
这时数组说明符的一对方括号中可以不指定数组的大小; C 项错误, a char 类型的数组,里面的元素应该是字
符而非字符串,应该用单引号括起来; D 项错误,数组变量一旦定义,其地址值不可改变,不能给数组名重新赋
值。答案选择 A 选项

21.若有定义语句:
double x[5]={1.0,2.0,3.0,4.0,5.0}, *p=x;
则错误引用 x 数组元素的是( )。
A *p
B x[5]
C *(p+1)
D *x
【答案】 B
【解析】 直接引用一维数组元素的表达式为:数组名 [ 下标 ] 。数组大小为 n 时,下标的取值范围为 0 ~( n-1 ),
所以本题中 x 的下标为 0 4 x[5] 溢出, B 项错误。还可以通过指针引用一维数组元素。指针 p 指向该数组,所
*p 表示 x[0] A 项正确;指针 p+1 指向数组 x 的第二个元素的地址, *(p+1) 表示 x[1] C 项正确;数组名 x
x 数组元素的首地址, *x 表示对 x[0] 的引用, D 项正确。答案选择 B 选项。
22.若有函数
void fun(double a[],int *n)
{......}
以下叙述中正确的是( )。
A .调用 fun 函数时只有数组执行按值传送,其他实参和形参之间执行按地址传送
B .形参 a n 都是指针变量
C .形参 a 是一个数组名, n 是指针变量
D .调用 fun 函数时将把 double 型实参数组元素一一对应地传送给形参 a 数组
【答案】 C
【解析】 A 项,用数组名(指向数组首元素的一个指针常量)作为实参可以实现实参和形参之间执行按地址
传送; B 项,形参 a 是一个数组名,是指针常量而不是变量; D 项,调用 fun 函数时只是将实参数组的首地址传
送给形参 a 。答案选择 C 选项。
18.下面是有关 C 语言字符数组的描述,其中错误的是( )。
A .不可以用赋值语句给字符数组名赋字符串
B .可以用输入语句把字符串整体输入给字符数组
C .字符数组中的内容不一定是字符串
D .字符数组只能存放字符串
【答案】 D
【解析】 C 语言中,字符数组可以用来存放单个的字符或者字符串。答案选择 D 选项。
37.若主函数中有定义语句:int a[10],b[10],c;
在主函数前定义的 fun 函数首部为:
void fun(int x[ ])
则以下选项中错误的调用语句是( )。
A fun(b);
B fun(&c);
C fun(&a[3]);
D fun(b[11]);
【答案】 D
【解析】 fun 函数的形式参数为一个数组,需要实参为一个地址,而 b[11] 是一个整型元素,参数类型不一致,
b[11] 已经溢出,所以 D 项错误。答案选择 D 选项。
63.若有定义:
int a[2][3];
以下选项中对 a 数组元素正确引用的是( )。
A a[2][!1]
B a[2][3]
C a[0][3]
D a[1>2][!1]
【答案】 D
【解析】 a[2][3] 表示 2 3 列的数组,即 a[0][0] a[0][1] a[0][2] a[1][0] a[1][1] a[1][2] ,行下标最大值
1 ,列下标最大值为 2 D 项,其中 1>2 为假即 0 !1 也为 0 ,即访问 a[0][0] 。答案选择 D 选项。
62.若有定义语句:
int m[ ][3]={1,2,3,4,5,6,7};
则与该语句等价的是( )。
A int m[ ][3]={{1,2,3},{4,5,6},{7}};
B int m[ ][3]={{1,2},{3,4},{5,6,7}};
C int m[ ][3]={{1,2,3},{4,5},{6,7}};
D int m[ ][3]={{1},{2,3,4},{5,6,7}};
【答案】 A
【解析】 考查二维数组的初始化。二维数组的初始化有两种方式,①分行初始化,方式为:数据类型数组名 [ 行下标表达式 ][ 列下标表达式 ]={{ 0 行初值 },{ 1 行初值表 }, { 最后 1 行初值表 }}; ,如果初值表只对部分元
素赋初值,没有被赋初值的元素将被自动赋值为 0 。②不分行将所有数据依次列在一个花括号里,即数据类型数
组名 [ 行下标表达式 ][ 列下标表达式 ]={ 初值表 }; ,这种方式的赋值就是将初值表的数据依次赋予数组的每个元素,
其中赋值是按照数组元素在内存中的位置进行的。题目中的初始化语句是第二种方法,如果用第一种方法应该是
int m[][3] = {{1,2,3}, {4,5,6}, {7}}; ,这里应该保证除 r 最后一行,每一行都满列有 3 个元素,答案选择 A 选项。
71.若有定义语句:
char s[3][10],(*k)[3],*p;
则以下赋值语句正确的是( )。
A p=s;
B p=k;
C p=s[0];
D k=s;
【答案】 C
【解析】 A 项,将字符型二维数组首地址赋值给了一个字符型指针,类型不匹配; B 项,将指针数组的首地
址赋值给一个字符型指针,类型不匹配; C 项, s 是二维字符数组, s[0] 表示一个含有 10 个元素的一维数组,即
将一维字符数组首地址赋值给了一个字符型指针,这是允许的; D 项,将二维字符数组赋值给了指向一维字符数
组的指针,类型不匹配。答案选择 C 选项。
73.若有定义
int(*pt)[3];
则下列说法正确的是( )。
A .定义了基类型为 int 的三个指针变量
B .定义了基类型为 int 的具有三个元素的指针数组 pt
C .定义了一个名为 *pt 、具有三个元素的整型数组
D .定义了一个名为 pt 的指针变量,它可以指向每行有三个整数元素的二维数组
【答案】 D
【解析】 int(*pt)[3]; 语句定义了一个指向一维数组的指针 pt ,该一维数组具有三个 int 型元素。 D 项,按照 C
语言中二维数组的定义知,二维数组先进行行排列,再进行列排列,故 pt 也可以指向每行有三个整数元素的二
维数组。答案选择 D 选项。
19.若有定义语句:
int a[4][10],*p,*q[4];
0≤i<4,则错误的赋值是( )。
A p=a
B q[i]=a[i]
C p=a[i]
D p=&a[2][1]
【答案】 A
【解析】 二维数组名是指向指针的指针,所以 a q 都为指向指针的指针,而 p 为指向 int 类型的指针, p
a 不同类型,故 A 选项中 p=a 赋值语句错误。其余选项可以正确赋值,其中 D 项是用取地址符 & 返回整数的
地址,然后赋值给 p 。所以答案选择 A 选项。
96.以下正确的字符串常量是( )。
A ""
B 'abc'
C Olympic Games
D "\\\"
【答案】 A
【解析】 字符串常量需要用双引号括起来, A 项正确; "\\\" 中第三个 \ " 和在一起是一个字符, D 项错误。
答案选择 A 选项。
98.设有以下定义:
char s1[ ]="0123";
char s2[ ]={'0','1','2','3'};
则以下叙述正确的是( )。
A .数组 s1 的长度小于 s2 的长度
B .数组 s1 s2 的长度相同
C .数组 s1 的长度大于 s2 的长度
D .数组 s1 s2 完全等价
【答案】 C
【解析】 字符数组 s1 赋值字符串 "0123" ,字符串中字符依次放入数组中,在最后一个字符后要添加一个结
束字符 '\0' ,数组 s1 长度为 5 。数组 s2 只需要 4 个单元即可放下所有初始化值,故数组长度为 4 。所以数组 s1
长度大于 s2 的长度, C 项正确, AB 错误。两个数组等价是指两个数组长度和类型以及对应每个元素值均相同,
所以 s1 s2 不是完全等价, D 项错误。答案选择 C 选项。
99.以下选项中,合法的是( )。
A char str3[]={'d', 'e', 'b', 'u', 'g', '\0'}
B char str4; str4="hello world";
C char name[10]; name="china";
D char str1[5]="pass", str2[6]; str2=str1;
【答案】 A
【解析】 A 项是在赋初值时直接赋字符串常量。 B 项, str4 是一个字符型变量,不能直接赋值字符串; C 项,
数组名 name 是一个地址常量,不能直接被赋值; D 项, str1 str2 代表两个大小不同的字符数组的首地址,不
能互相赋值。答案选择 A 选项。
100.以下能正确进行字符串赋值的语句组是
A char*ch; ch="abc";
B char ch[]={'a', 'b', 'c'};
C char ch[3]= "abc";
D char ch[4]; ch="abc";
【答案】 A
【解析】 一个字符串包括字符部分和字符串结束标志。将字符指针变量初始化为一个字符串有两种方式,①
通过赋值运算使一个字符指针指向一个字符串常量: char*ch; ch="abc" ;②定义一个字符指针变量,并且初始化
为一个字符串的首地址: char*ch="abc" A 项正确。 B 项定义一个字符数组并为其赋初值,因为没有字符串结束
标志,所以字符数组不是一个字符串, B 项错误。 C 项定义字符数组,长度为 3 ,用字符串 "abc" 初始化,但是字
符串的结束标志由于数组长度不够并未放入数组,所以数组不是一个完整的字符串, C 项错误。 D 项正确定义了
数组,长度为 4 ch 表示数组首地址,不可以修改,更不能被赋值, D 项错误。答案选择 A 选项。

110.以下使指针指向一个字符串的选项错误的是( )。
A char str[]="string"; char * ps; *ps= str;
B char str[]="string"; char *ps; ps= str;
C char str[]="strinh",* ps=str;
D char * ps; ps=str; ps="strinh";
【答案】 A
【解析】 A 项中定义了指针 ps 后, *ps 表示指针 ps 指向地址的内容,而不是地址, *ps=str 无法将 str 的首地
址赋给一个常量,语法错误。答案选择 A 选项。
116.有以下说明语句:
char *s = "\"Name\\Address\n";
指针 s 所指字符串的长度是( )。
A 17
B 15
C 14
D .说明语句不合法
【答案】 C
【解析】 以“ \ ”开头的转义字符也是字符常量。用一对双引号括起来的多个字符为字符串。“ \" ”是“ "
的转义字符,“ \\ ”是“ \ ”的转义字符,“ \n ”是换行的转义字符,指针 s 指向的字符串中字符依次是: " N
a m e \ A d d r e s s \0 。所以字符串长度为 14 。答案选择 C 选项。
128.设有定义:
char s[81];int i=0;
以下不能将一行(不超过 80 个字符)带有空格的字符串正确读入的语句或语句组是( )。
A gets(s);
B while((s[i++]=getchar())!='\n');s[i]= '\0';
C scanf("%s",s);
D do{scanf("%c",&s[i]);}while(s[i++]!='\n'); s[i]='\0';
【答案】 C
【解析】 字符串的输入有两种方式:① scanf() 函数;② get() 函数。 A 项, gets 函数用来从终端键盘读入字符
串(包括空格符),直到读入一个换行符为止; B 项, getchar() 函数从终端读入一个字符作为函数值; D 项, %c
格式读入单个字符,空格、回车符和 Tab 键都将作为字符读入。 C 项中, s 代表输入一个字符数组而非地址,而
且遇到空格时会默认字符串输入结束,所以不能读入带有空格的字符串。答案选择 C 选项。
151.以下关于字符串的叙述中正确的是( )。
A C 语言中有字符串类型的常量和变量
B .两个字符串中的字符个数相同时才能进行字符串大小的比较
C .可以用关系运算符对字符串的大小进行比较
D .空串比空格打头的字符串小
【答案】 D
【解析】 A 项错误, C 语言中没有字符串类型,而是通过字符数组的形式保存字符串。 B 项错误,字符串比
较的方法是:依次对 s1 s2 中对应位置上的字符两两进行比较,当出现第一对不相同的字符时,即由这两个字
符决定所在串的大小(比较字符大小的依据是其 ASCII 码值)。空格是一种字符,所以空串肯定比空格打头的字
符串小。 C 项错误,比较字符串大小时,通过库函数 strcmp(s1,s2) 或者自定义函数,不能使用关系运算符。 D
正确:空串的长度为 0 ,而以空格打头的字符串的长度至少为 1 。答案选择 D 选项。
43.若有定义语句:
char s[10]="1234567\0\0";
strlen(s)的值是( )。
A 7
B 8
C 9
D 10
【答案】 A
【解析】 C 语言规定以字符 '\0' 作为字符串结束的标识符。 strlen 函数返回的是字符串的长度,不包含字符 '\0'
所以值是 7 。答案选择 A 选项。
157.以下不能将 s 所指字符串正确复制到 t 所指存储空间的是( )。
A while(*t=*s){t++;s++;}
B for(i=0;t[j]=s[i];i++);
C do{*t++=*s++;}while(*s);
D for(i=0,j=0;t[i++]=s[j++];);
【答案】 C
【解析】 C 项, *t++=*s++; 能够实现将 s 中除了字符串结束标志的字符 '\0' 以外的所有字符复制到 t 中,字符
t 是不完整的。答案选择 C 选项。
7.以下叙述中错误的是( )。
A C 程序必须由一个或一个以上的函数组成
B .函数调用可以作为一个独立的语句存在
C .若函数有返回值,必须通过 return 语句返回
D .函数可以通过实际参数和形式参数之间进行数据传递
【答案】 C
【解析】 C 项错误,比如 main 函数中有 exit(0) ,则可以通过 exit 函数返回状态。 A 项正确, C 程序至少有
一个 main 函数; B 项正确, C 语言中的函数可以仅进行某些操作而不返回函数值,这时函数的调用可作为一条
独立的语句; D 项正确,当函数调用为传引用时,形参指针和实参指针指向同一块内存,修改形参的同时也就修
改了实参。答案选择 C 选项。
35.以下关于 C 语言函数参数传递方式的叙述正确的是( )。
A .数据只能从实参单向传递给形参
B .数据可以在实参和形参之间双向传递
C .数据只能从形参单向传递给实参
D C 语言的函数,参数既可以从实参单向传递给形参,也可以在实参和形参之间双向传递,可视情况选择
使用
【答案】 A
【解析】 数据只能由实参单向传递给形参称为“值传递”,而不能由形参传给实参, A 项正确, B C D 误;数组名、指针等作参数,实参传递给形参的是地址值,这样形参和实参就指向同一段内存单元,在函数体内
对形参数据的改变也将影响到实参。答案选择 A 选项。
60.在一个 C 源程序文件中所定义的全局变量,其作用域为( )。
A .所在文件的全部范围
B .所在程序的全部范围
C .所在函数的全部范围
D .由具体定义位置和 extern 说明来决定范围
【答案】 D
【解析】 全局变量是在函数外部任意位置上定义的变量,它的作用域是从变量定义的位置开始,到整个源文
件结束止。答案选择 D 选项
61.以下叙述中正确的是( )。
A .只要是用户定义的标识符,都有一个有效的作用域
B .只有全局变量才有自己的作用域,函数中的局部变量没有作用域
C .只有在函数内部定义的变量才是局部变量
D .局部变量不能被说明为 static
【答案】 A
【解析】 A 项正确,标识符的“作用域”是指在程序中的某一部分中,标识符是有定义的,可以被 C 编译
和连接程序所识别。在 C 语言中,由用户命名的标识符都有一个有效的作用域。 B 项错误,局部变量的作用域是
所在的函数体(或复合语句); C 项错误,在函数内部或复合语句内部定义的变量,称为局部变量; D 项错误,
在函数体(或复合语句)内部用 static 来说明一个变量时,变量为静态局部变量。答案选择 A 选项

84.以下针对全局变量的叙述错误的是( )。
A .全局变量的作用域是从定义位置开始至源文件结束
B .全局变量是在函数外部任意位置上定义的变量
C .用 extern 说明符可以限制全局变量的作用域
D .全局变量的生存期贯穿于整个程序的运行期间
【答案】 C
【解析】 在不同编译单位内用 extern 说明符来扩展全局变量的作用域, extern 可以将全局变量作用域扩展到
其他文件,而不是限制全局变量的作用域。选项 C 正确。
6.以下叙述中错误的是( )。
A .当在程序的开头包含头文件 stdio.h 时,可以给指针变量赋 NULL
B .函数可以返回地址值
C .改变函数形参的值,不会改变对应实参的值
D .可以给指针变量赋一个整数作为地址值
【答案】 D
【解析】 A 项正确, NULL 是在头文件 stdio.h 中定义的符号常量; B 项正确,函数的返回值可以是地址,即
指针; C 项正确,函数调用中形参值的变化不会传递给实参; D 项错误,不能将一个整数直接赋给指针变量作为
地址,只能用取地址运算符“ & ”把该整型变量的地址赋值给该指针变量。答案选择 D 选项。
3.关于地址和指针,以下说法正确的是( )。
A .通过强制类型转换可以将一种类型的指针变量赋值给另一种类型的指针变量
B .可以取一个常数的地址赋值给同类型的指针变量
C .可以取一个表达式的地址赋值给同类型的指针变量
D .可以取一个指针变量的地址赋值给基类型相同的指针变量
【答案】 A
【解析】 常数的地址存储在内存的常量区,常量区存储的都是常量,值都是不可修改的,所以直接取常量的
地址赋给指针变量没有任何意义, C 语言也不允许这样做,编译会出错, B 项错误;表达式的值存储在临时变量
中,内存中存在专门用来存储临时变量的区域,对这块地址进行操作也是没有意义的, C 语言不允许这样做,编
译会出错, C 项错误;可以取一个指针变量的地址,但是指针变量的地址属于指针,只能赋值给指针类型的指针
变量, D 项错误。答案选择 A 选项。
7.若有定义语句:
double a,*p=&a;
以下叙述中错误的是( )。
A .定义语句中的 p 只能存放 double 类型变量的地址
B .定义语句中的 * 号是一个说明符
C .定义语句中的 * 号是一个间址运算符
D .定义语句中 *p=&a 把变量 a 的地址作为初值赋给指针变量 p
【答案】 C
【解析】 C 项错误,只有取指针变量的值时,星号 * 才是间址运算符,引用指针指向的存储单元。 A 项正确,
p double 类型的指针,只能存放 double 类型的地址; B 项正确,定义指针变量时,星号 * 是一个说明符,用来
说明该变量是指针变量; D 项正确,“ & ”是求地址运算符, *p=&a 用来求出 double 变量 a 的地址赋给指针变量
p ,而使 p 指向 a 。答案选择 C 选项。
8.设有定义:
int a,b[10],*c=NULL,*p;
则以下语句错误的是( )。
A p=a;
B p=b;
C p=c;
D p=&b[0];
【答案】 A
【解析】 p 为指针变量,存放变量的地址。对指针变量赋值,值必须是地址值。 a 为整型变量不是地址值,
不能赋值给 p A 项错误,应改为 p=&a 。数组名 b 为数组首地址,可以赋值给 p B 项正确。 c 为指针变量,初
始化为 NULL ,与 p 均为整型指针,可以将其赋值给 p C 项正确。 & 为取地址运算符, &b[0] 为数组元素 b[0]
地址,可以赋值给 p D 项正确。答案选择 A 选项。
10.设有定义:
int x=0,*p;
紧接着的赋值语句正确的是( )。
A *p=x;
B *p=NULL;
C p=x;
D p=NULL;
【答案】 D
【解析】 指针赋值的正确写法:① p=&x ,表示 p 指向 x 的存储单元;② p=NULL ,表示 p 是空指针。③ *p=x
表示将 p 指向的内容赋值为 x ,但前提是 p 已进行了初始化。答案选择 D 选项。
12.设变量 p 是指针变量,语句 p=NULL;是给指针变量赋 NULL 值,它等价于( )。
A p="";
B p='0';
C p=0;
D p='';
【答案】 C
【解析】 NULL ASCII 码值为 0 p=NULL 等价于 p='\0'; p=0 。答案选择 C 选项
6.若程序中有宏定义行:
#define N 100
则以下叙述中正确的是( )。
A .宏定义行中定义了标识符 N 的值为整数 100
B .在编译程序对 C 源程序进行预处理时用 100 替换标识符 N
C .上述宏定义行实现将 100 赋给标识符 N
D .在运行时用 100 替换标识符 N
【答案】 D
【解析】 D 项正确,预处理程序对源程序中所有使用宏名的地方进行直接替换。 A 项错误,宏定义没有类型
限制; B 项错误,预处理程序进行宏替换,而非编译程序; C 项错误,宏定义不是赋值操作,而是进行在预编译
时进行替换。答案选择 D 选项。
36.若有说明:typedef struct{int a;char c;}w;,则以下叙述正确的是( )。
A .编译后系统为 w 分配 5 个字节
B .编译后系统为 w 分配 6 个字节
C .编译后系统为 w 分配 8 个字节
D .编译后系统不为 w 分配存储空间
【答案】 D
【解析】 w 是一个自定义类型,不是变量,故编译后系统不为 w 分配存储空间。当 w 定义为结构体变量时
才会为其分配存储空间。答案选择 D 选项。
39.若有以下语句
typedef struct S
{int g;char h;}T;
以下叙述中正确的是( )。
A .可用 S 定义结构体变量
B .可用 T 定义结构体变量
C S struct 类型的变量
D T struct S 类型的变量
【答案】 B
【解析】 AC 两项, S 是定义的结构体的名字,并不是 struct 类型的变量也不可用来定义结构体变量; D 项,
题目中 T 定义为 struct S 类型,即 T 被定义为一个类型名,而不是变量。答案选择 B 选项
40.设有如下语句:
typedef struct Date
{
int year;
int month;
int day;
} DATE;
则以下叙述中错误的是( )。
A DATE 是用户定义的结构体变量
B struct Date 是用户定义的结构体类型
C DATE 是用户说明的新结构体类型名
D struct 是结构体类型的关键字
【答案】 A
【解析】 C 语言允许用 typedef 说明一种新类型名,其一般形式如下: typedef 类型名 新类型名 ; ,题目中定
义了新类型 Date ,这种类型变量包含 3 个成员, DATE 是这种新类型的名字,不是结构体变量, C 项正确, A
错误。 struct Date 是用户定义的结构体类型, B 项正确。 struct 是结构体类型的关键字, D 项正确。答案选择 A
选项。
42.若有定义:
typedef int T[10];
T *a[20];
则与上述定义完全等价的说明语句是( )。
A int *a[20][10];
B int *a[20];
C int *a[10];
D int *a[10][20];
【答案】 A
【解析】 新定义的类型 T 为大小为 10 的整型数组,定义 T 型指针数组 *a[20] ,等价于定义了一个指向整型
长度为 10 的数组的指针数组,这个指针数组大小为 20 ,即为整型指针二维数组,行 20 10 ,答案选择 A 选项。
45.设有定义:
struct complex
{int real,unreal;}data1={1,8},data2;
则以下赋值语句中错误的是( )。
A data2=data1;
B data2=(2,6);
C data2.real=data1.real;
D data2.real=data1.unreal:
【答案】 B
【解析】 B 项,对结构体进行初始化时,应该用花括号括起来的一组值,而不是用小括号,而且需要强制转 换数据类型,应该为 data2=(struct complex){2,6}; 。答案选择 B 选项。
46.设有定义:struct{int n;float x;}s[2],m[2]={{10,2.8},{0,0.0}};,则以下赋值语句中正确的是( )。
A s[0]=m[1];
B s=m;
C s.n=m.n;
D s[2].x=m[2].x;
【答案】 A
【解析】 定义了结构体类型数组 s ,长度为 2 ,结构体类型数组 m ,长度为 2 ,并对数组 m 进行了初始化。
同类型的结构体可以直接用变量名实现赋值, A 项正确;数组名为数组首地址,地址常量之间不可以相互赋值,
B 项错误;数组名为地址常量不是结构体变量,不能引用成员, C 项错误; s[2] m[2] 数组越界, D 项错误。答
案选择 A 选项。
53.若有以下定义:
struct tt{char name[10];char sex;}aa={"aaaa",'F'},*p=&aa;
则错误的语句是( )。
A scanf("%c",aa.sex);
B aa.sex=getchar();
C printf("%c\n",(*p).sex);
D printf("%c\n",p->sex);
【答案】 A 【解析】 sex 是一个 char 类型变量,不是地址, A 项应为 scanf("%c",&aa.sex); 。答案选择 A 选项。
97.若有以下定义和语句:
struct st
{
int n;
struct st*next;
};
struct st a[3] = {5,&a[0], 6,&a[1],7,&a[2]}, *p;
p = &a[0];
则值为 6 的表达式是(提示:运算符->的优先级高于++)( )。
A (*p).n++
B p++->n
C p->n++
D (++p)->n
【答案】 D
【解析】 定义指向结构体变量的指针 p ,并将结构体数组首地址赋给 p 。执行 (++p)->n p 指针加一指向数组
第二个元素 a[1] a[1].n=6 D 项正确。 A 项, (*p).n++ *p 为结构体数组第一个元素 a[0] a[0].n=5 ,先取值,
表达式为 5 B 项, p++->n p 指向结构体数组第一个元素 a[0] a[0].n=5 C 项, p->n++ p 指向结构体数组第
一个元素 a[0] a[0].n=5 ,由于 ++ 是后缀,先取值,所以表达式为 5 ,之后再加一。答案选择 D 选项。
1.下列关于 C 语言文件的叙述中正确的是( )。
A .文件由一系列数据依次排列组成,只能构成二进制文件
B .文件由结构序列组成,可以构成二进制文件或文本文件
C .文件由数据序列组成,可以构成二进制文件或文本文件
D .文件由字符序列组成,其类型只能是文本文件
【答案】 C
【解析】 C 语言将文件看作是一个字符(字节)的序列,即由一个一个字符(字节)数据顺序组成。根据数
据的组成形式,可将文件分为两种:① ASCII 文件,又称文本( text )文件,它的每一个字节可放一个 ASCII 码,
代表一个字符;②二进制文件,是把内存中的数据按其在内存中的存储形式原样输出到磁盘上存放。所以 C
件就是一个字节流或一个二进制流。答案选择 C 选项。
2.以下叙述中正确的是( )。
A C 语言中的文件是流式文件,因此只能顺序存取数据
B .打开一个已存在的文件并进行了写操作后,原有文件中的全部数据必定被覆盖
C .在一个程序中当对文件进行了写操作后,必须先关闭该文件然后再打开,才能读到第 1 个数据
D .当对文件的读(写)操作完成之后,必须将它关闭,否则可能导致数据丢失
【答案】 D
【解析】 D 项正确, C 语言中读写文件是通过文件缓冲区完成的,在完成了对文件的操作之后,应当关闭文
件,否则文件缓冲区中的剩余数据可能丢失。 A 项错误, C 程序中的输入、输出文件都以数据流的形式存储在介
质上,用顺序存取和直接存取两种方式; B 项错误,可以以追加的方式写文件; C 项错误,“ r+ ”为读和写而打
开文本文件,在读和写操作之间不必关闭文件,用 fseek() 函数进行重新定位就能够读到第 1 个数据也不必关闭文
件。答案选择 D 选项
3.下面选项中关于“文件指针”概念的叙述正确的是( )。
A .文件指针就是文件位置指针,表示当前读写数据的位置
B .文件指针是程序中用 FILE 定义的指针变量
C .文件指针指向文件在计算机中的存储位置
D .把文件指针传给 fscanf 函数,就可以向文本文件中写入任意的字符
【答案】 B
【解析】 文件指针实际上是指向一个结构体类型的指针。 B 项正确,结构体类型名为 FILE ,用来定义文件
指针,文件指针的定义形式为: FILE* 文件指针名。 A 项错误,文件指针是指在程序中定义的 FILE 类型的变量,
通过 fopen 函数调用给文件指针赋值,使文件指针和某个文件建立联系, C 程序中通过文件指针实现对文件的各
种操作;文件位置指针只是一个形象化的概念,表示当前读或写的数据在文件中的位置; C 项错误,文件在计算
机中的存储位置由操作系统负责,文件指针并没有指向文件的存储位置; D 项错误, fscanf 可以用于读文件,而
非写文件。答案选择 B 选项
16.设 fp 为指向某二进制文件的指针,且已读到此文件末尾,则函数 feof(fp)的返回值为( )。
A .非 0
B '\0'
C 0
D NULL
【答案】 A
【解析】 本题考查的是文件指针 feof 的运用。当文件读到结尾时, feof(fp) 为非零值,否则为 0 。答案选择 A
选项
17.以下叙述正确的是( )。
A EOF 只能作为文本文件的结束标志,其值为 -1
B EOF 可以作为所有文件的结束标志
C EOF 只能作为二进制文件的结束标志
D .任何文件都不能用 EOF 作为文件的结束标志
【答案】 A
【解析】 返回符 EOF End of file )是在头文件 stdio.h 中定义的宏,表示文件的结束标志,值为 -1 ,这种以
EOF 作为文件结束标志的文件,必须是文本文件。在文本文件中,数据都是以字符的 ASCII 代码值的形式存放,
由于不可能出现 -1 ,因此可以用 EOF 作为文件结束标志。答案选择 A 选项。
20.标准库函数 fgets(s,n,f)的功能是( )。
A .从文件 f 中读取长度不超过 n-1 的字符串存入指针 s 所指的内存
B .从文件 f 中读取长度为 n 的字符串存入指针 s 所指的内存
C .从文件 f 中读取 n 个字符串存入指针 s 所指的内存
D .从文件 f 中读取 n-1 个字符串存入指针 s 所指的内存
【答案】 A
【解析】 fgets 函数功能是从 f 所指文件中读入 n-1 个字符放入 s 为起始地址的空间内,并在尾端自动加一个
结束标志“ \0 ”。同时将读 / 写位置指针向前移动字符串长度个字节。在读出 n-1 个字符之前,如遇到了换行符或
EOF ,则读出结束, A 项正确。 B 项中“读取长度为 n ”错误。 C 项与 D 项中“读取 n/n-1 个字符串”错误,读
取的是 n-1 个字符。答案选择 A 选项
21.以下不能对文件进行输出的库函数是( )。
A fwrite
B fputs
C fpout
D fprintf
【答案】 C
【解析】 fwrite 函数的功能是用来向文件写数据块。 fputs 函数的功能是用来向指定文件输出一个字符串。
fprintf 函数按照格式向文本文件中输出数据。这三者都是库函数,而 fpout 不是库函数。答案选择 C 选项。
23.有如下定义:
struct st
{
int a;
float b;
}x[10];
FILE *fp;
若文件已正确打开,且数组 x 10 个元素均已赋值,以下将数组元素写到文件中的语句错误的是( )。
A for(i=0; i<10; i++) fwrite(x,sizeof(struct st), 1,fp);
B fwrite(x,10*sizeof(struct st), 1,fp);
C fwrite(x,sizeof(struct st), 10,fp);
D for(i=0; i<10; i++) fwrite(&x[i],sizeof(struct st), 1,fp);
【答案】 A
【解析】 A 项中,因为函数 fwrite 中第三个参数为 1 ,即每次写入 1 个结构体数据, x 是数组的首地址,因
此,每次写入的数据都是数组的首个结构体元素,没有将整个数组写入文件中去。答案选择 A 选项。
12.以下关于算法的叙述中错误的是( )。
A .算法可以用伪代码、流程图等多种形式来描述
B .一个正确的算法必须有输入
C .一个正确的算法必须有输出
D .用流程图可以描述的算法可以用任何一种计算机高级语言编写成程序代码
【答案】 B
【解析】 算法可以使用自然语言、伪代码、流程图等多种不同的方法来描述。故选项 A D 说法正确。一个
正确的算法可以有零个或者多个输入,必须有一个或者多个输出。故选项 C 说法正确, B 说法错误。答案选择 B
选项。
17C 语言主要是借助以下( )功能来实现程序模块化的。
A .定义函数
B .定义常量和外部变量
C .三种基本结构语句
D .丰富的数据类型
【答案】 A
【解析】 C 程序的模块化主要通过函数来实现。 C 语言允许对函数单独进行编译,从而可以实现模块化。
21.以下叙述中错误的是( )。
A .使用三种基本结构构成的程序只能解决简单问题
B .结构化程序由顺序、分支、循环三种基本结构组成
C C 语言是一种结构化程序设计语言
D .结构化程序设计提倡模块化的设计方法
【答案】 A
【解析】 结构化程序由顺序、分支和循环三种基本结构组成,选项 B 正确。由三种基本结构组成的算法可
以解决任何复杂的问题,而不只是解决简单问题,选项 A 错误。由三种基本结构所构成的算法称为结构化算法;
由三种基本结构所构成的程序称为结构化程序, C 语言是一种结构化程序设计语言。结构化程序通过函数实现模
块化的设计方法。选项 C D 正确。答案选择 A 选项。
7.以下叙述正确的是( )。
A C 语言程序是由过程和函数组成的
B C 语言函数可以嵌套调用,例如: fun(fun(x))
C C 语言函数不可以单独编译
D C 语言中除了 main 函数,其他函数不可作为单独文件形式存在
【答案】 B
【解析】 一个函数的返回值可以作为参数然后传给另一个函数,因此函数是可以嵌套调用的。 A 项错误, C
语言程序只有函数构成,没有过程; C 项错误,编译系统的任务在于检查语法错误,只要符合语法规则的 C 程序
都可以通过编译,就算是单独的函数也可以; D 项错误,在 C 语言中除 main() 函数以外的其他函数可以和 main()
函数在同一个 C 文件中,也可以单独处于其他的 C 文件,只要在使用到这些函数的 main() 函数的 C 文件中用预
编译指令“ #include ”包含进来即可。答案选择 B 选项。
9.下列叙述中正确的是( )。
A .每个 C 程序文件中都必须要有一个 main 函数
B .在 C 程序中 main 函数的位置是固定的
C C 程序中所有函数之间都可以相互调用
D .在 C 程序的函数中不能定义另一个函数
【答案】 D
【解析】 C 程序中, main 函数的位置可以任意,而且不管 main 函数位置怎么变化,程序都会以 main
数作为入口,选项 B 错误;每个 C 程序(而不是每个 C 程序文件)必须有且只能有一个 main 函数,选项 A
误; main 函数不能被其他函数调用,选项 C 错误;函数的定义不能放在另一个函数体内,但是声明可以,答案
选择 D 选项
52.以下叙述中正确的是( )。
A C 程序的基本组成单位是语句
B C 程序中的每一行只能写一条语句
C .简单 C 语句必须以分号结束
D C 语言必须在一行内写完
【答案】 C
【解析】 C 程序的基本组成单位是函数, A 项错误; C 程序以分号作为每个语句结尾,一行能写多条语句,
也可以将一条语句分几行书写, B D 两项错误; C 语言中语句分为简单语句和复合语句。简单语句以分号作为
结束。其中简单语句里面又有赋值语句、声明语句、结构化语句、函数调用语句和空语句。复合语句指用花括号
{} 将简单语句甚至另一些复合包起来,所以就以 } 作为语句结束的标记。答案选择 C 选项
47.以下选项中不能作为 C 语言合法常量的是( )。
A 'cd'
B 0.1e+6
C "a"
D '\011'
【答案】 A
【解析】 常量包括整型常量、实型常量、字符常量和字符串常量等。单引号表示字符常量,但不能包含字符
串。表达字符串常量时需用双引号。 A 项,在 C 语言中,字符常量是用单引号括起来的一个字符, 'cd' 包含了 2
个字符; B 项, 0.1e+6 是实型常量的指数形式,代表 0.1×10 6 C 项, "\a" 是合法的字符串常量, \a 是一个非打印
的转义字符表示响铃; D 项, '\011' 是一个字符常量, \011 是一个用 3 位八进制表示的转移字符。答案选择 A
35.以下选项中,能用作数据常量的是( )。
A 115L
B 0118
C 1-5e1.5
D o115
【答案】 A
【解析】 C 语言中实型常量有两种表示:小数形式和指数形式。在指数形式中,字母 e (或 E )之前必须要
有数字,且 e E 后面的指数必须为整数,故 C 项错误;八进制整数常量以数字 0 开始,而不是 o ,故 D 项错
误。在八进制数中的有效数字为 0 7 ,故 B 项错误; L 是长整型数据标识, 115L 为长整型常数即 long int A
正确。答案选择 A 选项
39.以下定义语句中正确的是( )。
A int a=b=0;
B char A=65+1,b='b';
C float a=1,*b=&a,*c=&b;
D double a=0.0;b=1.1;
【答案】 B
【解析】 A 项错误,变量定义的时候不能用连续用等号,等号在定义是初始化的一种; C 项错误, b 是指针
变量, *c=&b 表示将一个二级指针赋值给一个一级指针,应该为 *c=b 或者 **c=&b D 项,变量前为分号“ ; ”表
示前面的语句定义完毕,变量 b 的定义没有指明变量类型。答案选择 B 选项。
40.以下关于 C 语言数据类型使用的叙述中错误的是( )。
A .若只处理“真”和“假”两种逻辑值,应使用逻辑类型
B .若要保存带有多位小数的数据,可使用双精度类型
C .若要处理如“人员信息”等含有不同类型的相关数据,应自定义结构体类型
D .整数类型表示的自然数是准确无误差的
【答案】 A
【解析】 A 项错误, C 语言中没有逻辑类型,在 C++ 中才引入的; B 项正确, float 类型称为单精度类型, double
类型称为双精度类型,一般系统中,为 float 类型的变量分配 4 个字节的存储单元,为 double 类型的变量分配 8
个字节的存储单元。 C 项正确, struct 结构体,可以用来描述包含多种基本类型的复杂对象。 D 项正确,整数的
表示是不存在误差的。答案选择 A 选项
41.设有两行定义语句:
int scanf;
float case;
则以下叙述正确的是( )。
A .两行定义语句都不合法 B .两行定义语句都合法
C .第 1 行语句不合法
D .第 2 行语句不合法
【答案】 D
【解析】 预定义标识符是系统已经有过定义的标识符,用户可以重新定义,可以作为变量名。 scanf 为库函
数名,属于预定义标识符,可以被用户重定义,第一行语句合法。 C 语言关键字是被保留的,不能用作其他用途
的一些标识符,它们在程序中都代表着固定的含义,用户不可重新定义。 case 是选择结构 switch 语句中的关键字,
不可被用户重定义,第二行语句不合法。答案选择 D 选项。
53.关于 C 语言中数的表示,以下叙述中正确的是( )。
A .只有整型数在允许范围内能精确无误地表示,实型数会有误差
B .只要在允许范围内整型和实型都能精确表示
C .只有实型数在允许范围内能精确无误地表示,整型数会有误差
D .只有八进制表示的数才不会有误差
【答案】 A
【解析】 实型数据在内存中存储的二进制位数是有限的,而一个十进制实数转化为二进制实数时,其有效数
字位数有可能会超过尾数的存储长度,从而导致有效数字丢失而产生误差。在整型数允许范围之内,二进制可以
表示任意一个整数。答案选择 A 选项。
63.若有定义:
int a=1,b=2,c=3;
则执行表达式(a=b+c)||(++b)后,abc 的值依次为( )。
A 1,2,3
B 5,3,2
C 5,2,3
D 5,3,3
【答案】 C
【解析】 || 表示或运算,当第一个表达式为真时,第二个表达式不执行。根据运算符的优先级规则,先计算
(a=b+c) ,将 b+c 的值赋值给 a ,则 a=5 ,而 || 右边的括号不会被执行,所以 b=2 c=3 。答案选择 C 选项。
68.若在程序中变量均已定义成 int 类型,且已赋大于 1 的值,则下列选项中能正确表示代数式 1/abc 的表 达式是( )。
A 1.0/a/b/c
B 1/(a*b*c)
C 1.0/a*b*c
D 1/a/b/(double)c
【答案】 A
【解析】 abc 均大于 1 ,所以表达式 1/abc 小于 1 ,需要用浮点类型表示。若要计算表达式值,需要使其自动
转化成浮点类型, A 项正确。 B 项变量与常量均为整型,不会自动转换为浮点类型, B 项错误。 C 项表示表达式
bc/a ,错误。 D 项,算数运算法结合性自左向右,先计算 1/a ,结果为 0 ,之后的计算无论是否转换数据类型结果
均为 0 D 项错误。答案选择 A 选项。
71.设有以下程序段:
int y;
y=rand()%30+1;
则变量 y 的取值范围是( )。
A 0≤y≤30
B 0<y≤30
C 1<y<30
D 1<y≤30
【答案】 B
【解析】 rand 函数产生随机整数,任何整数对 30 求余得到的整数范围为 0 29 ,则 y 的取值范围为 1≤y≤30
或者 0<y≤30 y 是整数, 0<y≤30 。答案选择 B 选项
74.设有定义:int x=7,y=12;,则以下表达式值为 3 的是( )。
A (y%=x)-(x%=5)
B y%=(x%=5)
C y%=x-x%5
D y%=(x-x%5)
【答案】 A
【解析】 A 项正确, a%=b 表示 a=a%(b) A 项可改写成 y=y%x x=x%5 ,再计算 y-x 计算的结果为 3 ,满足
题意; B 项为 0 C 项为 2 D 项等同于 C 项。答案选择 A 选项。
77.以下能正确表述算式 sin(2πr+30°)C 语言表达式是( )。
A sin(2*3.14*r+3.14*30/180.0)
B sin(2*π*r+30)
C sin(2*3.14*r+30)
D sin(2*3.14*r+30*3.14/360.0)
【答案】 A
【解析】 A 项正确。 sin 是库函数,其参数中的角度要求用弧度制表示。 C 语言中 π 不是已定义的常量,需
要用户自定义或者直接使用 3.14 代替 π B 项未替换 π 也没有将 30 度换算成弧度,错误。 C 项没有将 30 度换算
成弧度,错误。 D 项弧度换算错误, π 对应于 180° ,应该除以 180.0 而不是 360.0 。答案选择 A 选项。
78.有以下定义
int a;
long b;
double x,y;
则以下选项中正确的表达式是( )。
A a%(int)(x-y)
B a==x!=y
C (a*y)%b
D y=x+y=a
【答案】 A
【解析】 % 运算是取两整数相除后余数的运算符,它只适用于整数的运算。 A 项正确, x-y 结果为 double 型,
但是通过强制类型转换将其转换为 int 型; B 项错误, a==x!=y == 和! = 是同一个优先级的,先运行 a==x ,而因
double 是占 8 位的,不能自动转换,必须要强制类型转换, a==(double)x!=y 才是正确的; C 项错误, (a*y)%b
中的 (a*y) double 型; D 项错误, x+y 不能作为左值。答案选择 A 选项。
83.以下选项中,值为 1 的表达式是( )。
A '1'-0
B 1-'0'
C 1-'\0'
D '\0'-'0'
【答案】 C
【解析】 ASCII 码表, '0' 48 '1' 49 '\0' 0 ,答案选择 C 选项。
92.设 abc 是整型变量且均已赋值,则以下选项中错误的赋值语句是( )。
A a=(b=3)=1;
B a=(b=2)+c;
C a=b=c+10;
D a=1+(b=c=2);
【答案】 A
【解析】 赋值运算结合性为由右向左结合,赋值运算符左值为变量,右值为变量或常量或表达式,且左右两
边数据类型相同才能实现赋值。 A 项中,赋值运算 (b=3)=1 ,左值为表达式,不是变量不能被赋值, A 项错误。 B
项运算过程为,先赋值 b=2 ,再计算 b+c ,将结果赋给 a ,是正确的赋值语句。 C 项运算过程为,先计算 c+10
结果赋给 b ,再将 b 赋给 a ,是正确的赋值语句。 D 项运算过程为,先将 2 赋给 c ,再将 c 赋给 b ,然后计算 1+b
将结果赋给 a ,是正确的赋值语句。答案选择 A 选项
94.若有定义:
int a,b,c;
以下选项中的赋值语句正确的是( )。
A a=(b=c)+1;
B (a=b)=c=1;
C a=(b==c)=1;
D a+b=c;
【答案】 A
【解析】 赋值运算结合性为由右向左结合,赋值运算符左值为变量,右值为变量或常量,且左右两边数据类
型相同才能实现赋值。 A 项中,将 c 赋值给 b ,然后将 b 1 赋值给 a ,是正确的赋值语句,正确。 B 项中,将 1
赋值给 c ,赋值运算 (a=b)=c 中左值为表达式,不是变量不能被赋值,错误。 C 项中赋值运算 (b==c)=1 左值为逻辑
表达式,不是变量不能被赋值,错误。 D 项左值 a+b 为表达式,不是变量不能被赋值, D 项错误。答案选择 A
选项
71.以下选项中错误的是( )。
A a&=b a=a & b 等价
B a^=b a=a^b 等价
C a|=b a=a|b 等价
D a!=b a=a!b 等价
【答案】 D
【解析】 D 项, a!=b 表示 a 不等于 b 时,表达式结果为 1 ,否则为 0 ;而 a=a!b 是语法错误,“ ! ”是非运算,
且是单目运算符,要求只有一个操作数,故两者不等价。答案选择 D 选项。
74.设有定义:
int a=64,b=8;
则表达式(a&b) || (a&&b)(a|b) && (a||b)的值分别为( )。
A 1 1
B 1 0
C 0 1
D 0 0
【答案】 A
【解析】 逻辑或运算符“ || ”,计算左表达式值,如果为真,则不计算右表达式,而整个表达式为真,若左表
达式为假,再计算右表达式然后做或运算。逻辑与运算符“ && ”,计算左表达式值,如果为假则不计算右表达式,
而整个表达式为假,若左表达式为真,再计算右表达式然后做与运算。 a=64=10000008 b=8=1000B a&b=0
假, a&&b 为真, (a&b) || (a&&b) 为真,值为 1 a|b=1001000B 为真, a||b 为真,则 (a|b) && (a||b) 为真,值为 1
答案选择 A 选项
49.如有表达式(w)?(-x):(++y),则其中与 w 等价的表达式是( )。
A w==1
B w==0
C w!=1
D w!=0
【答案】 D
【解析】 条件表达式形式为 < 表达式 1>?< 表达式 2>:< 表达式 3> 。表达式 1 的值为真,结果为表达式 2 的值;
表达式 1 的值为假,结果为表达式 3 的值。可见表达式 w 等价于 w!=0 。答案选择 D 选项。
2.以下叙述中正确的是( )。
A .语句“ int a[8]={0}; ”是合法的
B .语句“ int a[]={0}; ”是不合法的,遗漏了数组的大小
C .语句“ char a[2]={"A","B"}; ”是合法的,定义了一个包含两个字符的数组
D .语句“ char a[3];a="AB"; ”是合法的,因为数组有三个字符空间的容量,可以保存两个字符
【答案】 A
【解析】 A 项正确,表示定义了长度为 8 int 型数组,它里面的每个元素都是 0 。当所赋初值少于所定义
数组的元素个数时,将自动给后面的元素补以初值 0 B 项错误, C 语言规定可以通过赋初值来定义数组的大小,
这时数组说明符的一对方括号中可以不指定数组的大小; C 项错误, a char 类型的数组,里面的元素应该是字
符而非字符串,应该用单引号括起来; D 项错误,数组变量一旦定义,其地址值不可改变,不能给数组名重新赋
值。答案选择 A 选项。
73.若有定义
int(*pt)[3];
则下列说法正确的是( )。
A .定义了基类型为 int 的三个指针变量
B .定义了基类型为 int 的具有三个元素的指针数组 pt
C .定义了一个名为 *pt 、具有三个元素的整型数组
D .定义了一个名为 pt 的指针变量,它可以指向每行有三个整数元素的二维数组
【答案】 D
【解析】 int(*pt)[3]; 语句定义了一个指向一维数组的指针 pt ,该一维数组具有三个 int 型元素。 D 项,按照 C
语言中二维数组的定义知,二维数组先进行行排列,再进行列排列,故 pt 也可以指向每行有三个整数元素的二
维数组。答案选择 D 选项。
130.有定义语句:
char s[10];
若要从终端给 s 输入 5 个字符,错误的输入语句是( )。
A gets(&s[0]);
B scanf("%s",s+1);
C gets(s);
D scanf("%s",s[1]);
【答案】 D
【解析】 采用 scanf 函数输入时,输入项为变量的地址。 gets 函数的输入项为存放字符串的首地址。 A 项,
&s[0] 为数组的首地址; B 项, s+1 为数组中第二个元素的地址; C 项, s 也为数组的首地址; D 项, s[1] 不是地址。
答案选择 D 选项
139.若有定义:char*ps[]={"aa","bb","cc","dd"};,则以下叙述正确的是( )。
A ps[0] 是字符串 "aa"
B *ps[0] 是字符串 "aa" 的首地址
C ps[0] 是字符串 "aa" 的首地址
D *ps[0] 是字符串 "aa"
【答案】 C
【解析】 定义一个字符串数组指针 ps 后, ps 是指针变量, ps[0] 指向的是数组首个元素的地址,即字符串 "aa"
的首地址,答案选择 C 选项。
63.在 C 语言中,只有在使用时才占用内存单元的变量,其存储类型是( )。
A auto register
B extern register
C auto static
D static register
【答案】 A
【解析】 C 语言中,动态存储区域中存放的变量在使用时才分配内存空间。 auto 变量的存储单元是分配在内
存的动态存储区中,每当进入函数体时自动分配存储单元。 register 变量也是自动类变量。 static 说明的变量为静
态变量,静态变量在内存的静态存储中占据着永久的存储单元,直至程序运行结束。 extern 说明的变量为外部变
量,属于全局变量,全局变量在整个程序运行期间都占用内存空间。答案选择 A 选项。
65.以下叙述错误的是( )。
A .未经赋值的全局变量值不确定
B .未经赋值的 auto 变量值不确定
C .未经赋值的 register 变量值不确定
D .未经赋值的静态局部变量值为 0
【答案】 A
【解析】 C 语言中,未经赋值的全局变量默认初始化为 0 ,答案选择 A 选项。 ​​​​​​​

二、代码类

46.设有如下函数定义:
int fun(int k)
{
 if(k<1) return 0;
 else if(k==1) return 1;
 else return fun(k-1)+1;
}

若执行调用语句:n=fun(3);,则函数 fun()总共被调用的次数是( )。

A 2
B 3
C 4
D 5
【答案】 B
【解析】 函数 fun 为递归函数,递归结束条件是 k 为小于等于 1 的数。执行 fun(3) 语句时会返回 fun(3-1)+1
fun(2)+1 ;执行 fun(2) 时会返回 fun(2-1)+1 ,即 fun(1)+1 ;执行 fun(1) 时会返回 1 ,所以函数 fun 总共被调用 3
次。答案选择 B 选项。
26.有以下程序:
#include<stdio.h>
main()
{
int x=0,y=6;
do
{
while(--y)x++;
}
while(y--);
printf("%d,%d\n",x,y);
}

程序的运行结果是( )。

A 5,0
B 6,0
C 5,-1
D 6,-1
【答案】 C
【解析】 程序执行过程为:执行 do while 的循环体: y=5 ,判断 y 为真, x=1 y=4 x=2 y=3 x=3 y=2 x=4 y=1 x=5 y=0 ,判断 y 为假,退出循环体。判断 do while 条件 y=0 为假, y=-1 ,退出循环。输出 x,y
5,-1 ,答案选择 C 选项。
65.有如下程序:
#include <stdio.h>
main()
{
int i;
for (i=0;i<5;i++)
putchar('9'-i);
printf("\n");
}

程序运行后的输出结果是( )。

A 54321
B 98765 C '9''8''7''6''5'
D '43210'
【答案】 B
【解析】 本题执行过程为: i=0 ,输出字符 9 ,在 i<5 的情况下,依次输出字符 8 7 6 5 。在 i=5 时,退出
for 循环。最后显示在命令窗口结果为 98765 。答案选择 B 选项。
118.有以下程序
#include <stdio.h>
main()
{
int i;
for(i=1;i<=40;i++)
{
if(i++%5==0)
if(++i%8==0)printf("%d",i);
}
printf("\n");
}

执行后的输出结果是( )。

A 32
B 24
C 5
D 40
【答案】 A
【解析】 自增运算符“ ++ ”分为前缀和后缀两种形式。两种形式的作用效果是一样的,都是使运算分量的
值加 1 ,但是它们的表达式的值不一样,前缀形式表达式的值为运算分量加 1 之后的值,而后缀形式表达式的值
为运算分量加 1 之前的值。题目中使用了一个 for 循环,循环变量 i 1 递增到 40 。在循环体中有两条嵌套的 if
语句,首先判断 i++%5==0 ,即判断 i++ 的值( i 1 之前的值)是否能被 5 整除(判断后 i 被加 1 ),然后再判断
++i 的值( i 1 之后的值)是否能被 8 整除(判断后 i 被加 1 ),若两个条件都满足了,就输出 i 的值,只有 i=30 时,满足 i++%5==0 ,此时 i=31 ++i%8==0 成立,此时 i=32 。答案选择 A 选项
55 .有以下程序:
#include<stdio.h>
main()
{
FILE*pf;
char*s1="China",s2="Beijing";
pf=fopen("abc.dat","wb+");
fwrite(s2,7,1,pf);
rewind(pf); /*文件位置指针回到文件开头*/
fwrite(s1,5,1,pf);
fclose(pf);
}

以上程序执行后 abc.dat 文件的内容是( )。

AChina

B Chinang
C ChinaBeijings
D BeijingChina
【答案】 B
【解析】 pf 是一个文件指针, fopen("abc.dat","wb+"); 执行后, pf 指向可读写的二进制文件 abc.dat 。语句
fwrite(s2,7,1,pf); 是将 s2 的前 7*1 个字符的内容写入 pf 中,即 Beijing rewind(pf); 是将文件位置指针移回到文件
开头,语句 fwrite(s1,5,1,pf); 是从文件的开头位置,将 s1 的前 5*1 个字符的内容写入,替换掉原来位置上的内容,
所以结果为 Chinang 。答案选择 B 选项。

18.有以下程序
#include <stdio.h>
main()
{
FILE *fp;
int k,n,a[6]={1,2,3,4,5,6};
fp=fopen("d2.dat","w");
fprintf(fp,"%d%d%d\n",a[0],a[1],a[2]);
fprintf(fp,"%d%d%d\n",a[3],a[4],a[5]);
fclose(fp);
fp=fopen("d2.dat","r");
fscanf(fp,"%d%d",&k,&n);
printf("%d%d\n",k,n);
fclose(fp);
}
程序运行后的输出结果是( )。
A 123456
B 14
C 1234
D 12
【答案】 A
【解析】 将有 6 个元素的整型数组分两行输出到一个文件中,因为输出的都是数字并且每行都没有分隔符,
所以当再对其进行读取操作时,每一行都会被认为是一个完整的数,而换行符则作为它们的分隔符。答案选择 A
选项
93.有如下程序:
#include <stdio.h>
struct pair
{
 int first,second;
};
struct pair get_min_max(int*array, int len)
{
 int i;
 struct pair res;
 res.first=array[0];
 res.second=array[0];
 for(i=1;i<len;i++)
 {
 if(array[i]<res.first)
 res.first=array[i];
 if(array[i]>res.second)
 res.second=array[i];
 }
 return res;
}
main()
{
 int array[5]={9,1,3,4};
 struct pair min_max = get_min_max(array,5);
 printf("min=%d,max=%d\n", min_max.first, min_max.second);
}

程序运行后的输出结果是( )。
A min=1,max=9
B min=0,max=9
C min=1,max=4
D min=0,max=4
【答案】 B
【解析】 在对数组进行初始化时,如果在定义数组时给出了长度,但没有给所有的元素赋予初始值,那么 c
语言将自动对余下的元素赋初值 0 ,则 array[5] = {9,1,3,4,0} 。程序的执行过程为:调用函数 get_min_max(array,5)
将数组 array 的首地址传入函数,定义结构体变量 res ,并为其成员赋值。 for 循环查找数组 array 的最小值 0 ,将
其赋值给 res 的成员 first ,查找数组最大值 9 ,并将其赋值给 res 的成员 second 。最后返回结构体变量 res ,则
min_max=res 。输出 min_max.first=0 min_max.second=9 。答案选择 B 选项。
69 .有以下程序
#include <stdio.h>
typedef struct
{
 int b,p;
}A;
void f(A c)
{
 int j;
 c.b+=1;
 c.p+=2;
}
main()
{
 int i;
 A a={1,2};
 f(a);
 printf("%d,%d\n",a.b,a.p);
}

程序运行后的输出结果是( )。

A 1,2
B 2,4
C 1,4
D 2,3
【答案】 A
【解析】 当把一个结构体变量传送给相应的形参时,传递的是实参结构体变量中的值,系统将为结构体类型
形参开辟相应的存储单元,并将实参中各成员的值一一对应赋给形参中的成员,函数中形参结构体变量的改变不
会影响到实参结构体变量。所以,函数 f 不会改变 a 中的数据。答案选择 A 选项。

65.有以下程序:
#include <stdio.h>
struct ord
{int x,y;}dt[2]={1,2,3,4};
main()
{
struct ord *p=dt;
printf("%d,",++p->x);
printf("%d",++p->y);
}

程序运行后的输出结果是( )。

A 1,2
B 2,3
C 3,4
D 4,1
【答案】 B
【解析】 dt 是一个结构体数组,所以初始化的结果为 dt[0]={1,2} dt[1]={3,4} *p=dt; 表示 p 指向 dt[0] ++p->x
中, -> 的优先级大于 ++ ,所以表达式等价于 ++(p->x) ,因为 p->x 1 ,所以输出这个值为 2 ,同理,第二个 ++p->y
的值为 2+1=3 。答案选择 B 选项。
62.有如下程序:程序运行后的输出结果是( )。
#include<stdio.h>
struct person
{
 char name[10];
 int age;
};
main()
{
 struct person room[2] = {{"Wang",19},{"Li",20}};
 printf("%s:%d\n", (room+1)->name, room->age);
}

A.Li:19

B Wang:19
C Li:20
D Wang:17
【答案】 A
【解析】 room 表示数组首地址,首地址 +1 ,指向 room 数组中第二个元素,并将该元素的 name 信息进行输
出,同理,对第一个元素中的 age 信息输出。答案选择 A 选项。

47.有以下程序段
struct st
{
int x;
int *y;
}*pt;
int a[]={1,2},b[]={3,4};
struct st c[2]={10,a,20,b};
pt=c;

以下选项中表达式的值为 11 的是( )。

A ++pt->x
B pt->x
C *pt->y
D (pt++)->x
【答案】 A
【解析】 pt->x 值为 10 -> 优先级高于 ++ ,前置 ++ 表达式的值为加 1 之后的值,答案选择 A 选项。
29 .有以下程序:
 
#include <stdlib.h>
void fun(int*p1,int*p2,int*s)
{
s=(int*)malloc(sizeof(int));
*s=*p1+*p2;
free(s);
}
main()
{
int a=1,b=40,*q=&a;
fun(&a,&b,q);
printf("%d\n",*q);
}

程序运行后的输出结果是( )。

A 42
B 0
C 1
D 41
【答案】 C
【解析】 main 函数中定义了 3 个变量, a b 和指针变量 q ,并且 q 存放的是 a 的地址, fun 函数中 s 是重新
分配的空间,将重分配的空间中存放 *p1 *p2 即为 1 40 ,然后释放 s ,而 q 没有变化,仍然指向变量 a ,故 *q
仍然为 1 ,答案选择 C 选项
27.有以下程序
#include <stdio.h>
#include <stdlib.h>
main()
{
int *a,*b,*c;
a=b=c=(int*)malloc(sizeof(int));
*a=1;
*b=2,*c=3;
a=b;
printf("%d,%d,%d\n",*a,*b,*c);
}
程序运行后的输出结果是( )。

A.3,3,3

B 2,2,3
C 1,2,3
D 1,1,3
【答案】 A
【解析】 库函数 malloc(size) 用来分配 size 个字节的存储区,返回一个指向存储区首地址的基类型为 void
地址。本程序中,系统只分配了一个整型数据的存储空间,并把这个空间的地址分别赋给了指针型变量 a b
c 。程序利用指针 a 把数据 1 写入了该空间,然后利用指针 b ,把数据 2 写入该空间,因为指针型变量 a b c
指向了同一个存储空间,所以数据 2 将原来的 1 覆盖掉了,同理数据 3 又将 2 覆盖掉了。因此,此空间中最后留
有的数据是 3 。又因为 3 个指针都指向该空间,所以输出数据均为 3 。答案选择 A 选项。
14 .若有以下程序
#include <stdio.h>
#define S(x) x*x
#define T(x) S(x)*S(x)
main()
{
int k=5,j=2;
printf("%d,%d\n",S(k+j),T(k+j));
}

则程序的输出结果是( )。

A 17,37
B 49,2401
C 17,289
D 49,289
【答案】 A
【解析】 编译系统处理带参数的宏名时,按程序行中指定的字符串,括号内的内容,从左到右进行处理,若
遇到形参则以实参代替,非形参字符原样保留,就形成了替换后的内容,这期间没有任何计算。 S(k+j) 展开后是
5+2*5+2 = 17 T(k+j) 展开后是 5+2*5+2*5+2*5+2 = 37 。答案选择 A 选项。
9 .有如下程序:
#include <stdio.h>
#define D(x)4*x+1
main()
{
int i=2,j=4;
printf("%d\n",D(i+j));
}

程序运行后的输出结果是( )。

A 25
B 13
C 9
D 12
【答案】 B
【解析】 带参数的宏定义不是进行简单的字符串替换,而是要进行参数替换。替换过程是:用宏调用提供的
实参字符串,直接置换宏定义命令行中相应形参字符串,非形参字符保持不变。调用函数 D(i+j) ,进行替换为
4*i+j+1=13 ,输出 13 ,答案选择 B 选项。
21 .有以下程序:
#include <stdio.h>
main()
{
int a[10]={1,3,5,7,11,13,17},*p=a;
printf("%d,",*(p++));
printf("%d\n",*(++p));
}

程序运行后的输出结果是( )。

A 3,7
B 3,5
C 1,5
D 1,3
【答案】 C
【解析】 程序执行过程:指针 p 指向数组第一个元素; *(p++) 先取 p ,输出 p 指向的元素 1 ,之后 p 移动 1
个存储空间,指向数组第二个元素; *(++p) ,指针 p 移动 1 个存储空间指向数组第三个元素,之后输出所指元素
5 。答案选择 C 选项。
15.有以下程序
#include <stdio.h>
main()
{
int n,*p=NULL;
*p=&n;
printf("Input n:");
scanf("%d",&p);
printf("output n:");
printf("%d\n",p);
}

该程序试图通过指针 p 为变量 n 读入数据并输出,但程序有多处错误,以下语句正确的是( )。

A int n,*p=NULL;
B *p=&n;
C scanf("%d",&p);
D printf("%d\n",p);
【答案】 A
【解析】 B 项的正确写法应为“ p=&n; ”,将变量 n 的地址赋给指针 p C 项的正确写法应为“ scanf("%d",p); ”;
D 项的正确写法应为“ printf("%d\n",*p); ”。答案选择 A 选项。
59.有如下程序:
函数调用
#include<stdio.h>
int sum(int *array,int len)
{
 if(len == 0)
 return array[0];
 else
 return array[0]+sum(array+1,len-1);
}
main()
{
 int array[5] = {1,2,3,4,5};
 int res = sum(array,4);
 printf("%d\n",res);
}

程序运行后的输出结果是( )。

A 15
B 10
C 8
D 1
【答案】 A
【解析】 程序执行过程为:调用函数 sum(array,4) len=4 len>0 递归调用 sum(array+1,3) ,传入地址为 array+1
即数组第二个元素地址; len=3>0 ,递归调用 sum(array+1,2) ,传入地址为数组第三个元素地址; len=2>0 ,递归
调用 sum(array+1,1) ,传入地址为数组第四个元素地址; len=1>0 递归调用 sum(array+1,0) ,传入地址为数组第五
个元素地址,此时 len=0 ,返回 5 ;返回上一层调用执行 array[0]+sum(array+1,1) ,即 4+5 ,返回 9 ;再返回上一层
调用执行 array[0]+sum(array+1,2) ,即 3+9 ,返回 12 ;同理,最后返回 15 ,并输出。本题中需要注意的是每一层
调用时 array[0] 是不一样的,并不是指 1 。答案选择 A 选项。
54 .有以下程序
#include<stdio.h>
int f(int t[],int n);
main()
{
int a[4]={1,2,3,4},s;
s=f(a,4);
printf("%d\n",s);
}
int f(int t[],int n)
{
if(n>0)return t[n-1]+f(t,n-1);
else return 0;
}

程序运行后的输出结果是( )。

A 4
B 10
C 14
D 6
【答案】 B
【解析】 函数 f 的功能是通过递归计算数组 t 中元素的和。在主函数中调用了递归函数 f(a,4) ,将递归函数 f(a,4) 的递归式展开,
s = f(a,4) = a[3] + f(a,3) = a[3] + a[2] + f(a,2) = a[3] + a[2] + a[1] + f(a,1) = a[3] + a[2] + a[1] + a[0]
+ f(a,0) = a[3] + a[2] + a[1] + a[0] + 0 = 4 + 3 + 2 + 1 + 0 = 10 。答案选择 B 选项。
40.有以下程序
则以下函数调用语句错误的是( )。
#include <stdio.h>
int add(int a,int b)
{
return (a+b);
}
main()
{
int k,(*f)(),a=5,b=10;
f=add;
…
}
A k=*f(a,b);
B k=add(a,b);
C k=(*f)(a,b);
D k=f(a,b);
【答案】 A
【解析】 int (*f)(int, int) 声明了一个函数指针,它可以指向一个函数,该函数的形参是两个 int ,返回值是 int
f=add ,是把函数 add 的地址赋给指针 f ,选项 B 正确;函数指针的调用有两种方式, (*f)() f() ,选项 C D
确。 f(a,b) 已经表示调用函数 add ,返回 15 k=*15 出现编译错误,选项 A 错误。答案选择 A 选项。
21.有以下函数:程序运行后的输出结果是( )。
#include <stdio.h>
void func(int n)
{
 int i;
 for(i=0;i<=n;i++)printf("*");
 printf("#");
}
main()
{
 func(3);
 printf("????");
 func(4);
 printf("\n");
}

A.****#????***#

B ***#????*****#
C **#????*****#
D ****#????*****#
【答案】 D
【解析】 main 函数开始,执行 func(3) 函数, for 循环执行 4 次,连续输出四个“ * ”,然后输出一个“ # ”;
输出“ ???? ”;再次调用 func(4) for 循环执行 5 次,连续输出五个“ * ”,然后输出一个“ # ”;最后输出换行
符。答案选择 D 选项。
 173.有以下程序:
#include <stdio.h>
#include <string.h>
main()
{
char s[]="Beijing";
printf("%d\n", strlen(strcpy(s,"China")));
}

程序运行后的输出结果是( )。

A 5
B 7
C 12
D 14
【答案】 A
【解析】 在存储字符串常量时,由系统在字符串的末尾自动加一个 '\0' 作为字符串的结束标志。 strcpy 函数将
"China" 复制给字符数组 s ,内存存储情况为 "China\0" strlen 函数统计字符串长度时,遇到 '\0' 结束, s 数组长度为
5 。答案选择 A 选项。
187.有以下程序

#include <stdio.h>
#include<string.h>
main()
{
char str[][20]={"One*World","One*Dream!"},*p=str[1];
printf("%d,",strlen(p));
printf("%s\n",p);
}

程序运行后的输出结果是( )。

A 6
B 9
C 11
D 7
【答案】 A
【解析】 首先定义了 3 个字符数组 p
q
r ,并分别被初始化。数组 p 指定的大小为 20 ,初始化列表为 {'a','b','c','d'}
即只指定了前 4 个元素的内容,根据 C 语言的规定,初始化列表不足时,其余元素均自动初始化为 0 。然后通过
strcat 函数,将字符串 r 连接到字符串 p 之后,即执行后 p 中的内容为 "abcdabcde" "strlen(q)" 表示求字符串 q
长度,不包括最后的字符串结束符,得到 3 ,所以语句 "strcpy(p+strlen(q),q); " 的作用就是:将字符串 q 复制到数
p 的第 4 个元素位置处,数组 p 变成 {'a','b','c', 'a','b','c'} ,所以字符串 p 的长度是 6 。答案选择 A 选项。
181.有以下函数:
int fun(char *s,char *t)
{
while((*s)&&(*t)&&(*t++==*s++));
return (*s-*t);
}

函数的功能是( )。

A .求字符串的长度
B .比较两个字符串的大小
C .将字符串 s 复制到字符串 t
D .连接字符串 s 和字符串 t
【答案】 B
【解析】 函数体执行过程为:将两个字符串首地址传入函数,分别赋给指针 s t ,在函数体内 s t 所指向
的字符串的字符不为 '\0' 时,判断两个指针指向的字符是否相同,若相同则两个指针分别加一指向下一个字符,
若不同则退出 while 循环,返回不相同的字符的 ASCII 码值之差。返回值大于 0 表示字符串 s>t ;返回值小于 0
表示 s<t ;返回值为 0 ,表示 s=t 。函数实现了比较两个字符串大小的功能。答案选择 B 选项。
178.有以下函数
int fun(char *s)
{
char *t=s;
while(*t++);
return(t-s);
}

该函数的功能是( )。

A .计算 s 所指字符串占用内存字节的个数
B .比较两个字符串的大小 C .计算 s 所指字符串的长度
D .将 s 所指字符串复制到字符串 t
【答案】 A
【解析】 本题中,首先让 t 指向形参 s ,然后通过一个循环体为空的 while 循环,将 t 逐次后移,直到其所指
内容为 '\0' (字符串结束标志)。此时 t 仍然会被增 1 ,所以从循环出来, t 指向的是 s 所指字符串的结束标志的后
一个字节。因此,返回的 t-s s 所指字符串占用内存字节的个数, A 项正确。而 C 项所说的长度并不包括字符
串结束标志位,错误。答案选择 A 选项
165.有如下程序:
#include<stdio.h>
#include<string.h>
main()
{
char a[]="THIS", *b="OK";
printf("%d,%d,%d,%d\n", strlen(a), sizeof(a), strlen(b), sizeof(b));
}
程序运行后的输出结果是( )。A.4,5,2,4
B.4,4,2,1
C.5,5,3,3
D.4,5,2,3

【答案】 A
【解析】 strlen 函数统计字符串长度,遇到 '\0' 统计结束。 sizeof 用来获取类型或数据对象的长度,也即是一
个这种数据类型的变量在内存中所占字节数。 a 数组 '\0' 之前有效字符有 4 个,由于字符串有效字符之后有一个 '\0'
也会被放入数组, char 类型占一个字节,所以数组 a 所占字节数为 1*5=5 b 为指向字符串的指针,字符串长度
2 ,指针类型变量所占字节数为 4 。答案选择 A 选项。
164.有以下程序
#include<stdio.h>
#include<string.h>
main()
{
char x[]="STRING";
x[0]=0;
x[1]='\0';
x[2]='0';
printf("%d %d\n",sizeof(x),strlen(x));
}
程序运行后的输出结果是( )。
A 6 1
B 7 0
C 6 3
D 7 1
【答案】 B
【解析】 sizeof 是返回字符串在内存中所占用的空间,是字符数组真正的长度。 strlen 是返回字符串的长度,
strlen 遇到 '\0' ASCII 码值为 0 )就结束,而且不包括 '\0' 。题目中数组 x 初始化为字符串 "STRING" 6 个字符加
上字符串结束符共占用 7 个字节长度,所以 sizeof(x) 返回值为 7 。数组 x 在初始化后,又重新赋值 x[0] = 0 ,即
x[0] = '\0' ,所以 strlen(x) 返回值为 0 。答案选择 B 选项。
140.若有以下程序段
char str[4][12] = {"aa","bbb","ccccc","d"}, *strp[4];
int i;
for(i=0;i<4;i++)strp[i]=str[i];
不能正确引用字符串的选项是( )。
A *strp
B str[0]
C strp[3]
D strp
【答案】 D
【解析】 strp char * 类型、长度为 4 的数组, 4 个指针分别指向字符串数组 str 中的 4 个字符串。 D 项错误,
strp char * 的数组,不能引用字符串。 A 项正确,引用 strp 数组中第一个指针指向的内容,即 "aa" B 项正确,
str 是字符串数组,引用数组中的 "aa" C 项正确, strp[3] 等价于 *(strp+3) ,访问 strp 中第四个指针指向的内容,
"d" 。答案选择 D 选项。

131.有以下程序
​​​​​​​#include <stdio.h>
main()
{
char a[20],b[20],c[20];
scanf("%s%s",a,b);
gets(c);
printf("%s%s%s\n",a,b,c);
}
程序运行时从第一列开始输入:
This is a cat!< 回车 >
则输出结果是( )。
A Thisisacat!
B Thisis a
C Thisis a cat!
D Thisisa cat!
【答案】 C
【解析】 scanf() 函数的 %s 格式符输入字符串时,空格和回车符都作为输入数据的分隔符而不能被读入;
gets 函数可以一次接收一行输入字符串,其中可以有空格。在本题中,字符数组 a 的赋值到输入的第一个空格
即结束, a 的值为“ This ”,同理 b 的值为“ is ”;而 gets(c) 函数可以接收该行剩余的所有字符,所以 c 被赋值为“ a
cat! ”。故输出的结果为 Thisis a cat! 。答案选择 C 选项。
22 .有以下程序:

#include <stdio.h>
main()
{
 char s[]={"012xy"};
 int i,n=0;
 for(i=0;s[i]!='\0';i++) if(s[i]>='a'&&s[i]<='z')n++;
 printf("%d\n",n);
}
程序运行后的输出结果是( )。
A 0
B 2
C 3
D 5
【答案】 B
【解析】 程序中 main 函数的作用就是判断字符串 s 中小写字母的个数,显然结果为 2 。答案选择 B 选项。
30 .有以下程序段
#include<stdio.h>
main()
{
int j;
float y;
char name[50];
scanf("%2d%f%s",&j,&y,name);
}
当执行上述程序段,从键盘上输入 55566 7777123 后, y 的值为( )。
A 566.0
B 55566.0
C 7777.0
D 566777.0
【答案】 A
【解析】 本题考查的是格式输入函数,即按用户指定的格式从键盘上把数据输入到指定的变量之中,其中的
格式命令可以说明最大域宽。在百分号 % 与格式码之间的整数用于限制从对应域读入的最大字符数。因此 j 的值
55 y 的值为 566.0 ,字符数组 name 的值为 7777123 。答案选择 A 选项。
23.有以下程序:
#include <stdio.h>
main()
{
char c1,c2;
c1='A'+'8'-'4';
c2='A'+'8'-'5';
printf("%c,%d\n",c1,c2);
}

已知字母 A ASCII 码为 65 ,程序运行后的输出结果是( )。
A E,68
B D,69
C E,D
D .输出无定值
【答案】 A
【解析】 C 语言中每个字符都对应一个 ASCII 码值,该值可以用来运算。本题中 main 函数将字符 A 经过加
四和加三运算后分别赋值给 c1 c2 ,则 c1='E' c2='D' ,然后将 c1 按字符格式输出, c2 按整型格式输出。答案选
A 选项。
37.有以下程序
程序运行后的输出结果是( )。
#include <stdio.h>
main()
{
 int x=1, y=0;
 if (!x) y++;
 else if (x==0)
 if (x) y+=2;
 else y+=3;
 printf("%d\n", y);
}
A 0
B 2
C 1
D 3
【答案】 A
【解析】 在该题中,选择结构的表达式都不成立,所以整个选择语句都没有执行, y 值没有发生改变,答案
选择 A 选项。
112.有以下程序:
#include <stdio.h>
main()
{
int a=1,b=0;
if(--a) b++;
else if(a==0) b+=2;
else b+=3;
printf("%d\n",b);
}
程序运行后的输出结果是( )。
A.0
B.1
C.2
D.3
【答案】 C
【解析】 ++ ”和“ -- ”运算,当以前缀形式出现时,则先进行加一或减一操作,再进行其他运算,当以后
缀形式出现时,则先进行其他运算,再进行加一或减一操作。 a 初始定义为 1 b 0 ,执行 --a a 的值变为 0
--a 的值也为 0 ,即 if 判断为假,执行 b+=2 ,输出 b 的值为 2 。答案选择 C 选项。
43.有以下程序
#include<stdio.h>
main()
{
int a=0,b=0,c=0,d=0;
if(a=1)b=1;c=2;
else d=3;
printf("%d,%d,%d,%d\n",a,b,c,d);
}
程序输出( )。
A.0,0,0,3
B.编译有错
C.1,1,2,0
D.0,1,2,0
【答案】 B
【解析】 如果 if 的执行语句含有多个语句(两个以上),则必须使用复合语句,即用花括号把一组语句括起 来;否则,紧跟 if 的下一条语句是它的执行语句,因此 c=2 不是 if 执行语句,它是在 if else 之间的语句。在 程序中 else 必须与 if 配对,共同组成一条 if-else 语句,中间不能出现其他语句,因此该程序编译错误。答案选 择 B 选项。
20 .有以下程序:
#include <stdio.h>
main()
{
int i=0,sum=1;
do
{
sum += i++;
}while(i<6);
printf("%d\n",sum);
}
程序的输出结果是( )。
A.22
B.18
C.20
D.16
【答案】 D
【解析】 语句 sum+=i++ ;相当于 sum+=i i++ ;程序执行过程为: sum=1 i=1 sum=2 i=2 sum=4 i=3 ; sum=7, i=4 sum=11 i=5 sum=16 i=6 ;退出循环。答案选择 D 选项。
22 .有以下程序(注:字符 a ASCII 码值为 97 ):
程序运行后的输出结果是( )。
#include <stdio.h>
main()
{
 char *s={"abc"};
 do
 {
 printf("%d",*s%10);
 ++s;
 }while(*s);
}
A.abc
B 789
C 7890
D 979800
【答案】 B
【解析】 a b c ASCII 值分别为 97 98 99 。程序中执行输出 s 中字符对应的 ASCII 码与 10 进行模运
算后的值, s 是一个指针,首先指向字符 a ,先执行 97%10 ,结果为 7 ;然后 ++s ,指针指向下一个字符 b ,执行
98%10 ,结果为 8 ,直到 s 所指为空,故最后输出的结果为 789 。答案选择 B 选项。
26.有以下程序:
#include<stdio.h>
main()
{
int x=0,y=6;
do
{
while(--y)x++;
}
while(y--);
printf("%d,%d\n",x,y);
}
程序的运行结果是( )。
A.5,0
B.6,0
C.5,-1
D.6,-1

【答案】C

【解析】 程序执行过程为:执行 do while 的循环体: y=5 ,判断 y 为真, x=1 y=4 x=2 y=3 x=3 y=2 x=4 y=1 x=5 y=0 ,判断 y 为假,退出循环体。判断 do while 条件 y=0 为假, y=-1 ,退出循环。输出 x,y
5,-1 ,答案选择 C 选项。
32 .有如下程序段:
for 循环体执行的次数是( )。
int k;
for(k=2;k==0;)
 printf("%d",k--);
A 0
B 1
C 2
D .无限次
【答案】 A
【解析】 for(k=2;k==0;) ”表示给 k 赋值 2 ,如果 k 等于 0 ,则进入循环,但是 k 不满足条件,因此循环体不
执行。答案选择 A 选项。

39.有以下程序

程序运行后的输出结果是( )。

#include<stdio.h>
main()
{
 int a=1,b=2;
 for(;a<8;a++)
 {
 b+=a;
 a+=2;
 }
 printf("%d,%d\n",a,b);
}
​​​​​​​​​​​​​​​​​​​​​A.9,18
B 8,11
C 7,11
D 10,14
【答案】 D
【解析】 初始值 a=1 b=2 ,第一次循环: b=b+a=2+1=3 a=a+2=1+2=3 a=a+1=3+1=4 ;第二次循环: b=b+a=3+4=7
a=a+2=4+2=6 a=a+1=6+1=7 ;第三次循环: b=b+a=7+7=14 a=a+2=7+2=9 a=a+1=9+1=10 ,不满足 for 循环条
件退出循环,最终 a=10 b=14 。答案选择 D 选项。
48 .有以下程序 程序运行后的输出结果是( )。
#include<stdio.h>
main()
{
 int i,sum;
 for(i=1;i<6;i++)sum+=i;
 printf("%d\n",sum);
}

A.0

B.随机值

C 15
D 16
【答案】 B
【解析】 sum 作为局部变量,没有显式初始化, sum 值代表原来内存中存储的对象,不可预知,程序结果是
随机值。答案选择 B 选项。
53 .有以下程序
程序运行后的输出结果是( )。
#include<stdio.h>
main()
{
 int b[3][3]={0,1,2,0,1,2,0,1,2},i,j,t=1;
 for(i=0;i<3;i++)
 for(j=i;j<=i;j++)t+=b[i][b[j][i]];
 printf("%d\n",t);
}
A 1
B 3
C 4
D 9
【答案】 C
【解析】 for(j=i;j<=i;j++) 可知,内层循环变量 j 只可以取当前外层循环变量 i 的值。当 i=0 j=0 时,
b[0][b[0][0]]=0 ;当 i=1 j=1 时, b[1][b[1][1]]=1 ;当 i=2 j=2 时, b[2][b[2][2]]=2
t 初始值为 1 ,故结果 t=1+0+1+2=4
答案选择 C 选项。
22.有以下程序:
#include <stdio.h>
main()
{
char s[]={"012xy"};
int i,n=0;
for(i=0;s[i]!='\0';i++) if(s[i]>='a'&&s[i]<='z')n++;
printf("%d\n",n);
}
程序运行后的输出结果是( )。

A.0

B.2

C 3
D 5
【答案】 B
【解析】 程序中 main 函数的作用就是判断字符串 s 中小写字母的个数,显然结果为 2 。答案选择 B 选项。

82.有以下程序
#include<stdio.h>
main()
{
int a[3][4] = {1,3,5,7,9,11,13,15,17,19,21,23}, (*p)[4]=a,i,j,k=0;
for(i=0;i<3;i++)
for(j=0;j<2;j++) k=k+=*(*(p+i)+j);
printf("%d\n",k);
}
程序运行后的输出结果是( )。
A 99
B 68
C 60
D 108
【答案】 C
【解析】 定义了二维数组 a p 是指针,它指向长度为 4 int 数组,初始化时, p 执行 a[0] *(*(p+i)+j)
当于 a[i][j] main 函数的作用是计算数组 a 中前两列的和,结果是 60 。答案选择 C 选项。
106.有如下程序:
#include <stdio.h>
main()
{
 char name[10] = {'S','T','R','I','N','G'};
 name[3]='E';
 name[5]=0;
 printf("%s\n",name);
}
程序运行后的输出结果是( )。
A STRENG
B STRIEG
C STREN
D STREN0
【答案】 C
【解析】 printf 函数按照格式符说明输出对应的数据。 %s 控制符用于输出字符串,输出时从给定地址开始依
次输出字符,直到遇到 '\0' 结束。给字符变量赋值 0 ,相当于赋值 '\0' 。初始化时 name = "STRING" ,改动数组第 4
个和第 6 个元素之后字符串变为 "STREN" 。调用 printf 输出字符串为 STREN ,答案选择 C 选项。
124.有以下程序:
#include <stdio.h>
int fun(char *s)
{
char *p=s;
while(*p++!='\0');
return(p-s);
}
main()
{
char *p="01234";
printf("%d\n",fun(p));
}
程序的运行结果是( )。
A.6
B.5
C.4
D.3
【答案】 A
【解析】 程序执行过程为:定义字符串指针 p 并为其初始化为 "01234" ,调用函数 fun(p) ,将指针传入函数。
fun 函数功能即返回字符串首地址与结束符下一个地址之差,也即是字符串长度加 1 。输出地址差为 6 ,答案选择
A 选项。
​​​​​​​
  • 11
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值