zoukankan      html  css  js  c++  java
  • C 2016笔试题

    1、下面程序的输出结果是(    

    1.1

    int x = 3;
    
    do
    {
        printf(“%d
    ”,x -= 2);
    }while(!(-- x));
    

    分析:x初始值为3,第一次循环中运行printf函数,参数x -= 2的值为1,输出1,此时x = 1,进行判断!(-- x),x先自减1,为0,取非为1(真),进行第二次循环,x先减2,输出-2,此时x=-2,判断!(-- x),x先自减1为-3,取非为0(假),结束循环

    输出结果:

    1

    -2


    1.2

    void main()
    {
    
        int a[]= {1,7,12,15};
    
        int *p1=a,*p2 = p1++;
    
        *p1 += *p2++;
    
        printf(“%d %d”,*p1,*p2);
    }
    

    分析:首先定义指针p1指向数组a首地址,然后定义指针p2,也指向数组首地址,然后p1自加,也就指向了数组第二个元素。*p1 += *p2++;语句先将p2指向的第一个元素的值加到p1指向的第二个元素的值上,也就是第二个元素值为8,然后p2自加,指向第二个元素(*p2++,*与++优先级相同,从右自左结合,先与++结合,表示语句执行完后p2指向下一个元素,然后与*结合,表示p2现在所指向的第一个元素的值)

    输出结果:8 8


    1.3

    int func(int *p){
    
         return (*p-- = 3) - 1;
    
    }
    void main(){
    
         int arr[]={10,7,5};
    
         int *p = arr + 1;
    
         printf(“%d”,func(p) + *p);
    
    }
    

    分析:p指针首先指向数组arr的第二个元素,首先调用func函数,将实参指针p指向的地址传递给函数形参p,形参执行*p-- = 3,使得p指向的数组第二个元素值为3,然后形参p自减指向第一个元素,但是实参p不变,还是指向第二个元素,此时func返回的值为3 - 1 = 2,然后2 + *p,这里实参p指向第二个元素,值为3,

    输出结果:5


    1.4

    void main()
    {
        int i = 1;
        switch(i)
        {
            printf("hello ");
        case 1:
            printf("Hi ");
        case 2:
            printf("Bye ");
        }
    }
    

    分析:i的值为1,所以直接从case 1后面的语句开始执行,输出Hi ,由于这里没有break;不会跳出switch语句,所以继续往下执行,输出Bye

    输出结果:Hi Bye


     1.5

    void main(){
    int a,b = 0;
    static int c[10]={9,2,3,4,5,6,7,8,0,1};
    for(a = 0;a < 10;a ++)
        b += c[a];
    printf("%d",b);
    }
    

    分析:程序遍历数组c,将c的每个元素的值累加到b上

    输出结果:45


    1.6

    void main()
    {
        char str[100];
        FILE *p1,*p2;
        gets(str);
        p1 = fopen(str,”w”);
        p2 = fopen(str,”w”);
        fputc(‘A’,p1);
        fputc(‘B’,p2);
        fclose(p1);
        fclose(p2);
    }
    

    分析:文件指针p1,p2分别打开文件,先使用p1往文件输出A,p2此时指向文件头,所以用p2往文件输出B,覆盖了原本的A

    文件中的内容:B


    1.7

    long fib(int n)
    {
        if(n > 2) return (fib(n - 1) + fib(n - 2));
        else return 1;
    }
    
    void main()
    {
        printf(“%d
    ”,fib(3));
    }
    

    分析:调用fib(3),由于3>2,所以返回fib(2)+fib(1)fib(2)fib(1)都返回1,所以最后结果为:2


    1.8

    void main()
    {
        char c = 48;
        int i,mark = 01;
        for(i = 0;i < 5;i ++)
        {
            printf(“%c”,c|mark);
            mark = mark << 1;
         }
    }

    分析:C=48转换成二进制数就是110000,mark初始为八进制1,循环执行5次,每次先输出c|mark(按位或运算)对应的ASCII字符,然后mark左移1位,即乘以2。第一次循环c为110000,mark为1,c|mark为110001,即十进制49,对应ASCII字符‘1’,然后mark左移为2;第二次循环c|mark为110010,即十进制50,对应ASCII字符‘2’,然后mark左移为4;次循环c|mark为110100,即十进制52,对应ASCII字符‘4然后mark左移为8次循环c|mark为111000,即十进制56,对应ASCII字符‘8’,然后mark左移为16;次循环c|mark为110000,即十进制48,对应ASCII字符‘0’,然后mark左移为32。

      以数字0开头,由0~7组成的数是八进制


    2 改错  下面程序的功能是将字符串src逆序输出

    请将下面程序的错误改正,缺少的代码补全

    #include<stdio.h>
    #include<stdlib.h>
    #include<string.h>
    void main()
    {
        char *src = “hello,world”;
        char *dest,*d,*p;
        int len,i;
        len = strlen(src);
        dest = (char *)malloc(len);  //错误1
        p = src[len];   //错误2
        d = dest;
        while(len-- != 0)
            d ++ = p --;   //错误3
                  //缺少字符串收尾语句*d=’’;
        printf(“%s”,dest);
    } 

    dest = (char *)malloc(len);改为dest = (char *)malloc(len + 1);因为要多出一个存储字符串结束符(或者dest = (char *)malloc(sizeof(char)*(len + 1));这里sizeof(char)的值为1,所以写成len+1也行)

    p = src[len];改为p = &src[len - 1];因为src[len - 1]才是最后一个字符,数组下标从0开始,并且要取地址&赋给指针p

    d ++ = p --;改为*(d ++) = *(p --);这里应将指针p指向的字符赋值给指针p所指向的内存,所以要加**(d ++)d先与++结合(这里不加括号也行,*p++*++优先级相同,从右往左结合,先与++结合再与*结合,不过习惯性加上括号可以增加代码可读性,也不容易出错),表示语句结束后自加指向下一个字符,再与*结合,表示d所指向的字符。*(d ++) = *(p --);语句作用是先把*p赋值给*d,然后p自减,d自加,即{*d = *p;d ++;p --;}复合语句的效果

    ④在printf(“%s”,dest);语句前要增加一行语句*d = ‘’;设置字符串结束标志

    改正后:

    #include<stdio.h>
    #include<stdlib.h>
    #include<string.h>
    void main()
    {
        char *src = "hello,world";
        char *dest,*d,*p;
        int len,i;
        len = strlen(src);
        dest = (char *)malloc(len + 1);
        p = &src[len - 1];
        d = dest;
        while(len-- != 0)
            *(d ++) = *(p --);
        *d = '';
        printf("%s",dest);
    }
    

    3 分析题

    3.1从程序效率角度分析下面两段代码

    if(B1)					if(B1)
    S1						S1
    if(B2)					else if(B2)
    S2						S2
    …						…
    if(Bn)					else if(Bn)
    Sn						Sn
    

    分析:本题要求从程序效率角度考虑,应该默认B1~Bn中只有一个事件为真,其它为假。左边程序无论何种情况都要进行nif语句判断,而右边语句执行if语句判断的次数与B1~Bn的情况有关,若B1B2、…、B(m-1)为假,Bm为真,那么只会执行mif语句判断,之后的if语句不再执行,从而提高了程序效率。


    3.2 若有定义

    #define SQUARE(x)  ((x)*(x));

    int a = 5,b;

    则执行

    b = SQUARE(a ++);

    后,a,b各为何值?

    分析:b = SQUARE(a ++);语句可将宏定义替换掉,即b = ((a ++)*(a ++));,由于是a++,先以a的原值执行完该语句,a再自加,也就是{b = a*a;a ++;a ++}复合语句的效果,所以a = 7,b = 25


    3.3 下面程序的运行结果是什么

    void main()
    {
    	void fun(int a[],int n);
    	int a[] = {1,2,4,8};
    	int i;
    	fun(a,4);
    	for(i = 0;i < 4;i ++)
    	  printf(“%d,”,a[i]);
    }
    
    void fun(int a[],int n)
    {
    	int i,*p;
    	for(i = 0;i < n;i ++)
    	  p = &a[i];
    	*p = 0;
    }
    

    分析:fun函数中for循环每次将a[i]的地址赋给指针p,注意这里没有花括号,循环只执行p = &a[i];这句,循环结束后,p指向数组的最后一个元素,然后执行*p = 0;将最后一个元素改为0,所以运行结果是1,2,4,0


    3.4 下面这段程序的功能是什么?

    #include<stdio.h>
    #include<string.h>
    char str[100];
    char string[100];
    
    void main()
    {
        void fun(int m);
        int m;
        gets(str);
        scanf(“%d”,&m);
        fun(m);
        printf(“%s
    ”,string);
    }
    void fun(int m)
    {
        int len,i;
        len = strlen(str);
        if(m > len)
        {
            string[0] = ‘’;
            return ;
        }
        for(i = 0; str[m - 1] != ‘’; i ++,m ++)
            string[i] = str[m - 1];
        string[i] = ‘’;
    }
    

    分析:str字符串第m个字符开始截取后面的子串,并复制给string字符串,输出string字符串。


    3.5 请简述C语言的隐式类型转换发生的四种情况,并说明每种情况如何转换。【同2018年】

    混合运算: 级别低的类型向级别⾼的类型值转换。 1分
    将表达式的值赋给变量: 表达式的值向变量类型的值转换。 1分
    实参向函数形参传值: 实参的值向形参的类型进⾏转换。 2分
    函数返回值: 返回值向函数返回类型的值进⾏转换。 2分


    3.6 C语言执行效率方便,简述下C语言采取了哪些措施提高执行效率。(18分)

    分析:

    ①使⽤指针:有些程序⽤其他语⾔也可以实现,但C能够更有效地实现;有些程序⽆法⽤其它语⾔实现,如直接访问硬件,但C却可以。正因为指针可以拥有类似于汇编的寻址⽅式,所以可以使程序更⾼效。

    ②使⽤宏函数:宏函数仅仅作为预先写好的代码嵌⼊到当前程序,不会产⽣函数调⽤,所以仅仅是占⽤了空间,⽽使程序可以⾼效运⾏。在频繁调⽤同⼀个宏函数的时候,该现象尤其突出。函数和宏函数的区别就在于,宏函数占⽤了⼤量的空间,⽽函数占⽤了时间。

    宏函数的例⼦:

    ③.使⽤位操作:位操作可以减少除法和取模的运算。在计算机程序中数据的位是可以操作的最⼩数据单位,理论上可以⽤"位运算"来完成所有的运算和操作。灵活的位操作可以有效地提⾼程序运⾏的效率。

    ④.循环嵌套中将较长循环设为内置循环,较短循环设为外置循环,以减少cpu跨切循环层的次数,提⾼程序的运⾏效率。(操作系统页⾯置换相关,减少页⾯置换次数)

    ⑤.将汇编指令嵌⼊到 C 语⾔程序中,汇编语⾔是效率最⾼的计算机语⾔,因此为了获得程序的⾼效率,可以在C语⾔程序中嵌⼊汇编,从⽽充分利⽤⾼级语⾔和汇编语⾔各⾃的特点。

    ⑥.在C语⾔程序中可以调⽤系统API,接近底层,从⽽提⾼程序的运⾏效率。

    ⑦.⼀般情况下,C语⾔源程序中的每⼀⾏代码.都要参加编译。但有时候出于对程序代码优化的考虑.希望只对其中⼀部分内容进⾏编译.此时就需要在程序中加上条件,让编译器只对满⾜条件的代码进⾏编译,将不满

    ⾜条件的代码舍弃,这就是条件编译


    4 填空

    4.1 求2/1+3/2+5/3+8/5+…的前20项之和

    #include<stdio.h>
    void main()
    {
    	float  m,k,s = 0,i = 1,j = 2;
    	for(k = 1;k <  21  ;k ++)
    	{
    		s +=  j/i  ;
    		m =  i + j  ; i =  j  ; j =  m  ;
    }
    printf(“%f
    ”,s);
    }

    4.2 一个包含9个数的非降序数列存储在数组中,现在插入一个数到合适位置,使序列保持非降序(插入的数大于第一个数,小于第九个数)

    #include<stdio.h>
    #define N  10 
    void main()
    {
    	int a[N] = {1,2,4,8,16,32,64,128,256};
    	int m,i,d;
    	scanf(“%d”,&d);
    	for(i = 0;i <  9  ;i ++)	//这里填N-1也行  找到插入位置
    		if(  d < a[i]  ){  m = i  ;  break  ;}
    	for(i =  8  ;i >= m;i --)	//这里填N-2也行  插入位置后面的元素依次后移
    		 a[i + 1]  = a[i];
    	a[m] = d;  //插入
    }
    

    4.3 建立一个结构体包含学生信息(学号,成绩),使用结构体数组结构体指针,输入200个学生信息,以成绩从低到高排序,输出最高成绩的学生的学号和成绩(最高成绩可能有多名学生)

    #include<stdio.h>
    
    typedef struct Student{
    	int num;
    	int score;
    }Stu;
    
    int main()
    {
        /*选择排序:
    假设排序表为L【1....n】,第一趟排序即从L【i...n】中选择关键字最小的元素与L(i)交换,每一趟排序可以确定一个元素的最终位置,这样经过n-1趟排序就可以使得整个排序表有序
        */
    	Stu stu[200],temp,*p,*q,*k;  //stu为结构体数组,*p,*q,*k为结构体指针
    	int i,j,max = 0;  //max记录分数最大值
    	p = stu;
    	//输出数据
    	for(i = 0;i < 200;i ++,p ++)
    		scanf("%d%d",&p->num,&p->score);
        //选择排序,以成绩从低到高排序
    	p = stu;
    	for(i = 0;i < 199;i ++,p ++)	//由于题目说明要用结构体指针,所以我这使用指针操作
    	{
    		k = p;  //记录最小元素位置
    		q = p + 1;
    		for(j = i + 1;j < 200;j ++,q ++)	
    			if(k->score > q->score)
    				k = q;   //更新最小元素的位置
            //与第i个位置交换
    		temp = *p;
    		*p = *k;
    		*k = temp;
    	}
    	//记录最高成绩
    	p = stu;
    	for(i = 0;i < 200;i ++,p ++)
    		if(p->score > max)
    			max = p->score;
        //输出打印最高分数和对应的学号
    	p = stu;
    	for(i = 0;i < 200;i ++,p ++)
    		if(p->score == max)
    			printf("学号:%5d分数:%5d
    ",p->num,p->score);
    
    	return 0;
    }

    4.4 输入20个数(整型或浮点型),逆序构建一个单向链表

    #include<stdio.h>
    #include<stdlib.h>
    
    typedef struct Node{
    	float num;
    	struct Node *next;
    }node;
    
    int main()
    {
    	node *s,*head;
    	int i;
    	float t;
    	head = (node *)malloc(sizeof(node));   //head为头结点
    head->num = 0; head->next = NULL; for(i = 0;i < 20;i ++) { scanf("%f",&t); s = (node *)malloc(sizeof(node)); s->num = t; s->next = head->next; //头插法 head->next = s; }
              s = head->next; //s为工作指针 while(s) { printf("%f ",s->num); s = s->next; } return 0; }
  • 相关阅读:
    .Net Core 5.x Api开发笔记 -- 消息队列RabbitMQ实现事件总线EventBus(二)
    .Net Core 5.x Api开发笔记 -- 消息队列RabbitMQ实现事件总线EventBus(一)
    SQL 入门教程:创建视图
    微信小程序-企业微信PC端,对接echarts图无法显示
    SQL查看表结构以及表说明
    Skoruba.IdentityServer4.STS.Identity 踩坑
    Docker部署文档
    eCharts图形在IE11中不能渲染
    Cookie中文乱码问题
    Blazor Webassembly多标签页实现
  • 原文地址:https://www.cnblogs.com/pam-sh/p/12520591.html
Copyright © 2011-2022 走看看