一、选择题 17. 有以下程序:
#include <stdio.h>
main()
{
int x;
scanf("%d",&x);
if(x>10) printf("1");
else if(x>20) printf("2");
else if(x>30) printf("3");
}
若运行时输入:35<回车>,则输出结果是______。
A B C D
D
[解析] 程序执行过程为:输入35<回车>,scanf函数从键盘读入35赋值给x=35,对if条件进行判断,35>10,条件成立,输出1,不再执行下面的else if语句,程序结束,输出结果为1,故D选项正确。
19. 有以下程序:
#include <stdio.h>
main()
{
int i=1,k=0;
for( ; i<6; )
{ switch(i%3)
{ case 0: k++;
case 1: k++; break;
case 2: k++; continue;
}
i+=1;
}
printf("%d\n",k);
}
程序的运行情况是______。
A B C D
A
[解析] switch语句是一种多分支选择语句,执行过程为:计算switch后圆括号内的表达式的值,然后用该值逐个去与case后的常量表达式值进行比较,当找到相匹配的值时,就执行该case后面的语句。若均不匹配的,就执行default后面的语句。执行完一个case后面的语句后,程序就转移到下一个case处继续执行,并不再进行判断。break语句作用是结束整个循环过程,不再判断执行循环的条件是否成立,且在嵌套循环中,其只跳出最内层的一层循环,在分支结构中,跳出最内层分支结构。continue语句只能用在循环结构中,其作用是结束本次循环,即不再执行循环体中continue语句之后的语句,而是立即转入对循环条件的判断与执行。本题执行过程为:i=1,k=0,i<6成立,执行for循环:i%3=1,匹配case1,k=1,break退出switch,i=2;i<6成立,执行for循环:i%3=2,匹配case2,k=2,执行continue,由于其只用于循环结构,退出switch,且不执行此次for循环以后的语句,i=2不变,i<6成立,执行下一次for循环,以后的循环情况与刚刚的情况完全一致,i=2不会改变,形成无限循环。故A选项正确。
22. 有以下程序段:
scanf("%d%d%d",&a,&b,&c);
if(a<b)a==b;
if(a<c)a==c;
printf("%d\n",a);
该程序段的功能是______。
A.输出a、b、c中值相等的数值 B.输出a、b、c中的最大值 C.输出a、b、c中的最小值 D.输出a的原始值
A B C D
D
[解析] 程序段执行过程为:从键盘读入3个整型数据分别赋值给a,b,c,如果a<b,判断a与b是否相等,无论结果如何不做任何改变。如果a<c,判断a与c是否相等,无论结果如何均不做任何改变。区分‘==’操作符和‘=’操作符。最后对于a,b,c的值不做任何改变,输出a的原始值,故D选项正确。
23. 以下程序的功能是:通过调用calc函数,把所求得的两数之和值放入变量add中,并在主函数中输出。
#include <stdio.h>
void calc(float x,float y,float *sum)
{______ = x+y;}
main()
{ float x,y,add;
scanf("%f%f",&x,&y);
calc(x,y,&add);
printf("x+y=%f\n",add);
}
calc函数中下划线处应填入的是______。
A B C D
A
[解析] 程序的执行过程为:从键盘读入两个float类型数据,分别赋给x,y,调用函数calc将x与y的值与add变量地址传入函数,地址赋给指针sum,函数体中将两数之和放入指针指向的地址,指针正确的引用形式为(*sum),这表示变量,可以被赋值。所以横线处填写*sum,故A选项正确。
24. 有以下程序:
#include <stdio.h>
main()
{ char a [4][4]={''};
int i,j;
for(i=0;i<4; i++)
{ a[i][0]=a[i][3]='#';
for(j=1; j<3; j++)
{ a[0][j]=a [3][j]='#';
if((i!=0)&&(i! =3)) a[i][j]='o';
}
{
for(i=1;i<3;i++)
{ for(j=0; j<4;j++)
printf("%2c" ,a[i][j]);
printf("\n");
}
}
程序的运行结果是______。
A.#o o# #o o# B.# # # # # o o # C.# o o # # # # # D.# # # # # # # #
A B C D
A
[解析] 程序的执行过程为:定义4行4列二维数组字符a并且初始化为a[0][0]='',其他元素均为0。执行for循环将数组第一列和第四列赋值为‘#’。执行for循环将数组第一行和第四行的第二个到第三个元素赋值为‘#’,然后将剩余元素全部赋值为‘0’。此时矩阵为{{#,#,#,#},{#,o,o,#},{#,o,o,#},{#,#,#,#}}。之后输出矩阵第二行与第三行元素为:# o o #<回车># o o #,故A选项正确。
26. 有以下程序:
#include <stdio.h>
void fun(int *x,int s,int n)
{ int i;
for(i=s; i>=n; i--)
*(x+i+3) = * (x+i);
}
main()
{ int m[] = {0,1,2,3,4,5,6,7,8,9},k;
fun(m,10-4,3);
for(k=0; k<10;k++)
printf("%d",m[k]);
}
程序的运行结果是______。
A.0123456345 B.0123453456 C.0123456666 D.0123454569
A B C D
B
[解析] 程序的执行过程为:定义数组m,并为其赋初值,数组长度为10。调用函数fun(m,6,3)将数组首地址传入函数,函数实现将数组下标值从6到3的元素依次向下标值大的方向移动三个位置,for循环结束之后数组为m={0,1,2,3,4,5,3,4,5,6}。依次输出数组元素,结果为0123453456,故B选项正确。
30. 有以下程序:
#include <stdio.h>
main()
{ char s[10]="verygood", *ps=s;
ps+=4;
ps="nice";
puts(s);
}
程序的运行结果是______。
A.nice B.verynice C.nicegood D.verygood
A B C D
D
[解析] 将字符指针变量初始化为一个字符串有两种方式,其中的一种通过赋值运算使一个字符指针指向一个字符串常量:char*ps;ps="nice"。这种形式只是将字符串“nice”首地址赋给指针,而不是将指针原本指向的单元元素改变成“nice”。程序执行过程为:定义字符数组并且初始化为“verygood”常量,常量存在于内存的常区,不得通过任何方式来修改内存中的内容(当然可以释放这块内存),定义指针ps使其指向数组,使ps指向数组第5个元素,使指针指向字符串“nice”’,这并不影响s数组任何元素值,故输出字符串s为“verygood”,故D选项正确。
31. 有以下程序:
#include <stdio.h>
int fun(char *s)
{ char *p=s;
while(*p !='\0')p++;
return(p-s);
}
main()
{ char *p="01234";
printf("%d\n",fun(p));
}
程序的运行结果是______。
A B C D
D
[解析] 程序执行过程为:定义指针p,初始化为字符串“01234”首地址。调用函数fun,将指针传入函数,定义指针s使其指向字符串第一个字符。while循环使指针p指向字符串结束符’\0’,返回两个指针差,也即是字符串长度5。最后输出5,故D选项正确。
32. 有以下程序:
#include <stdio.h>
main()
{ int findmax(int,int,int),m;
┋ m=findmax(a,b,e);
┋ }
int findmax(int x,int y,int z)
{ … }
则以下叙述正确的是______。
A.在main函数中声明了findmax函数 B.在main函数中定义了findmax函数 C.在main函数中两次调用了findmax函数 D.在main函数内、外重复定义了findmax函数
A B C D
A
[解析] 程序编译是从上到下进行的,所以如果函数定义放在主函数之后,那么在函数调用时必须提前声明函数,可以在主函数之前声明函数,也可以在主函数中函数调用之前声明函数。题目中函数findmax定义放在了函数之后,所以主函数中声明了.findma函数。int findmax(int,int,int);为函数声明,m=findmax(a,b,c);为函数调用,int findmax(intx,inty,int z){}为函数定义。A选项正确。B选项是在main函数外定义的findmax函数,错误。在main函数中,出现了一次findmax函数的声明和一次findmax函数的调用,不是两次调用,C选项错误。D选项在main函数内不是定义findmax函数而是声明findmax函数。
33. 有以下程序:
#include <stdio.h>
void fun(int n)
{ int i;
if((i=n/10)!=0)
fun(i);
putchar(n%10+'0');
}
main()
{ fun(256); }
程序运行后的输出结果是______。
A B C D
A
[解析] 程序的执行过程为:调用函数fun(256),i=25,i!=0,if条件成立,调用:fun(25),i=2,i!=0,if条件成立,调用fun(2),i=0,if条件不成立,输出字符’2’,返回fun(25),输出字符’5’,返回fun(256),输出字符’6’,函数调用结束。程序运行后的输出结果是256,故A选项正确。
34. 有以下程序:
#include <stdio.h>
#include <stdlib.h>
void fun(int*p1, int *s)
{ int *t;
t=(int *)malloc(2 * sizeof(int));
*t=*p1 + *p1 ++;
*(t+1)=*p1+ *p1;
s=t;
}
main()
{
int a[2]={1,2},b[2]={0};
fun(a,b);
printf("%d,%d\n",b[0],b[1]);
}
程序运行后的输出结果是______。
A B C D
B
[解析] malloc函数的原型为:malloc(size);,函数的作用是在内存的动态存储区分配一个长度为size的连续空间。程序执行过程为:定义数组a={1,2},b={0,0},b,调用函数fun,将数组地址传入函数,指针p1指向a,s指向b,定义指针t并使其指向开辟的两个整型内存,为第一个内存赋值为数组a第一个元素的2倍,即2,然后指针p1指向a数组第二个元素,为第二个内存赋值为数组a第二个元素的2倍,即4,最后使指针s指向动态开辟的两个内存的首地址。整个过程中数组b没有发生变化,依次输出b中元素为0,0,故B选项正确。
35. 有以下程序:
#include <stdio.h>
#define FNA(x) x*x
#define FNB(x) x+z
main()
{ int a=2,b=4;
printf("%d,%d\n",FNA(FNB(a)),FNB(FNA(b)));
}
程序运行后的输出结果是______。
A.8,16 B.16,32 C.8,32 D.16,16
A B C D
C
[解析] 带参数的宏定义不是进行简单的字符串替换,而是要进行参数替换不计算,只是进行简单的替换。替换过程是:用宏调用提供的实参字符串,直接置换宏定义命令行中相应形参字符串,非形参字符保持不变。FNA(FNB(a))的替换过程为:FNA(2+2)替换为2+2×2+2,计算结果为8。FNB(FNA(b))的替换过程为:FNB(4*4)替换为4×4+4×4=32。程序运行后的输出结果是8,32,故C选项正确。
36. 设有如下语句:
typedef struct Date{
int year;
int month;
int day;
} DATE;
则以下叙述中错误的是______。
A.DATE是用户定义的结构体变量 B.struct Date是用户定义的结构体类型 C.DATE是用户说明的新结构体类型名 D.struct是结构体类型的关键字
A B C D
A
[解析] C语言允许用typedef说明一种新类型名,其一般形式如下:typedef类型名新类型名;,题目中定义了新类型Date,这种类型变量包含3个成员,DATE是这种新类型的名字。DATE是用户说明的新结构体类型名,不是结构体变量,C选项叙述正确,A选项叙述错误,选择A选项。structDate是用户定义的结构体类型,B选项叙述正确。struct是结构体类型的关键字,D选项叙述正确。
38. 有以下程序:
#include <stdio.h>
#include <string.h>
typedef struct {
char name[10];
char sex;
int age;
} STU;
void fun(STU t)
{ strcpy(t.name,"Tong");
t.age++;
}
main()
{ STU s[2]=t"Hua",'m',18,"Qin",'f',19};
fun(s[1]);
printf("%s,%d,%s,%d\n",s[0].name,s[0].age,s[1].name,s[1].age);
}
程序运行后的输出结果是______。
A.Hua,19,Tong,19 B.Hua,18,Tong,20 C.Tong,19,Qin,19 D.Hua,18,Qin,19
A B C D
D
[解析] 用typedef说明一种新类型名STU,其使用情况与结构体基本一致。程序执行过程为:定义STU类型数组,长度为2,并为其初始化。s[0].name="Hua",s[0].sex='m',s[0].age=18,s[1].name("Qin",s[1].sex='f',s[1].age=19。调用函数fun(s[1])将变量s[1]值传入函数,则t.name="Qin",t.sex='f',t.age=19。调用函数strcpy使t.name="Tong",t.age=20,函数调用结束。其中结构体数组中元素并没有发生改变,依次输出s[0].name,s[0],age,s[1].name,s[1].age,结果为Hua,18,Qin,19,故D选项正确。
40. 有以下程序段:
FILE *fp;
if((fp=fopen("test.txt","w"))== NULL)
{ printf("不能打开文件!");
exit(0);}
else
printf("成功打开文件!");
若文件test.txt已存在,则以下叙述正确的是______。
A.程序运行后,文件test.txt中的原有内容将全部消失 B.程序运行时,会因文件存在而出错 C.对文件test.txt进行写操作后,可以随机进行读取 D.对文件test.txt写入的内容总是被添加到文件尾部
A B C D
A
[解析] fopen函数以一定方式打开指定文件,返回一个指向文件的文件指针,如果不能实现打开指定文件的操作,则返回一个空指针NULL。如果指定文件不存在,则创建一个文件名为指定文件名的新文件,然后打开它。在指定文件有错误或者指定文件不存在却不能创建新文件的情况下,打开文件操作错误,返回空指针。本题程序中,文件test.txt已存在,程序运行后,文件test.txt中的原有内容将全部消失,A选项正确。文件原本就存在,不会导致程序出错,会按照指定的方式打开文件,B选项错误。对文件进行写操作,只能对指针指向的位置内容进行写操作,不能随机读写,C选项错误。对文件test.txt写入的内容写到指针所指向的位置,而不是添加在文件尾部,D选项错误。
二、程序填空题 1. 下列给定程序中,函数fun的功能是:统计带头节点的单向链表中节点的个数,并存放在形参n所指的存储单元中。
请在程序的下画线处填入正确的内容,使程序得出正确的结果。
注意:部分源程序给出如下。
不得增行或删行,也不得更改程序的结构!
试题程序:
#include <stdio.h>
#include <stdlib.h>
#define N 8
typedef struct list
{ int data;
struct list * next;
} SLIST;
SLIST * creatlist(int *a);
void outlist(SLIST*);
vom fun(SLIST * h, int * n)
{ SLIST *p;
/**********found**********/
______ =0;
p=h->next;
while(p)
{ (* n)++;
/**********found**********/
p=p-> ______ ;
}
}
main()
{ SLIST * head;
int a[N]={12,87,45,32,91,16,20,48}, num;
head=creatlist(a);
outlist(head);
/**********found**********/
fun(______, &hum);
printf("\nnumber=%d\n",num);
}
SLIST * creatlist(int a[])
{ SLIST *h,*p,*q; int i;
h=p=(SLIST*)malloc(sizeof(SLIST));
for(i=0;i<N;i++)
{ q=(SLIST*)malloc(sizeof(SLIST));
q->data=a[i]; p->next=q;
p=q;
}
p->next=0;
return h;
}
void outlist(SLIST*h)
{ SLIST * p;
p=h->next;
if(p==NULL)
printf("The list is NULL!\n");
else
{ printf("\nHead");
do
{ printf("->%d",p->data);
p=p->next; }
while(p! = NULL);
printf("->End\n");
}
}
*n next head
[考点] 本题考查:变量赋初值操作;链表节点的数据域和指针域表示方法;函数调用。 [解析] 填空1:*n用来存放节点的个数,对其赋初值为0。 填空2:while循环用于遍历链表,循环一次,指针指向链表的下一个节点。 填空3:根据函数定义语句确定调用函数的实际参数,即fun(head,&num);。
三、程序修改题 1. 下列给定程序中,函数fun的功能是:求出S所指字符串中最后一次出现的t所指字符串的地址,并通过函数值返回,在主函数中输出从此地址开始的字符串;若未找到,则函数值为NULL。
例如,当字符串中的内容为“abcdabfabcdx”,t中内容为“ab”时,输出结果应是“abcdx”。
请改正程序中的错误,使它能得出正确的结果。
注意:不要改动main函数,不得增行或删行,也不得更改程序的结构!
试题程序:
#include <stdlib.h>
#include <stdio.h>
#include <conio.h>
#include <string.h>
char * fun(char*s,char * t)
{
char * p, *r, *a;
/**********found**********/
a=Null;
while(*s)
{
p=s;r=t;
while(*r)
/***********found**********/
if(r==p)
{r++;p++;}
else break;
if(*r=='\0')a=s;
s++;}
return a;
}
void main()
{
char s[100],t[100],*p;
system("CLS");
printf("\nPlease enter string S:");
scanf("%s",s);
printf("\nPlease enter substring t:");
scanf("%s",t);
p=fun(s,t);
if(p)
printf("\nThe result is:%s\n",p);
else
printf("\nNot found!\n");
}
a=NULL; if(*r==*p)
[考点] 本题考查:C语言关键字;if语句条件表达式;指针型变量。 [解析] a=NULL;是个明显的语法错误,指针指向空值的关键字应为NULL。 r和p均为指针变量,分别指向两个字符串中的字符变量,循环条件是当r和p所指向的字符相同时,进行指针后移操作,故此处应为if(*r==*p)。
四、程序设计题 1. 编写函数fun,其功能是:将两个两位数的正整数a、b合并成一个整数放在c中。合并的方式是:将a数的十位和个位数依次放在c数的十位和千位上,b数的十位和个位数依次放在c数的百位和个位上。
例如,当a=45,b=12时,调用该函数后,c=5142。
注意:部分源程序给出如下。数据文件IN.DAT中的数据不得修改。
请勿改动主函数main和其他函数中的任何内容,仅在函数fun的花括号中填入编写的若干语句。
试题程序:
#include <stdlib.h>
#include <stdio.h>
#include <conic.h>
void fun(int a,int b,long*c)
{
}
void main()
{
int a,b;
long c;
system("CLS");
printf("Input a,b;");
scanf("%d%d",&a,&b);
fun(a,b,&c);
printf("The result is:%ld\n",c);
}
void fun(int a,int b,long*c) { /*b%10获取b的个位,a/10获取a的十位,a%10获取a的个位,b/10获取b的十位*/ *c=b%10+(a%10)*10+(b/10)*100+(a/10)*1000; }
[考点] 本题考查:如何取出数n的各个位数值;知道数n的各个位数值,又如何表示该数;指针型变量的使用。 [解析] 本题主要的问题是如何取出a和b的个位数和十位数,取出后如何表示成e中相应的位数。由于a和b都是只有两位的整数,所以分别对它们除10可得到它们的十位数,分别用10对它们求余可得到它们的个位数。得到后对应乘以1000、100、10、1即可得到c的千位数、百位数、十位数和个位数。注意使用c时要进行指针运算。 如果知道某两位数n,需要表示其个位数值和十位数值,可以采用求余和除法操作,例如n%10(取个位),n/10(取十位)。