C 2014年笔试题

1、指出程序中的错误,说明原因并修正#

1.1#

1
2
3
4
5
6
7
8
int *p,*q;
p=malloc(sizeof(int)*20);
q=malloc(sizeof(int)*10);
q=p;
free(p);
free(q);

分析:

错误1,q原本储存一片int类型的内存区域的地址,在没有释放这片地址时就修改了q的内容,使这片区域无法收回,导致内存泄漏

错误2,p与q指向同一片内存区域,在使用free(p)后该内存区域已经释放,不能再free一遍。改正:将free(q)放在q=p前面(改正有多种说法,这里选择其中一种)


1.2#

1
2
3
4
5
6
7
8
//交换字符串
void swap(char *p, char *q)
{
    char *temp; //p、q所指的值的交换
    *temp=*p;
    *p=*q;
    *q=*temp;
}

分析:该代码首先创建了形参p和q接受两个char类型的地址,在代码内部交换的这两个形参的内容,没有对外界产生任何影响。

该代码的修改如下:

1
2
3
4
5
6
7
void swap(char *p, char *q)
{
    char temp[100];
    strcpy(temp,p); //strcpy函数:复制字符串
    strcpy(p,q);
    strcpy(q,temp);
}

2、简答题#

2.1 arr为整型数组,N为数组长度,enumb为整型变量,下列函数负责找出arr数组中等于enumb的元素所在位置。指出程序的三种异常,并说明原因。#

1
2
for(i=N-1;arr[i]!=enumb;--i)
  printf(“%d”,i);

分析:

首先for循环后面应该有分号,否则每次循环都有输出。

其次如果arr数组中没有enumb,i就会变为负号,数组溢出。

最后,若i一直减小,i会减小直到溢出。


2.2  if(B) s1 else s2;是什么结构?使用显示结构语言该如何表示?并标出条件跳转和强制跳转#

 分析:条件分支结构

1
2
3
4
if(b) goto L1;//条件跳转
goto L2;//强制跳转
L1: s1
L2:     s2

2.3 C语言中,常量存储在哪里?静态局部变量和静态全局变量存储在哪里?#

分析:常量存储在常量区,静态局部变量和静态全局变量存储在全局数据区。


3填空题#

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
list selectsort(list head){
    list p = (struct node*)malloc(sizeof(node));
    p->next = head;
    head = p;//新建一个头结点
    p = head->next;
    list k = head, q = head;
 
    while (p->next)
    {
        q = p->next;
        k = q;  //k记录最小值位置          //找到最小元素位置
        while (q) {
            if (q->data < k->data) {
                k = q;
            }
            q = q->next;
        }          //交换元素位置
        if (p->next != k) {
            int r = p->next->data;
            p->next->data = k->data;
            k->data = r;
        }
        p = p->next;   //填空一
    }
    p = head;
    head = head->next;   //填空二
    free(p); //释放头结点
    return head;   //填空三
} 

3.2 速排序法求某个数组前n个元素第k大的数#

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
int find_k(int *a, int n,int k) {
    int i, j, t;
    int low = 0,high = n - 1;
    do {
        i = low; j = high; t = a[low];
        do {
            while (a[j]>t) j--;
            while (a[i]<t) i++;
            if ()
                swap(&a[j], &a[i]);
            else
                ;
        } while (i<j);
        if (i == k)
            return t;
        if (i>k)
            ;
        if (i<k)
            ;
    } while (low<high);
    ;
}

分析:该题目使用快排划分的第一种写法,原理是利用每次快排划分之后总能确定一个元素的最终位置。该程序可能仍然存在问题,最大的数字是第0个。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
int find_k(int *a, int n,int k) { //从大到小排序
    int i, j, t;
    int low = 0,high = n - 1;
    do {
        i = low; j = high; t = a[low];
        do {
            while (a[j]<t) j--;
            while (a[i]>t) i++;
            if (i<j)
                swap(&a[j], &a[i]);
            else
                break;   //填空1
        } while (i<j);
        if (i == k)
            return t;
        if (i>k)
            high = i - 1;   //填空2
        if (i<k)
            low = i + 1;     //填空3
    } while (low<high);
    return  a[low];   //填空4
}

3.3约瑟夫环问题 【见2015年】 #

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
int a[N + 1];
int *p = a, i,j,k;
for(i = 0; i<N + 1; i++)
    *(p+i) = i;
;
;
for( i = 0; k != 1; p++)
{
    if()
        p = a + 1;
    if()
        i++;
    if()
    {
        k--;
        i = 0;
        *p = 0;
    }
}
for(i = 0; i<N + 1; i++)
{
    if()
        printf("%d\n",a[i]);
}

分析:15年约瑟夫环区别

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
int a[N + 1];
int *p = a, i,j,k;//赋值0~N
for(i = 0; i<N + 1; i++)
    *(p+i) = i;
p = a + 1;  //填空1
k = N;    //填空2
for( i = 0; k > 1; p++)  //k为剩下的人数
{
    if(p>a + N)
        p = a + 1;
    if(*p != 0)  //碰到元素为0说明已经杀死,不参与计数
        i++;   //i报数
    if(i == 3)
    {
        k--;
        i = 0;
        *p = 0;
    }
}//打印输出
for(i = 0; i<N + 1; i++)
{
    if(a[i] != 0)
        printf("%d\n",a[i]);
}

3.4 完美乘法,若a*b=c,且abc中0~9的数字各出现一次,填写程序空缺处。#

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
int f[10],s[3];
int n=0;
for (int a = 12; a<999; a++)
{
    int t = 0;
    //清空数字计数
    for (int x = 0; x<10; x++)
        f[x] = 0;
    for (int b = 345; b<9999; b++)
    {
        int c ;
        ;     //填空一
        s[0] = a;
        s[1] = b;
        s[2] = c;
        //计算abc中出现数字的次数
        for (int x = 0; x < 3; x++)
        {
            int y = s[x];
            while ()
            {
                int t = y % 10;
                f[t]++;
                ;    //填空二
            }
        }
        //检查是否每个数都个出现一次
        for (int x = 0; x<10; x++)
        {
            if ()  ;   //填空三
        }
        if ()
            printf("%d*%d=%d\n",a,b,c);            ;//填空四
    }
}

分析:

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
int f[10],s[3];
int n=0;
for (int a = 12; a<999; a++)
{
    int t = 0;
    //清空数字计数
    for (int x = 0; x<10; x++)
        f[x] = 0;
    for (int b = 345; b<9999; b++)
    {
        int c = a*b;
        s[0] = a;
        s[1] = b;
        s[2] = c;
        //计算abc中出现数字的次数
        for (int x = 0; x < 3; x++)
        {
            int y = s[x];
            while (y > 0)
            {
                int t = y % 10;
                f[t]++;
                y = y / 10;
            }
        }
        //检查是否每个数都个出现一次
        for (int x = 0; x<10; x++)
        {
            if (f[x] != 1)  t++;
        }
        if (t == 0)
            printf("%d*%d=%d\n",a,b,c);
        n++;            //统计循环次数
    }
}

4编程题#

4.1 将字符串逆转,函数原型void reverse(char *str);,要求空间复杂度为O(1)#

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
 
void reverse(char *str)
{
    int i = 0, len = strlen(str);
    for (; i < len / 2; i++)
    {
        char a = str[i];
        str[i] = str[len - i - 1];
        str[len - i - 1] = a;
    }
}
int main()
{
    char ch[] = "helloworld";
    reverse(ch);
    printf("逆转后:%s",ch);
    return 0;
}
 

4.2 比较两个身份证字符串的生日大小。函数原型int isbothsame(char str1[19], char str2[19]);#

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include <stdio.h>
#include <stdlib.h>
 
int isbothsame(char str1[19], char str2[19])
{
    int low = 6, hight = 13;
    while (low<hight &&str1[low] == str2[low])low++; //low记录不相同的位置
    return str1[low] - str2[low];  //负数表示str1的年长
}
int main()
{
    char a[] = "412824199605281234",b[] = "41282519960825789x";
    if(isbothsame(a,b) < 0)
        printf("a年长!");
    else
        printf("b年长!");
    return 0;
}

4.3 计算1-x+x^2/2!-x^3/3!+…+x^n/n!  【见2015年】#

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
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);
}

4.4一个链表,找出其中数据项最大的结点,然后将其移动到链表尾部(结点node由整型data节点指针next构成不允许申请新的结点#

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
#include <stdio.h>
#include <stdlib.h>
 
typedef struct slist
{
    int data;
    struct slist *next;
};
void movemax(struct slist *L)
{
    struct slist *p = L->next, *pre = L, *max = p;
    //找到最大值的位置
    while (p)
    {
        if (p->data>max->data)max = p;
        pre = p;
        p = p->next;
    }
    //此时p指向NULL,pre指向最后一个结点
    //最大值和最后一个节点交换
    int temp = pre->data;
    pre->data = max->data;
    max->data = temp;
}
int main()
{
    //建立单链表【尾插法】
    int a[] = {1,4,7,8,5,2,9,6,3};
    struct slist *p,*head = (struct slist*)malloc(sizeof(struct slist));
    head ->next = NULL;
    int i;
    p = head;
    for(i = 0;i < 9;i++)
    {
        struct slist *node = (struct slist*)malloc(sizeof(struct slist));
        node ->data = a[i];
        node ->next = p ->next;
        p ->next = node;
        p = node;
    }
    printf("找到最大值后移:\n");
    movemax(head);
    //输出
    p = head ->next;
    while(p != NULL)
    {
        printf("%d\t",p ->data);
        p = p->next;
    }
    return 0;
}

作者:Hang Shao

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

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

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

posted @   PamShao  阅读(526)  评论(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