西邮移动应用开发实验室2018年纳新试题
一.基础题
1. 下面程序输出结果为
int main(void) {
int a;
char c=10;
Float f=100.0;
double x;
a=f/=c*=(x=6.5);
printf("%d %d %3.1f%3.1f\n",a,c,f,x);
return 0;
}
解析: 答案是1,65,1.5,6.5,从右向左运算,x = 6.5,c = c * 6.5 =65,f = f/c=1,5, a =f=1.
考点:这道题的主要考点是运算符的运算顺序.
扩展:可以就运算符继续深问下去,比如赋值表达式的值,逻辑表达式的值,比较表达式的值。表达式的运算优先级,逻辑表达式的短路运算,控制浮点数的小数位数。
2.下面这个程序执行后会有什么错误或者效果:
#define MAX 255
int main(void){
unsigned char A[MAX],i;
for (i=0;i<=MAX;i++){
A[i]=i;
}
return 0;
}
解析:
- MAX=255,数组A的下标范围为:0..MAX-1,A[255]越界
- 当i循环到255时,循环内执行: A[255]=255;这句本身没有问题,但是返回for (i=0;i<=MAX;i++)语句时,由于unsigned char的取值范围在(0..255),i++以后i又为0了..无限循环下去.
考点:数组越界,unsigned char的范围,数据溢出
3.找错题:找出下面程序的错误
int main(void){
char string[10], str1[10];
int i;
for(i=0; i<10; i++){
str1[i] = 'a';
}
strcpy( string, str1 );
return 0;
}
解析:str未加\0是一个字符数组,当strcpy(string, str1)调用使得从str1内存起复制到string内存起所复制的字节数具有不确定性
字符串strcpy的函数实现过程式
void strcpy( char *strdest, char *strsrc ){
while( (strdest++ = strsrc++) != ‘\0’ );
}
考点:字符串
扩展: 写一个函数,实现字符串的复制,拼接,统计长度
4.阅读下面程序,说出运行结果,并说明原因
#include <stdio.h>
#define X(x) x;x;x;x;x;x;x;x;x;x;
int main(void) {
int x = 1;
X(X(printf("%d ", x++)));
return 0;
}
解析:从1打印到100 ,对于X(printf(“%d “, x++))中的x是printf(“%d”, x++); 对于X(X(printf(“%d “, x++))) 中的x是X(printf(“%d”, x++)) ,所以当程序编译结束后,程序变为100个printf语句
考点:宏定义
拓展:define相关的问题,比如define F(x) x+x, 求F(4)*F(5) 的值?(29)
5.阅读下面程序,说出运行结果,并说明原因
#include <stdio.h>
int func(int x,int y){
return (x+y);
}
int main(void){
int a = 1, b = 2, c = 3, d = 4, e = 5;
printf("%d\n",func((a+b,b+c,c+a),(d,e)));
return 0;
}
解析:答案为9,括号中的逗号运算符返回值是最后的表达式的值,所以func(c+a,e)=9;
考点:逗号表达式
拓展: 逗号表达式的运算顺序 b =(a =3,a++ ,a+=2),求b的值?(6)
6. 阅读下面程序,说出运行结果,并说明原因
int main(void){
int a = 0X7FFFFFFF;
if(a+1 > a){
printf("ok \n");
}else{
printf("no \n");
}
int b =20;
float c =19.9;
if(b-c == 0.1){
printf("ok \n");
}else{
printf("no \n");
}
int d=-4;
unsigned e=2;
if(d<e)
printf("ok \n");
else
printf("no \n");
return 0;
}
解析 :
- 第一个no,原因是整形的溢出,a =0X7FFFFFFF= 2147483647,a+1=-2147483648(补码)。
- 第二个no,原因是浮点数不能准确的存储,19.9无法精确的用二进制表示,只能近似表示,所以内存中的19.9不是真正的19.9,所以20-19.9!=0.1 .还有int和float进行运算时,自动转换为double类型
- 第三个no, 原因是自动类型转换,当整形和无符号类型一起运算时,整形会自动向上专项为无符号类型,即-4对应的无符号数为4294967292(int的符号位也表示数值),所以4294967292>2为真
考点 : 类型自动转换,浮点数的存储,整形的溢出和存储
扩展·:
- 从补码的角度解释溢出,原码如何转换成补码,为什么要有补码,将-1用8/16进制输出(37777777777/FFFFFFFF).
- 将19.9用二进制表示(定点法,浮点法,IEE754)
- char和unsigned char的比较。
7. 下面的printf语句输出结果为?为什么?
printf("%d,%dn",strlen("12345\678\4009"),sizeof("12345\678\4009"));
解析:
strlen=7,sizeof=10 ,字符串中\ddd–ddd(八进制)为Ascll值(八进制)对应字符,/ 678中8超过8进制所以为/67对应的字符即7,\400即100 000 000,char类型只能存储8位,最高位溢出,所以内存中存储为00 000 000 =0,所以对应的字符为字符串结束标志\0。 但在有些编译器(VC系列)中会报错
所以”12345\678\4009” –> “1234578\09”,在内存中以字符串存储是系统会在结尾补充一个\0,所以”12345\678\4009”在内存中存储为”1234578\09\0”,所以strlen=7,sizeof=10
考点: strlen和sizeof的含义,字符串的存储,转义符。
扩展 : strlen和sizeof的含义,printf如何打印出\n。
8. 不排序将两个有序的数组合并成一个数组。
解析
#include <stdio.h>
int main()
{
int a[5] = {2,3,8,10,13};
int b[5] = {1,6,7,8,9};
int c[10] = {0};
int i = 0,j = 0;
for(int k = 0; k< 10;){
if(i<5 && a[i]<= b[j]) {
c[k++] = a[i++];
}
if(j<5 && b[j]< a[i]) {
c[k++] = b[j++];
}
if(i==5 && j<5) {
c[k++] = b[j++];
}
if(j == 5 && i<5) {
c[k++] = a[i++];
}
}
printf("合并后:");
for(int i = 0 ; i <10 ;i++) {
printf("%d ", c[i]);
}
}
扩展 :存在一个数组,1-n有序,n+1到K有序,将这个数组进行排序,要求空间复杂度为O(1),时间复杂度为O(n),说出你的思路。
9.题目:用变量a给出下面的定义
a) 一个整型数
b) 一个指向整型数的指针
c) 一个指向指针的的指针,它指向的指针是指向一个整型数
d) 一个有10个整型数的数组
e) 一个有10个指针的数组,该指针是指向一个整型数的
f) 一个指向有10个整型数数组的指针
g) 一个指向函数的指针,该函数有一个整型参数并返回一个整型数
h) 一个有10个指针的数组,该指针指向一个函数,该函数有一个整型参数并返回一个整型数
解析
a) int a;
b) int *a;
c) int **a;
d) int a[10];
e) int *a[10];
f) int (*a)[10];
g) int (*a)(int);
h) int (*a[10])(int);
扩展 :有一个指针a,指向h中的数组,如何定义a: int (*(*a)[10])(int)
10.求&i, pi, &pi, &ppi, *ppi, **ppi的关系?
int i;
int * pi;
int **ppi;
i = 50;
pi = &i;
*ppi = π
解析:
- 先说出这题的错误,即ppi是野指针,*ppi会使系统崩溃的原因,ppi未初始化,ppi里面会有垃圾数据,比如说1,*ppi会去访问地址为1的内存,但地址为1的内存可能不允许访问,此时会造成系统的崩溃
- 改正后说出i,pi,ppi的关系, 假设在内存中i的地址为5,pi的地址为9,ppi的地址为11;
ppi的值是–>9。*ppi的值是——>5,即pi的值。**ppi的值是——50,即i的值,也是*pi的值。
考点:* &运算符的含义,指针的理解
扩展: 引入3级指针。谈谈对指针的理解
二.简答题
1.一只青蛙一次可以跳上 1 级台阶,也可以跳上2 级。求该青蛙跳上一个n 级的台阶总共有多少种跳法
解析: 变种斐波那契,即
,青蛙达到n级台阶有两种方法,从n-1层跳一级台阶和n-2层跳二级台阶,所以说青蛙达到n级台阶方法数=n-1方法数+n-2方法数、
拓展:
- 分别用递归,迭代,数组求出青蛙跳上一个n 级的台阶总共有多少种跳法
一只青蛙一次可以跳上1级台阶,也可以跳上2 级……它也可以跳上n 级,此时该青蛙跳上一个n级的台阶总共有多少种跳法? (递归公式)推导过程:
①式
②式
①-② =
2. 说说你知道哪些排序算法,并说说思想
解析:冒泡排序,简单选择,直接插入,希尔排序,堆排序,归并排序,快速排序,桶排序等等的思想