• C 2015年笔试题


    1、写出程序输出结果

    void main()
    {
        char p[10]="abc";
        char q[]="xyz";
        int i,j;
        i=0;
        while(*(p+i)!='') i++;  //此时i=3
        j=0;
        i++;   // i= 4
        while(*(q+j)!='')
        {
            *(p+i)=*(q+j);
            j++;
            i++;
        }
        printf("%s", p);
    }
    

    解答:经过代码运行,p所指向的字符串内容为{a,b,c,,x,y,z,},所以最后运行的结果为输出abc。

    或者

    void main()
    {
        char p[10]="abc";
        char q[]="xyz";
        int i,j;
        i=0;
        while(*(p+i)!='') i++;  //此时i=3
        j=0;
        i++;   // i= 4
        while(*(q+j)!='')
        {
            *(p+i)=*(q+j);
            j++;
        }
        printf("%s", p);
    }
    

    解答:经过代码运行,p所指向的字符串内容为{a,b,c,,z,},所以最后运行的结果为输出abc。 


    2、 写出该代码的功能,并给出改进之处

    void main()
    {
    	int n, x, j, i = 1;
    	float sum = 1, k = -1;
    	printf("Input n and x:
    ");
    	scanf("%d %d", &n, &x);
    	while (i <= n) {
    		k = -1;
    		for (j = 1; j <= i; j++) {
    			k = -1*k*x;
    		}
    		for (j = 1; j <= i; j++) {
    			k =  k/ j;
    		}
    		sum += k;
    		i++;
    	}
    	printf("%f
    ", sum);
    }

    解答,该代码的功能为求解1+x+x^2/2! +x^3/3! + ... + x^n/n!

    该代码可以通过动态规划进行改进,使得时间复杂度下降至O(n),代码如下:

    void main()
    {
    		int n,x,i=1;
    		float sum = 1,k = -1;
    		printf("Input n and x:
    ");
    		scanf("%d %d", &n, &x);
    		while (i <= n) {
    			k = -1 * k*x / i;
    			sum += k;
    			i++;
    		}
    		printf("%f", sum);
    }

    3、代码for(int i=1;i<n;i++) S;是什么结构?该代码如何使用显示结构表示?

    解答:该代码是循环判断选择结构。该代码的显示结构如下:

    int i = 1;
    FOR: if (i<n) goto S0;
            goto S1;
    S0: S;
            i = i+1;
            goto FOR;
    S1: ...     
    

    4、根据下面的代码,填写表格。内存按2字节编址,整数占2字节,字符占1字节,指针占4字节。每个区域的相对地址都从0开始

    int num=2;//2存储在常量区,num存储在全局区,两个都是整形占2字节。
    void main()
    {
    	char str1[10]={"UESTC"};//"UESTC"和10存储在常量区,各占6和2个字节
    	char *str2="CHENGDU";//"CHENGDU"存储在常量区,占8各字节,注意’’。
    	char p;//p存储在main区,占1字节。str1和str2存储在main区,str1占10字节,str2占4字节
    }
    void func(int m)//m存储在func区,占2字节
    {
    	int n=10;//n存储在func区,10存储在常量区,各占2字节。
    }
    

    根据出现的顺序,就可以知道相对地址为多少了。每占用两个字节,内存向后偏移一位。


    填空题

    5.1 给定一个数,给出质数分解结果,例如90=2*3*3*5

    int main()
    {
        int n, i=2;
        printf("
    Input:");
        scanf("%d", &n);
        printf("=");
        i = 2;
        while (n > 1)
        {
            if (n%i == 0)
            {
                printf("%d", i);
                n = n / i;
                if (n > 1) printf("*");
            }
            else i++;  // 如果不能整除时,说明不是其素数
        }
        return 0;
    }

     5.2 若100个人围成圈,从第一个人开始,1~3报数,数到3人退出,剩下来的人编号是几

    代码:

    //求最后剩下的编号
    int main(
    {
        int n = 100, num[100];
        int m  /*m为已退出人数*/,f = 3, i, *p;
    
        p = num;
        for (i = 0; i < n; i++)  //将1~n存入num
        {
            *(p + i) = i + 1;
        }
        i = 0;
        m = 0;
        int k = 0;  // k是工作指针
        printf("杀死顺序为:
    ");
        while (m < n - 1)
        {
            if (*(p + i) != 0) //碰到元素为0的跳过,说明已经杀死,不再参与计数
            {
                k++;
            }
            if (k == f)  //正好到第f个时,将第f个元素置0
            {
                printf("%d	",*(p + i)); //输出满足条件的元素
                *(p + i) = 0;
                k = 0; //重新开始计数
                m++;
            }
            i++;
            if (i == n)  //当i = 6时,将i置0,循环操作
                i = 0;
        }
        while (*p == 0)
        {
            p++;
        }
        printf("
    最后一个是:%d",*p);
        return 0;
    }

    扩展:约瑟夫环问题:【 N个人围成一圈,从第一个开始报数,第M个将被杀掉,最后剩下一个,其余人都将被杀掉。例如N=6,M=5,被杀掉的顺序是:5,4,6,2,3,1】

    代码:

    //求最后剩下的号
    int main()
    {
        int n, num[100];
        int m/*注:m为已退出人数*/,f, i, *p;
    
        printf("n= ");
        scanf("%d", &n); //n是总人数
        printf("f= ");
        scanf("%d", &f); //f是第f个杀掉的人
    
        p = num;
        for (i = 0; i < n; i++)  //将1~n存入num
        {
            *(p + i) = i + 1;
        }
        i = 0;
        m = 0;
        int k = 0;  // k是工作指针
        printf("杀死顺序为:
    ");
        while (m < n - 1)
        {
            if (*(p + i) != 0) //碰到元素为0的跳过,说明已经杀死,不再参与计数
            {
                k++;
            }
            if (k == f)  //正好到第f个时,将第f个元素置0
            {
                printf("%d	",*(p + i)); //输出满足条件的元素
                *(p + i) = 0;
                k = 0; //重新开始计数
                m++;
            }
            i++;
            if (i == n)  //当i = 6时,将i置0,循环操作
                i = 0;
        }
        while (*p == 0)
        {
            p++;
        }
        printf("
    最后一个是:%d",*p);
        return 0;
    }

    5.3 带头结点链表逆序  【同2017年24题】

    方法1:取下头结点,然后按照头插法即可实现链表逆序

    方法2:后继指针指向前驱结点


    6 编程题

    6.1 将给定字符串例如”aaa111bbb222#”中的数字全部提取出来,放到给定的数组中。字符串以#结尾。

    函数形式为void int_find(int arr[], char *pc);溢出以-1作为标志

    分析:该题目有一处表述不清,即溢出以-1做为标志。已知C语言无法求出这种情况下的数组长度,所以无法判断数组溢出。综上,该溢出标志可能为数组的最后一个元素,即所有数字查找完毕时以-1结尾

    代码:

    #include <stdlib.h>
    
    void int_find(char *pc)
    {
        int arr[50] = {0};
        char *p = pc;  // p 是工作指针
        int i = 0;
        while (*p != '')
        {
            if (*p >'0'&&*p <'9')
            {
                arr[i]=atoi(p);
                /*
                int atoi(const char *str): 把参数str所指向的字符串转换为一个整数(类型为 int 型),该函数返回转换后的长整数,如果没有执行有效的转换,则返回零,标准库:<stdlib.h>
                */
                i++;
                //遇到数字后继续进行直到遇到非数字元素
                while (*p >'0'&&*p <'9')
                {
                    p++;
                }
            }
            //如果不是数字,则跳过
            else p++;
        }
        arr[i] = -1; //最后以-1结尾
        //输出arr的值
        int *q = arr;
        for(i = 0;*(q + i) != -1;i++)
        {
            printf("%d	",arr[i]);
        }
    }
    int main()
    {
        char ch[] ="aaa111bbb222dsadas2ew2ewq213rf32342r53433#";
        char *c = ch;
        int_find(c);
        return 0;
    }
      

    6.2 随机输入最多100个整数和浮点数,将整数按从大到小排列,浮点数按从小到大排列(浮点数排序可省略),并输出。

    如:输入10 12.3 12 5 52.1 3.65 88.6 1.0 输出:12 10 5 1.0 3.65 12.3 52.1 88.6

     分析:这道题目在不借助库函数编程非常困难,也是当年的一道难题。若忽略1.0这样的数字,可以将输入全部视为浮点数,然后判断浮点数可以使用if(int(num)==num)这种方法判断。要实现完美解答,并以最少的时间完成本题,需要借助strstr、atoi、atof三个函数

    代码:

    #include <stdio.h>
    #include <stdlib.h>
    //整数降序排序
    void sort_int(int num[], int n)
    {
        int i, j;
        for (i = 0; i<n - 1; i++)
        {
            for (j = i + 1; j <= n - 1; j++)
            {
                if (num[j]>num[i])
                {
                    int temp = num[i];
                    num[i] = num[j];
                    num[j] = temp;
                }
            }
        }
        //输出整型
        for(i = 0;i < n;i++)
        {
            printf("%d	",num[i]);
        }
    }
    //浮点数升序排序
    void sort_float(float num[],int n)
    {
        int i,j;
        //冒泡排序
        for(i = 0;i < n-1;i++)
        {
            for(j = i+1;j <= n-1;j++)
            {
                if (num[j]<num[i])
                {
                    int temp = num[i];
                    num[i] = num[j];
                    num[j] = temp;
                }
            }
        }
        //输出浮点数
        for(i = 0;i < n;i++)
        {
            printf("%f	",num[i]);
        }
    }
    int main()
    {
        int intarr[100];
        float fltarr[100];
        int m=0,n,i=0,j=0;
        char buff[100];
    
        printf("input n:
    "); //n是几个数
        scanf("%d", &n);
        while (m < n)
        {
            scanf("%s", buff);
            //如果是浮点型数
            if (strstr(buff, "."))
                /*
            strstr(str1,str2)函数用于判断字符串str2是否是str1的子串。如果是,则该函数返回 str1字符串从 str2第一次出现的位置开始到 str1结尾的字符串;否则,返回NULL
                */
                fltarr[j++]=atof(buff); //浮点数存入fltarr数组
                /*
                float atof(const char *str)把参数str所指向的字符串转换为一个浮点数(类型为 float型,函数返回转换后的单精度浮点数,如果没有执行有效的转换,则返回零(0.0),标准库:<stdlib.h>
                */
            else
                //若为整型
                intarr[i++] = atoi(buff);//整型存入intarr数组中
            m++;
        }
        printf("排序后:
    ");
        sort_int(intarr, i);
        sort_float(fltarr,j);
        return 0;
    }

    6.3 编写完整的程序,构造整数集合,并实现对该集合操作的若干功能:查找集合内的某元素;集合中加入一个新元素;删除集合中某一元素;求两个集合的并集;求两个集合的交集;并给出main函数调用的例子

    分析:该代码等价于构造一个链表,判断某元素是否在链表内,当加入一个元素时,判断该元素是否在链表内,如果不在则插入链表;当删除一个元素时,找到这个元素并删除该节点;输出两个链表的交集,输出两个链表的并集。该题目代码量非常大

    代码:

    #include <stdio.h>
    #include <stdlib.h>
    
    typedef struct node
    {
        int data;
        struct node *next;
    };
    
    //判断某元素是否在集合内
    int isexist(struct node *L, int num)
    {
        struct node *p = L->next;
        while (p != NULL)
        {
            if (p->data == num)return 1;
            p = p->next;
        }
        return 0;
    }
    
    //增加一个元素
    void add(struct node *L, int num)
    {
        //头插法,逆序
        if (isexist(L,num) == 0)
        {
            struct node *p = (struct node *)malloc(sizeof(struct node));
            p->data = num;
            p->next = L->next;
            L->next = p;
        }
    }
    
    //删除集合中某一元素
    void del(struct node *a, int num)
    {
        if (isexist(a,num) == 0)
        {
            printf("没有此元素,删除失败!
    ");
        }
    
        struct node *p = a->next, *pre = a;
        while (p != NULL)
        {
            if (p->data == num)
            {
                pre->next = p->next;
                free(p);
                break;
            }
            pre = p;
            p = p->next;
        }
    }
    //输出链表
    void inputnode(struct node *a)
    {
        struct node *l = a ->next;
        while(l != NULL)
        {
            printf("%d	",l ->data);
            l = l ->next;
        }
    }
    
    //输出两个集合并集
    void intersection(struct node *a, struct node *b)
    {
        struct node *p = a->next;
        int flag = 0;
        while (p != NULL)
        {
            printf("%d ", p->data);
            p = p->next;
        }
        struct node *q = b->next;
        while (q != NULL)
        {
            p = a->next;
            flag = 0;
            while (p != NULL)
            {
                if (q->data == p->data)
                {
                    flag = 1;
                    break;
                }
                p = p->next;
            }
            if (!flag)
                printf("%d ", q->data);
            q = q->next;
        }
    }
    
    //输出两个集合交集
    void Union(struct node *a, struct node *b)
    {
        struct node *p = a->next, *q = b->next;
        while (p != NULL)
        {
            q = b->next;
            while (q != NULL)
            {
                if (p->data == q->data)
                {
                    printf("%d ", q->data);
                    break;
                }
                q = q->next;
            }
            p = p->next;
        }
    }
    
    void main()
    {
        struct node *L = (struct node *)malloc(sizeof(struct node)); //L的头结点
        struct node *S = (struct node *)malloc(sizeof(struct node)); //S的头结点
        L->next = NULL;
        S->next = NULL;
    
        printf("输入L:
    ");
        int temp;
        scanf("%d", &temp);
        while (temp != -1)
        {
            add(L, temp);
            scanf("%d", &temp);
        }
    
        printf("输入S:
    ");
        scanf("%d", &temp);
        while (temp != -1)
        {
            add(S, temp);
            scanf("%d", &temp);
        }
    
        printf("输出L:");
        inputnode(L);
        printf("
    输出S:");
        inputnode(S);
    
        printf("
    删除L中的元素2:
    ");
        del(L,2);
        inputnode(L);
    
        printf("
    并集:");
        intersection(L, S);
        printf("
    交集:");
        Union(L, S);
    }

  • 相关阅读:
    python简单应用!用爬虫来采集天猫所有优惠券信息,写入本地文件
    python有哪些好玩的应用实现,用python爬虫做一个二维码生成器
    Python学习,给自己的代码做个合集,定制自己的桌面软件!
    用python抓取“3d”彩票数据,怎么分析你说了算!
    怎么让你的代码更Pythonic?光有技巧可不行,你还需要看这些
    Python学习汇总,做数据采集的一些小技巧,干货满满
    Python学习,还在用正则或者bs4做爬虫吗?来试试css选择器吧
    C# Windows API判断当前窗口是否与其他窗口有重叠(USER32.dll、dwmapi.dll)
    asp.net mvc 设置文本框的宽高
    C++ 判断当前系统x64 or x86
  • 原文地址:https://www.cnblogs.com/pam-sh/p/12549561.html
Copyright © 2020-2023  润新知