西邮移动应用开发实验室2018年纳新试题

西邮移动应用开发实验室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;
}

解析

  1. MAX=255,数组A的下标范围为:0..MAX-1,A[255]越界
  2. 当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;
}

解析 :

  1. 第一个no,原因是整形的溢出,a =0X7FFFFFFF= 2147483647,a+1=-2147483648(补码)。
  2. 第二个no,原因是浮点数不能准确的存储,19.9无法精确的用二进制表示,只能近似表示,所以内存中的19.9不是真正的19.9,所以20-19.9!=0.1 .还有int和float进行运算时,自动转换为double类型
  3. 第三个no, 原因是自动类型转换,当整形和无符号类型一起运算时,整形会自动向上专项为无符号类型,即-4对应的无符号数为4294967292(int的符号位也表示数值),所以4294967292>2为真

考点 : 类型自动转换,浮点数的存储,整形的溢出和存储
扩展·:

  1. 从补码的角度解释溢出,原码如何转换成补码,为什么要有补码,将-1用8/16进制输出(37777777777/FFFFFFFF).
  2. 将19.9用二进制表示(定点法,浮点法,IEE754)
  3. 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 = &pi;

解析:

  1. 先说出这题的错误,即ppi是野指针,*ppi会使系统崩溃的原因,ppi未初始化,ppi里面会有垃圾数据,比如说1,*ppi会去访问地址为1的内存,但地址为1的内存可能不允许访问,此时会造成系统的崩溃
  2. 改正后说出i,pi,ppi的关系, 假设在内存中i的地址为5,pi的地址为9,ppi的地址为11;
    ppi的值是–>9。*ppi的值是——>5,即pi的值。**ppi的值是——50,即i的值,也是*pi的值。

考点:* &运算符的含义,指针的理解
扩展: 引入3级指针。谈谈对指针的理解

二.简答题

1.一只青蛙一次可以跳上 1 级台阶,也可以跳上2 级。求该青蛙跳上一个n 级的台阶总共有多少种跳法

解析: 变种斐波那契,即 f n = f n 1 + f n 2 ,青蛙达到n级台阶有两种方法,从n-1层跳一级台阶和n-2层跳二级台阶,所以说青蛙达到n级台阶方法数=n-1方法数+n-2方法数、
拓展:

  1. 分别用递归,迭代,数组求出青蛙跳上一个n 级的台阶总共有多少种跳法
  2. 一只青蛙一次可以跳上1级台阶,也可以跳上2 级……它也可以跳上n 级,此时该青蛙跳上一个n级的台阶总共有多少种跳法? f n = 2 f n 1 (递归公式)推导过程:

    f n = f n 1 + f n 2 + f n 3 + . . . + f 0 ①式
    f n 1 = f n 2 + f n 3 + f n 4 + . . . + f 0 ②式
    ①-② = f n = 2 f n 1

2. 说说你知道哪些排序算法,并说说思想

解析:冒泡排序,简单选择,直接插入,希尔排序,堆排序,归并排序,快速排序,桶排序等等的思想

3. 你知道链表吗?链表和数组各有什么优点缺点?试说明链表的创建过程

链表相关可以看我之前的博客

4. 有如下所示的数塔,要求从顶层走到底层,若每一步只能走到相邻的结点,则经过的结点的数字之和最大是多少?

具体看崔一鸣学长的博客

猜你喜欢

转载自blog.csdn.net/qq_38499859/article/details/79822435
今日推荐