期末复习练习解析03
1、选择题:
1.1、C 语言中若以 2 个字节表示 int 类型数据,所能表示的最大整数为:(D)
A、216 B、215 C、216-1 D、215 -1
解析:2个字节共有2*8=16位,其中一位作为符号位,剩下15位表示数据。包括:负数、0、正数。其中,最大整数(二进制表示中,所有15位上面都为1)为:215 -1。
1.2、若有 int x,y; 则表达式 x==0&&y!=0||x!=0&&y==0 等效于:(A)
A、x*y==0&&x+y!=0
B、x*y==0&&(x+y==0)
C、x==0||y==0
D、x*y=0||x+y=0
解析:x==0&&y!=0||x!=0&&y==0,根据优先级加上括号:(x==0&&y!=0)||(x!=0&&y==0) ,表示了两种情况:x为0且y不为0,或者x不为0且y为0,也就是:x与y不同时为0。选项中A满足条件。
1.3、以下选项不能作为 C 语言标识符的是: (B)
A、_stu
B、default
C、a1b2c3
D、A_B_C
解析:合法标识符(变量名称)由字母、下划线(_)开始,后面可以跟数字、字母、下划线(_)。选项B中default是C语言的关键字,不能作为标识符。
1.4、对下列递归函数,函数调用 f(3)的返回值是: (A)
int f(int n) { return n==0 ? 1 : f(n-1)+ 2; }
A、7 B、1 C、9 D、5
解析:这里是递归函数的使用
f(3) --> f(2)+2 --> f(1)+2+2 --> f(0)+2+2+2 = 1+2+2+2 = 7
1.5、声明语句为"char a=’%’,*b=&a,**c=&b",下列表达式中错误的是: (B)
A、a==**c B、&a=*&b C、**c=='%' D、b==*c
解析:根据定义b为一级指针,c为二级指针;选项B中&a取到地址,地址常量不能作为左值。
1.6、数组定义为 float a[4][5],引用 a+3 表示: (C)
A、a 数组第 4 列的首地址
B、a 数组第 1 行第 4 列元素的值
C、a 数组第 4 行的首地址
D、a 数组第 1 列第 4 行元素的值
解析:a为第一行首地址,a+3表示第4行首地址。*a为第一个元素的地址,**a为第一个元素。
1.7、若有以下程序段:
int m,y;
for(m=1;m<=100;m++)
{ scanf("%d",&y);
if(y<0) continue;
printf("%3d",m);}
以下正确的描述是: (D)
A、当 y<0 时整个循环结束
B、y>=0 时什么也不输出
C、printf 函数永远也不执行
D、最多允许输出 100 个非负整数
解析:根据代码行if(y<0) continue; 当输入y<0时,直接进入下一轮循环,在y>=0时,输出m。因此,最多允许输出 100 个非负整数。
1.8、计算无符号整型变量 x 是几位数(如 1512 是四位数),其表达式是: (A)
A、(int)log10(x)+1
B、sizeof(x)
C、strlen(x)
D、sizeof(int)
解析:(int)log10(x)+1可以得到数据x的位数,使用对数函数需要添加头文件math.h。
1.9、以“追加”方式打开文本文件 e:\aa.txt,下列语句中正确的是:(B)
A、fp=fopen("e:\\aa.txt","w+"); B、fp=fopen("e:\\aa.txt","a");
C、fp=fopen("e:\aa.txt","r"); D、fp=fopen("e:\\aa.txt","wb");
解析:
文件模式如下:
"r" 以只读方式打开已存在的文本文件。(文件必须已存在,并且不能写)
"w" 以只写方式新建文本文件,若存在同名文件,则刷新已有文件。
"a" 以只写方式打开已存在文本文件,追加数据到末尾。
"r+" 文件应该已经存在,可以读可以写
"w+" 新建文件的同时,可以读可以写
"a+"打开已存在的文件,位置指针在文件末尾,可读可写
1.10、a、b 是结构体变量,语句 a=b 可以执行的前提是: (D)
A、a 与 b 存储空间相同。
B、a 与 b 各数据成员名称相同或类型相同。
C、a 与 b 各数据成员名称相同、类型相同。
D、a 与 b 用同一个类型标识符声明。
解析:相同类型的结构体变量之间可以整体赋值。
- 程序阅读题
2.1 switch, %, /知识点
#include <stdio.h>
int main(){
int m=13,s=1;
while(m){
switch(m%5){
case 2 :
m/=2;
s+=2;
break;
case 3 :
m/=3;
s+=3;
break;
case 5 :
m/=5;
s+=5;
break;
default :
m--;
s--;
};
printf("m=%d, s=%d\n",m,s);
}
return 0;
}
答案:
m=4, s=4
m=3,s=3
m=1,s=6
m=0,s=5
解析:
13%5 --> 3 执行case 3
m=13/3=4,s=1+3=4;输出m=4,s=4
4%5 --> 4 执行default
m=4-1=3, s=4-1=3;输出m=3,s=3
3%5 --> 3 执行case 3
m=3/3=1, s=3+3=6;输出m=1,s=6
1%5-->1 执行default
m=1-1=0,s=6-1=5;输出m=0,s=5
2.2 n%10 n/10取出数据中某一位上的数字
#include <stdio.h>
int main(){
int n=2046,d=0,x=10,a;
while( n!=0) {
a=n%10;
n/=10;
if(a>d) d=a;
if(a<x) x=a;
}
printf("d=%d\nx=%d\n",d,x);
return 0;
}
答案:
d=6
x=0
解析:取出数据中每一位上的数字,d取到这些数字中最大值,x取到这些数字中最小值。
2.3 全局变量默认值0,static变量
#include <stdio.h>
float x;
int func1(){
static int s=11;
s+=2;
x++;
return s;
}
int main(){
int i;
for(i=0; i<2; i++)
printf("%d,",func1( ));
printf("\n%.1f\n",x);
return 0;
}
答案: 13,15,
2.0
解析:x为全局变量,默认值为0。s为静态变量,初始化一次,在程序整个周期内都存在。会在函数的两次调用中保留。
2.4 传递字符串
#include <stdio.h>
int f(char *s) {
int k=0,i;
for(i=1; s[i]!='\0'; i++)
if(s[i-1]>s[i]) k++;
return k;
}
int main(){
char a[]="windows";
int i;
for(i=0; i<4; i++)
if ((i+1)%2)
printf("%5d",f(a+i));
else
printf("%5d\n",f(a+i));
return 0;
}
解析:函数功能:统计在一个字符串中,前一个字符比后一个字符大的次数
main函数中,for循环运行4次,由于函数实参数为 f(a+i),因此,四次传递的字符串分别为windows, indows, ndows, dows,统计得到的次数分别为3,2,2,1。根据if/else,第一个数和第三个的输出执行if部分,第二个数和第四个数的输出执行else部分,即一行输出2个结果。同时输出宽度为5,默认右对齐。
输出:
3 | 2 | ||||||||
2 | 1 |
2.5 结构
#include <stdio.h>
struct student{
char *s;
int age,score;
};
int main(){
int i,k=0;
struct student *p;
struct student a[5]= {{"mike",21,98},{"tom",19,89},{"jack",24,91},
{"alice",20,97},{"mary",18,91}
};
p=a;
for(i=0; i<5; i++) {
if (*a[i].s=='a') printf("%d\n",a[i].age);
if (a[k].score>a[i].score) k=i;
}
printf("%d\n",p->score);
printf("%s\n",a[k].s);
return 0;
}
输出:
20
98
Tom
解析:for循环中第一个if用来判断每位学生的姓名的第一个字符是否为’a’,是的话输出他的年龄,输出20。第二个if语句用来取出成绩最低的学生,用k记录该学生的下标。最后两个输出中,p 指针指向a[0]地址,取出其成绩,输出98。最后输出最低成绩学生的姓名,输出tom。
- 程序填空题
3.1 输入两个整数(必须都大于 0,否则重新输入),输出他们的最小公倍数。
#include <stdio.h>
int main(){
int m,n,x;
while(scanf("%d%d",&m,&n), m<=0 || n<=0);
x=m ;
while(x%n !=0)
x=x+m;
printf("%d\n",x);
return 0;
}
解析:最小公倍数(LCM):两个整数公有的倍数称为他们的公倍数,其中最小的公倍数是他们的最小公倍数。设a,b,公倍数意味着可以被a和b整除,所以可以把其中一个数不断的加倍,每加倍一次,判断是否能被另一个数整除,如果能,找到的第一个就是最小公倍数。
最大公约数(GCD):最大公约数=两整数的乘积÷最小公倍数
最大公约数算法(辗转相除法)
有两整数a和b:
① a%b得余数c
② 若c=0,则b即为两数的最大公约数
③ 若c≠0,则a=b,b=c,再回去执行①
最大公约数:
#include <stdio.h>
int main(){
int a,b,c;
scanf("%d%d",&a,&b);
while(b) {
c=a%b;
a=b;
b=c;
}
printf("%d\n",a);
return 0;
}
3.2 图形输出
输入 n 值,输出高度为 n 行的等腰三角形。例如当 n=4 时的图形如下:(最后一行起始位置无空格)
#include <stdio.h>
void prt(int m,int n,char c){
int i ;
for (i=1; i<=m; i++) putchar(' ');
for (i=1; i<=n; i++) putchar(c) ;
putchar('\n');
}
int main(){
int i,n;
scanf("%d",&n);
for(i=1; i<=n; i++)
prt(n-i, 2*i-1, '*') ;
return 0;
}
解析:函数prt(int m,int n,char c)用来实现一行图形的输出,参数m为空格的变化规律,参数n为输出符号的变化规律。因此调用函数时,prt函数的前两个实参值需要分析一行中空格和符号的变化规律(具体分析方法可以参考以前做过的实验)。
4程序设计题
4.1 编写一个求平均分的函数(函数原型:float ave(float *p, int n)),从键盘输入 60
个学生的成绩,调用函数后,输出高于平均分的成绩。
#include <stdio.h>
float ave(float *p, int n){
float s=0;
int i;
for(i=0; i<n; i++) s=s+*(p+i);
return s/n;
}
int main(){
int i;
float t, a[60];
for( i=0; i<60; i++)
scanf("%f", &a[i]);
t=ave(a, 60);
for( i=0; i<60; i++)
if (*(a+i)>=t)
printf("%f\n",*(a+i));
return 0;
}
解析:功能包括了数组的定义、数据的读入、平均值的求解、数据的输出。熟悉数组元素的操作:a[i]和*(a+i)。
4.2 字符串处理
输入一个字符串(串长小于 60),将字符串中连续的空格符保留一个。如输入:
"It’s a perfect ending!", 输出为:"It’s a perfect ending! "。
#include <stdio.h>
#include <string.h>
int main(){
char b[61];
int i;
gets(b);
for(i=1; b[i]!='\0' ; i++)
if(b[i-1]==' '&&b[i]==' '){
strcpy (b+i-1,b+i);
i--;
}
puts(b) ;
return 0;
}
解析:结合本题,可以熟悉字符串的操作:字符串保存在数组中、字符串的读取、如何循环取到字符串里的每一个字符、后一个字符与前一个字符之间的关系判断、strcpy函数的使用。
4.3 文本文件 e:\score.txt 存放着考试信息,每行包含学号以及 1 门课的实验成绩和考 试成绩(其间用空格间隔)。编程,在原文件的最后一列,为每位学生增加综合成绩(实验成绩×0.4+考试成绩×0.6),综合成绩保留一位小数。
#include <stdio.h>
void main(){
FILE *p1,*p2;
char xh[10];
int sy,ks;
p1=fopen("e:\\score.txt","r");
p2=fopen("e:\\temp.txt","w");
while(fscanf(p1,"%s%d%d",xh,&sy,&ks)!=EOF)
fprintf(p2,"%s %d %d %.1f\n",xh,sy,ks,sy*0.4+ks*0.6);
fclose(p1);fclose(p2);
remove("e:\\score.txt");
rename("e:\\temp.txt","e:\\score.txt");
}
解析:
文件操作相关知识:FILE *定义、fopen函数、fprintf输出、fclose关闭文件、remove删除文件、rename改文件名。
4.4 素数判断
输入 100 个正整数,编写一个判断质数的函数,调用函数求出 100 个数中的质数,并
把这些质数从小到大排序后输出。
#include <stdio.h>
#include <math.h>
int prime(int n){
if(n==1) return 0;
if(n==2) return 1;
for (int i = 2; i <= sqrt(n); ++i){
if (n % i == 0){
return 0;
}
}
return 1;
}
int main(){
int a[100],b[100],p=0,i,j,k,tmp;
for (i=0; i<100; i++){
scanf("%d",a+i);
if (prime(a[i])){
b[p]=a[i];
p++;
}
}
for (i=0; i<p-1; i++){
k=i;
for (j=i+1; j<p; j++)
if (b[j]<b[k]) k=j;
tmp=b[k];
b[k]=b[i];
b[i]=tmp;
}
for (i=0; i<p; i++)
printf("%5d",b[i]);
return 0;
}
解析:结合本题,熟悉读入数据保存到数组中、数组元素的比较、排序算法、素数判断方法