你也能够上程序咖(https://meta.chengxuka.com),关上大学幕题板块,岂但有答案,解说,还能够在线答题。

一、选择题

1.上面程序段的运行后果是( )。

int x[5] = {2, 4, 6, 8, 10}, *p, **pp;p = x;pp = &p;printf("%d", *(p++));printf("%d\n", **pp);

A.4 4

B.2 4

C.2 2

D.4 6

答:B

解析:

题目中先定义了 int 类型的数组 x,又定义两个指针。

而后 p = x,示意将 x 的基地址赋值给 p,所以 p 指向数组中第一个元素。

第一次打印 *(p++),获取 p 指向的元素,打印 2, 而后指针地位向后挪动一个地位。

因为 pp = &p,示意将 p 的地址赋值给 pp,所以 pp 指向 p,p 通过上次打印时的 ++,曾经向后肯定一个,所以第二个打印 **pp,打印的就是 4。

2.对于以下变量定义,正确的赋值是( )。

int *p[3], a[3];

A. p=a

B. *p=a[0]

C. p=&a[0]

D. p[0]=&a[0]

答:B

解析:

定义为int *p[3],a[3];
可知这里 p 是一个指针数组,p 为数组名,所以不能作为赋值号的左操作数,所以选项 A 和 C 不对
*p 即 p[0],所以选项 B 等效于 p[0]=a,如上所说,数组 p 的元素是指针,所以选项 D 是不适合的

3.下列程序段的输入是( )。

int i, a[12] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12}, *p[4];for (i = 0; i < 4; i++){    p[i] = &a[i * 3];}printf("%d\n", p[3][2]);

A.12

B.8

C.6

D.上述程序有谬误

答:A

解析:

题目中定义了一维数组 a[12],以及一个指针数组 p。

当 i=0 时,第一次循环:p[0]=&a[0] ,p[0] 指向 a[0]

当 i=1 时,第二次循环:p[1]=&a[3] ,p[1] 指向 a[3]

当 i=2 时,第三次循环:p[2]=&a[6] ,p[2] 指向 a[6]

当 i=3 时,第四次循环:p[3]=&a[9] ,p[3] 指向 a[9]

当 i=4 时,循环完结。

p[3][2],相当于 p[3]+2,因为 p[3] 指向 a[9] ,所以 p[3][2] 指向 a[11],a[11] 所对应的值是 12 ,所以输入12。

4.设有如下定义的链表,则值为 7 的表达式是( )。

struct st{  int n;  struct st *next;} a[3] = {5, &a[1], 7, &a[2], 9, NULL}, *p = a;

A. p->n

B. (p->n)++

C. p->next->n

D. ++p->n

答:C

解析:

题目中 *p=a,示意指针 p 指向 a 的基地址。

选项 A,打印数组 a 中第一个元素的 n 的值,输入 5。

选项 B,也是打印 5。因为是后加。

选项 C,p 指向 a 的基地址,默认第一个元素, p->next,示意它的下一个元素,就是 7 和 &a[2],打印它的 n,就是 7。

选项 D,因为 -> 的优先级高于 ++,所以这里取 p -> n,数组中第一个元素的 n ,为 5,前置++,所以打印 6。

5.上面程序段输出一行字符,按输出的逆序建设一个链表。

struct node    {        char info;        struct node *link;    } * top, *p;    char c;    top = NULL;    while ((c = getchar()) != '\n')    {        p = (struct node *)malloc(sizeof(struct node));        p->info = c;        ___________;        top = p;    }

A. top->link=p

B. p->link= top

C. top=p->link

D. p=top->link

答:B

解析:

因为要逆序建设链表,所以让 p->link 赋值为 top,而后 top赋值为 p。

二、填空题

1.上面程序段的输入后果是( )。

const char *s[3] = {"point", "continue", "break"};    for (int i = 2; i >= 0; i--)        for (int j = 2; j > i; j--)            printf("%s\n", s[i] + j);

答:

ntinue

int

oint

解析:

这里是两层循环嵌套,

i=2时,j=2时,内层循环条件不满足。

i=1时,j=2时,打印 s[i]+j ,就是 s[1]+2,对应continue,然而因为要加 2,所以从下标为 2 的字符开始,就是 ntinue。

j=1时,内层循环条件不满足。

i=0时,j=2时,打印 s[i]+j ,就是 s[0]+2,对应point,然而因为要加 2,所以从下标为 2 的字符开始,就是 int。

j=1时,打印 s[i]+j ,就是 s[0]+1,对应point,然而因为要加 2,所以从下标为 2 的字符开始,就是o int。

2.上面程序段的输入后果是( )。

const char *st[] = {"Hello", "world", "!"}, **p = st;p++;printf("%s-%c\n", *p, **p);(*p)++;printf("%s-%c-%c\n", *p, **p, (**p) + 1);

答:

world-w

orld-o-p

解析:

首先定义了指针数组 st,存储的是 3 个字符串的地址。而后又定义了二级指针变量 p,这里 p 存储的是 st 的基地址。

而后 p++,那么指向了外面的第二个字符串的地址。*p 打印该字符串。world,**p,打印字符 w。

而后 (*p)++,那么指针向后挪动一位,从 o 开始,打印 orld,**p 打印 o, (**p) + 1 先取 **p 就是 o 而后再加 1,就是 p。

3.上面程序段的输入后果是( )。

static int a[4][4];int *p[4], i, j;for (i = 0; i < 4; i++)  p[i] = &a[i][0];for (i = 0; i < 4; i++){  *(p[i] + i) = 1;  *(p[i] + 4 - (i + 1)) = 1;}for (i = 0; i < 4; i++){  for (j = 0; j < 4; j++)    printf("%2d", p[i][j]);  printf("\n");}

答:

1 0 0 1

0 1 1 0

0 1 1 0

1 0 0 1

解析:

首先定义了一个 4X4 的矩阵,默认都是 0 。

0 0 0 0

0 0 0 0

0 0 0 0

0 0 0 0

而后又定义了一个指针数组 p。

第一个 for 循环中:p[0] 存储 a[0][0] 的地址。p[1] 存储 a[1][0] 的地址。p[2] 存储 a[2][0] 的地址。p[3] 存储 a[3][0] 的地址。

第二个 for 循环中:

i = 0 时,

*(p[i] + i) = 1 ,示意 *(p[0]+0) ,示意 第一行第一个元素批改值为 1。
*(p[i] + 4 - (i + 1)) = 1 ,示意 *(p[0]+3) , 示意第一行第四个元素批改值为 1。

i = 1 时,

*(p[i] + i) = 1 ,示意 *(p[1]+1) ,示意 第二行第二个元素批改值为 1。
*(p[i] + 4 - (i + 1)) = 1 ,示意 *(p[1]+2) , 示意第二行第三个元素批改值为 1。

i = 2 时,

*(p[i] + i) = 1 ,示意 *(p[2]+2) ,示意 第三行第三个元素批改值为 1。
*(p[i] + 4 - (i + 1)) = 1 ,示意 *(p[2]+2) , 示意第三行第二个元素批改值为 1。

i = 3 时,

*(p[i] + i) = 1 ,示意 *(p[3]+3) ,示意 第四行第四个元素批改值为 1。
*(p[i] + 4 - (i + 1)) = 1 ,示意 *(p[3]+0) , 示意第四行第一个元素批改值为 1。

第三个 for 循环,打印这个矩阵,所以最终后果为:

1 0 0 1

0 1 1 0

0 1 1 0

1 0 0 1

4.找出最小字符串。输入多个字符串中最小的字符串。请填空。

    const char *st[] = {"bag", "good", "This", "are", "zoo", "park"};    const char *smin = _________;    for (int i = 1; i < 6; i++)        if (_________ < 0)            smin = st[i];    printf("The min string is %s \n",_________ );

答:

*st

strcmp(st[i], smin)

smin

解析:

首先定义了一个字符指针数组,想找到外面的最小字符串,首先取第一个字符串赋值给 smin,所以 *smin = *st,而后循环中顺次比拟字符串大小,strcmp(st[i], smin) <0 ,那么就取 st[i] 赋给 smin,循环完结后打印 smin 即可。

5.查找最高分。输出 n(n<=10)个问题,查找最高分并输入。请填空。

#include <stdio.h>int *GetMax(int score[], int n);int main(void){    int i, n, score[10], *p;    scanf("%d", &n);    for (i = 0; i < n; i++)        scanf("%d", &score[i]);    p = _____________;    printf("Max:%d\n", *p);    return 0;}int *GetMax(int score[], int n){    int i, temp, pos = 0;    temp = score[0];    for (i = 0; i < n; i++)        if (score[i] > temp)        {            temp = score[i];            pos = i;        }    return _____________;}

答:

GetMax(score, n)

score + pos 或者 &score[pos]

解析:

就是定义一个函数,找到数组中的最大值,返回它的地址。所以第一个空调用函数,参数传入数组和 n 的值。第二个空,就是函数中返回后果。数组的实质就是存储数组的基地址,加上 pos 即可。

6.输入链表中不及格学生的学号和问题。已建设学生"英语"课程的问题链表(问题存于 score 域中,学号存于 num 域中),下列函数的性能是输入不及格学生的学号和问题。请填空。

void require(struct student *head){    struct student *p;    if (head != NULL)    {        ____________;        while (p != NULL)        {            if (____________)                printf("%d%.1f\n", p->num, p->score);            p = p->next;        }    }}

答:

p = head

p->score < 60

解析:

第一个空将 head 赋值给 p,第二个空判断问题是否及格。

三、程序设计题

题目1:输入月份英文名:输出月份,输入对应的英文名称。要求用指针数组示意 12 个月的英文名称。例如,输出 5 ,输入 May。试编写相应程序。

答案代码:

#include <stdio.h>char *getmonth(int n);int main(){    // 习题(11.3.1)    /*    输入月份英文名:输出月份,输入对应的英文名称。要求用指针数组示意 12 个月的英文名称。例如,输出 5 ,输入 May。试编写相应程序。    */    char *p;    int n;    printf("input n:");    scanf("%d", &n);    p = getmonth(n);    if (p == NULL)        printf("wrong input!\n");    else        printf("%s\n", p);    return 0;}char *getmonth(int n){    int month;    char *a[12] = {"January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November"};    if (n > 0 && n < 13)    {        switch (n)        {        case 1:            month = 1;            break;        case 2:            month = 2;            break;        case 3:            month = 3;            break;        case 4:            month = 4;            break;        case 5:            month = 5;            break;        case 6:            month = 6;            break;        case 7:            month = 7;            break;        case 8:            month = 8;            break;        case 9:            month = 9;            break;        case 10:            month = 10;            break;        case 11:            month = 11;            break;        case 12:            month = 12;            break;        }        return a[--month];    }    else        return 0;}

运行后果:

题目2:查找星期:定义一个指针数组,将下表的星期信息组织起来,输出一个字符串,在表中查找,若存在,输入该字符串在表中的序号,否则输入 -1。试编写相应程序。

序号星期
0Sunday
1Monday
2Tuesday
3Wednesday
4Thurday
5Friday
6Saturday

答案代码:

#include <stdio.h>#include <string.h>int main(){    // 习题(11.3.2)    /*    查找星期:定义一个指针数组,将下表的星期信息组织起来,输出一个字符串,在表中查找,若存在,输入该字符串在表中的序号,否则输入 -1。试编写相应程序。    */    char *p[] = {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"};    char s[10];    printf("input string:");    scanf("%s", s);    int i = 0, j = -2;    for (i = 0; i < 7; i++)    {        if (!strcmp(p[i], s))        {            j = i;            break;        }    }    printf("%d\n", j);  return 0;}

运行后果:

题目3:计算最长的字符串长度:输出 n(n<10)个字符串,输入其中最长字符串的无效长度。要求自定义函数 int max_ len(char *s[], int n),用于计算有 n 个无素的指针数组 s 中最长的字符串的长度。试编写相应程序。

答案代码:

#include <stdio.h>#include <string.h>int max_len(char *s[], int n);int main(){    // 习题(11.3.3)    /*    计算最长的字符串长度:输出 n(n<10)个字符串,输入其中最长字符串的无效长度。要求自定义函数 int max_ len(char *s[ ],int n),用于计算有 n 个无素的指针数组 s 中最长的字符串的长度。试编写相应程序。    */    int i, n;    char *s[10];    char a[10][10];    printf("input n(n<10):");    scanf("%d", &n);    printf("input %d  string :\n", n);    for (i = 0; i < n; i++)    {        scanf("%s", a[i]);        s[i] = a[i];    }    printf("%d\n", max_len(s, n));    return 0;}int max_len(char *s[], int n){    int i, j = 0;    for (i = 0; i < n; i++)    {        if (strlen(s[i]) > strlen(s[j]))        {            j = i;        }    }    return strlen(s[j]);}

运行后果:

题目4:字符串的连贯:输出两个字符串,输入连贯后的字符串。要求自定义函数 char *streat(char *s, char *t), 将字符串 t 复制到字符串 s 的末端,并且返回字符串 s 的首地址。试编写相应程序。

答案代码:

#include <stdio.h>char *streat(char *s, char *t);int main(){    // 习题(11.3.4)    /*    字符串的连贯:输出两个字符串,输入连贯后的字符串。要求自定义函数 char *streat(char *s, char *t), 将字符串 t 复制到字符串 s 的末端,并且返回字符串 s 的首地址。    */    char s[80], t[80];    printf("input 1 string s:");    gets(s);    printf("input 2 string t:");    gets(t);    printf("%s\n", streat(s, t));    return 0;}char *streat(char *s, char *t){    int i = 0;    int j = 0;    while (s[i] != '\0')    {        i++;    }    while (t[j] != '\0')    {        s[i] = t[j];        i++;        j++;    }    return s;}

运行后果:

题目5:指定地位输入字符串:输出一个字符串后再输出两个字符,输入此字符串中从与第 1 个字符匹配的地位开始到与第 2 个字符匹配的地位完结的所有字符。例如,输出字符串 "program" 与 2 个字符 "r" 和 "g" 后,输入 "rog" 。要求自定义函数 char *match(char *s, char ch1, char ch2) 返回后果字符串的首地址。试编写相应程序。

答案代码:

#include <stdio.h>#include <string.h>char *match(char *s, char ch1, char ch2);int main(){    // 习题(11.3.5)    /*    指定地位输入字符串:输出一个字符串后再输出两个字符,输入此字符串中从与第 1 个字符匹配的地位开始到与第 2 个字符匹配的地位完结的所有字符。例如,输出字符串 "program" 与 2 个字符 "r" 和 "g" 后,输入 "rog" 。要求自定义函数 char *match(char *s, char ch1, char ch2)返回后果字符串的首地址。    */    char s[100], *p;    char ch1, ch2;    printf("input string:");    scanf("%s", s);    getchar();    printf("input two char:");    scanf("%c %c", &ch1, &ch2);    p = match(s, ch1, ch2);    if (p != NULL)        printf("%s\n", p);    else        printf("Not found!\n");    return 0;}char *match(char *s, char ch1, char ch2){    char c[100], *p;    int i = 0;    int j = 0;    int start = -1;    int end = -1;    int k;    while (s[i] != '\0')    {        if (s[i] == ch1) // 找到起始下标        {            start = i;        }        if (s[i] == ch2) //找到完结下标        {            end = i;            break; // 如果找到了,就能够间接完结while循环了。        }        i++;    }    if (start >= 0 && start <= end)    {        // 遍历 start到 end的字符        k = start;        while (k <= end)        {            c[j] = s[k];            k++;            j++;        }        c[j] = '\0';        p = c;        return p;    }    else    {        return NULL;    }}

运行后果:

题目6:查找子串:输出两个字符串 s 和 t ,在字符串 s 中查找子串 t ,输入起始地位,若不存在,则输入 -1。要求自定义函数 char *search(char *s, char *t)返回子串 t 的首地址,若未找到,则返回 NULL 。试编写相应程序。

答案代码:

#include <stdio.h>#include <string.h>char *search(char *s, char *t);int main(){    // 习题(11.3.6)    /*    查找子串:输出两个字符串 s 和 t ,在字符串 s 中查找子串 t ,输入起始地位,若不存在,则输入 -1。要求自定义函数 char *search(char *s, char *t)返回子串 t 的首地址,若未找到,则返回 NULL 。    */    char s[100], t[100], *p;    printf("input  string:");    scanf("%s", s);    printf("input substring:");    scanf("%s", t);    p = search(s, t);    if (p != NULL)    {        printf("%ld\n", p - s);    }    else    {        printf("-1\n");    }    return 0;}char *search(char *s, char *t){    int size_t = strlen(t), size_s = strlen(s), T, i, j;    char *p = NULL;    for (i = 0; i <= (size_s - size_t); i++)    {        p = s + i;        T = 1;        for (j = 0; j < size_t; j++)        {            if (*p != *(t + j))            {                T = 0;                break;            }            p++;        }        if (T == 1)            break;    }    if (T == 0)        return NULL;    else        return s + i;}

运行后果:

题目7:奇数值结点链表:输出若干个正整数(输出 -1 为完结标记)建设一个单向链表,头指针为 L ,将链表 L 中奇数值的结点从新组成个新的链表 NEW ,并输入新建链表的信息。试编写相应程序。

答案代码:

#include <stdio.h>#include <stdlib.h>struct ListNode{    int data;    struct ListNode *next;};struct ListNode *readlist();struct ListNode *getodd(struct ListNode **L);void printlist(struct ListNode *L);int main(){    // 习题(11.3.7)    /*    奇数值结点链表:输出若干个正整数(输出 -1 为完结标记)建设一个单向链表,头指针为 L ,将链表 L 中奇数值的结点从新组成个新的链表 NEW ,并输入新建链表的信息。    */    struct ListNode *L, *Odd;    L = readlist();    Odd = getodd(&L);    printlist(Odd);    printlist(L);    return 0;}void printlist(struct ListNode *L){    struct ListNode *p = L;    while (p)    {        printf("%d ", p->data);        p = p->next;    }    printf("\n");}struct ListNode *readlist(){    int data;                            // 输出数据    int size = sizeof(struct ListNode); // 单个链表结点占据的内存    struct ListNode *head, *tail, *p;    head = tail = NULL;    printf("input number:");    scanf("%d", &data);    while (data != -1)    {        p = (struct ListNode *)malloc(size);        p->data = data;        p->next = NULL;        if (head == NULL)        {            head = p;        }        else        {            tail->next = p;        }        tail = p;        scanf("%d", &data);    }    return head;}struct ListNode *getodd(struct ListNode **L){    int data;    int size = sizeof(struct ListNode);    struct ListNode *head, *tail, *pNew; // 链表New    struct ListNode *ptr1, *ptr2;    head = tail = NULL;    // L链表的head是奇数    while (*L != NULL && (*L)->data % 2 != 0)    {        data = (*L)->data;        // 将L链表的奇数从新组成一个新的链表        pNew = (struct ListNode *)malloc(size);        pNew->data = data;        pNew->next = NULL;        if (head == NULL)        {            head = pNew;        }        else        {            tail->next = pNew;        }        tail = pNew;        // 删除L链表的奇数        ptr2 = *L;        *L = (*L)->next;        free(ptr2);    }    if (*L == NULL)    {        return NULL;    }    // L链表的head非奇数    ptr1 = *L;    ptr2 = (*L)->next;    while (ptr2 != NULL)    {        data = ptr2->data;        if (data % 2 != 0)        {            // 将L链表的奇数从新组成一个新的链表            pNew = (struct ListNode *)malloc(size);            pNew->data = data;            pNew->next = NULL;            if (head == NULL)            {                head = pNew;            }            else            {                tail->next = pNew;            }            tail = pNew;            // 删除L链表的奇数            ptr1->next = ptr2->next;            free(ptr2);        }        else        {            ptr1 = ptr2;        }        ptr2 = ptr1->next;    }    return head;}

运行后果:

题目8:删除结点:输出若干个正整数(输出 -1 为完结标记)建设一个单向链表,再输出一个整数 m ,删除链表中值为 m 的所有结点。试编写相应程序。

答案代码:

#include <stdio.h>#include <stdlib.h>struct ListNode{    int data;    struct ListNode *next;};struct ListNode *readlist();struct ListNode *deletem(struct ListNode *L, int m);void printlist(struct ListNode *L);int main(){    // 习题(11.3.8)    /*    删除结点:输出若干个正整数(输出 -1 为完结标记)建设一个单向链表,再输出一个整数 m ,删除链表中值为 m 的所有结点。    */    int m;    struct ListNode *L = readlist();    printf("input m:");    scanf("%d", &m);    L = deletem(L, m);    printlist(L);    return 0;}void printlist(struct ListNode *L){    struct ListNode *p = L;    while (p)    {        printf("%d ", p->data);        p = p->next;    }    printf("\n");}struct ListNode *readlist(){    int data;    int size = sizeof(struct ListNode);    struct ListNode *head, *tail, *p;    head = tail = NULL;    printf("input number:");    scanf("%d", &data);    while (data != -1)    {        p = (struct ListNode *)malloc(size);        p->data = data;        p->next = NULL;        if (head == NULL)        {            head = p;        }        else        {            tail->next = p;        }        tail = p;        scanf("%d", &data);    }    return head;}struct ListNode *deletem(struct ListNode *L, int m){    struct ListNode *ptr1, *ptr2;    //要被删除结点为表头结点    while (L != NULL && L->data == m)    {        ptr2 = L;        L = L->next;        free(ptr2);    }    // 链表空    if (L == NULL)    {        return NULL;    }    // 要被删除结点为非表头结点    ptr1 = L;    ptr2 = L->next; // 从表头的下一个结点搜寻所有合乎删除要求的结点    while (ptr2 != NULL)    {        if (ptr2->data == m) // ptr2所指结点合乎删除要求        {            ptr1->next = ptr2->next;            free(ptr2);        }        else        {            ptr1 = ptr2; // ptr1后移一个结点        }        ptr2 = ptr1->next; // ptr2指向ptr1的后一个结点    }    return L;}

运行后果: