C 2015年笔试题

1、写出程序输出结果#

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
void main()
{
    char p[10]="abc";
    char q[]="xyz";
    int i,j;
    i=0;
    while(*(p+i)!='\0') i++;  //此时i=3
    j=0;
    i++;   // i= 4
    while(*(q+j)!='\0')
    {
        *(p+i)=*(q+j);
        j++;
        i++;
    }
    printf("%s", p);
}

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

或者

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
void main()
{
    char p[10]="abc";
    char q[]="xyz";
    int i,j;
    i=0;
    while(*(p+i)!='\0') i++;  //此时i=3
    j=0;
    i++;   // i= 4
    while(*(q+j)!='\0')
    {
        *(p+i)=*(q+j);
        j++;
    }
    printf("%s", p);
}

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


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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
void main()
{
    int n, x, j, i = 1;
    float sum = 1, k = -1;
    printf("Input n and x:\n");
    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\n", sum);
}

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

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

1
2
3
4
5
6
7
8
9
10
11
12
13
void main()
{
        int n,x,i=1;
        float sum = 1,k = -1;
        printf("Input n and x:\n");
        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;是什么结构?该代码如何使用显示结构表示?

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

1
2
3
4
5
6
7
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开始#

1
2
3
4
5
6
7
8
9
10
11
int num=2;//2存储在常量区,num存储在全局区,两个都是整形占2字节。
void main()
{
    char str1[10]={"UESTC"};//"UESTC"和10存储在常量区,各占6和2个字节
    char *str2="CHENGDU";//"CHENGDU"存储在常量区,占8各字节,注意’\0’。
    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#

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
int main()
{
    int n, i=2;
    printf("\nInput:");
    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人退出,剩下来的人编号是几#

代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
//求最后剩下的编号
int main(
{
    int n = 100, num[100];
    int /*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("杀死顺序为:\n");
    while (m < n - 1)
    {
        if (*(p + i) != 0) //碰到元素为0的跳过,说明已经杀死,不再参与计数
        {
            k++;
        }
        if (k == f)  //正好到第f个时,将第f个元素置0
        {
            printf("%d\t",*(p + i)); //输出满足条件的元素
            *(p + i) = 0;
            k = 0; //重新开始计数
            m++;
        }
        i++;
        if (i == n)  //当i = 6时,将i置0,循环操作
            i = 0;
    }
    while (*p == 0)
    {
        p++;
    }
    printf("\n最后一个是:%d",*p);
    return 0;
}

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

代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
//求最后剩下的号
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("杀死顺序为:\n");
    while (m < n - 1)
    {
        if (*(p + i) != 0) //碰到元素为0的跳过,说明已经杀死,不再参与计数
        {
            k++;
        }
        if (k == f)  //正好到第f个时,将第f个元素置0
        {
            printf("%d\t",*(p + i)); //输出满足条件的元素
            *(p + i) = 0;
            k = 0; //重新开始计数
            m++;
        }
        i++;
        if (i == n)  //当i = 6时,将i置0,循环操作
            i = 0;
    }
    while (*p == 0)
    {
        p++;
    }
    printf("\n最后一个是:%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结尾

代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
#include <stdlib.h>
 
void int_find(char *pc)
{
    int arr[50] = {0};
    char *p = pc;  // p 是工作指针
    int i = 0;
    while (*p != '\0')
    {
        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\t",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三个函数

代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
#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\t",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\t",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"); //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("排序后:\n");
    sort_int(intarr, i);
    sort_float(fltarr,j);
    return 0;
}

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

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

代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
#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("没有此元素,删除失败!\n");
    }
 
    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\t",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:\n");
    int temp;
    scanf("%d", &temp);
    while (temp != -1)
    {
        add(L, temp);
        scanf("%d", &temp);
    }
 
    printf("输入S:\n");
    scanf("%d", &temp);
    while (temp != -1)
    {
        add(S, temp);
        scanf("%d", &temp);
    }
 
    printf("输出L:");
    inputnode(L);
    printf("\n输出S:");
    inputnode(S);
 
    printf("\n删除L中的元素2:\n");
    del(L,2);
    inputnode(L);
 
    printf("\n并集:");
    intersection(L, S);
    printf("\n交集:");
    Union(L, S);
}

作者:Hang Shao

出处:https://www.cnblogs.com/pam-sh/p/12549561.html

版权:本作品采用「知识共享」许可协议进行许可。

声明:欢迎交流! 原文链接 ,如有问题,可邮件(mir_soh@163.com)咨询.

posted @   PamShao  阅读(898)  评论(0编辑  收藏  举报
编辑推荐:
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
阅读排行:
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· .NET10 - 预览版1新功能体验(一)
点击右上角即可分享
微信分享提示
more_horiz
keyboard_arrow_up dark_mode palette
选择主题
menu