浙大版《C语言程序设计》第四版(何钦铭颜晖) 第8章 指针 课后习题答案

发布时间:2023-11-08 08:00

你也可以上程序咖(https://meta.chengxuka.com),打开大学幕题板块,不但有答案,讲解,还可以在线答题。

\"WX20220412-135428@2x\"

一、选择题

1.下列语句定义 px 为指向 int 类型变量的指针,正确的是( )。

A. int x, *px=x;
B.int x, *px=&x;
C. int *px=&x, x;
D.int x, px=x;

答:B

解析:先定义变量,再定义指针,定义指针使用 *。为指针赋值为某个变量的地址时使用 & 符。

2.以下选项中,对基本类型相同的指针变量不能进行运算的运算符是( )。

A. =
B. ==
C. +
D. -

答:C

解析:

选项 A :“=(赋值)”是对于类型相同的两个指针变量之间常规运算。

选项 B: “==(比较相等)”比较两个指针变量是否相同。

选项 C:“+” 运算是不可以的,因为指针变量是一种特殊的变量,指针变量的值存放的是所指向变量的地址,两个地址相加并不能保证结果为一个有效的地址值,因而在 C 语言中指针变量相加是非法的。

选项 D:“-(减法)”运算两个相同指针变量相减可以获得在之间相隔的同类型元素个数(在某个类型的数组中的应用)。

3.下列程序的输出结果是( )。

void f(int *p)
{
    *p = 5;
}
int main(void)
{
    int x = 10, *px = &x;
    f(px);
    printf(\"%d#\", (*px)++);
    printf(\"%d\\n\", x);
    return 0;
}

A.5#6
B.6#6
C.10#11
D.11#11

答:A

解析:这里考察当是指针作为函数的参数。这里将 px 作为实参,传递给函数的形参 p,就表示 p 也指向变量 x 的地址。在函数中操作指针 p,修改 x 的值为 5。当函数结束后,打印 (*px)++,就是指针 px 对应的变量 x++,5。然后 x 的值自增 1,为 6 。

4.以下程序的输出结果是( )。

void sub(int x, int y, int *z)
{
    *z = y - x;
}
int main(void)
{
    int a, b, c;
    sub(10, 5, &a);
    sub(7, a, &b);
    sub(a, b, &c);
    printf(\"%d,%d,%d\\n\", a, b, c);
    return 0;
}

A.5,2, 3
B.5, -2, -7
C.-5,-12, -17
D.-5,-12, - 7

答:D

解析:

自定义函数中主要是修改指针 z 指向的变量的值。

在 main() 中,先定义了 3 个变量 a ,b,c。由于没有初始值,那么系统会自动分配随机值。

然后第一次调用sub() 函数,形参 x 赋值为 10,y 赋值为 5,*z 赋值为 a 的地址,就表示指针 z 指向变量 a 的地址。函数中通过指针 z 修改变量 a 的值为 y-x,就是 -5。

然后第二次调用sub() 函数,形参 x 赋值为 7,y 赋值为 a,就是刚刚的 -5,*z 赋值为 b 的地址,就表示指针 z 指向变量 b 的地址。函数中通过指针 z 修改变量 b 的值为 y-x,就是 -5-7=-12。

然后第三次调用sub() 函数,形参 x 赋值为 a,是 -5 ,y 赋值为 b,就是刚刚的 -12,*z 赋值为 c 的地址,就表示指针 z 指向变量 c 的地址。函数中通过指针 z 修改变量 c 的值为 y-x,就是 -12-(-5)=-7。

5.若有以下定义,且 0<=i<10 ,则对数组元素的错误引用是( )。·

int i,a[]={0,1,2,3,4,5,6,7,8,9},*p=a;

A. *(a+i)
B. a[p-a+i]
C. p+i
D. *(&a[i])

答:C

解析:p 是指针类型,要想操作 p 指向的变量,需要使用 *

6.下列程序段的输出结果是( )。

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

A.3
B.4
C.a[4]的地址
D.非法

答:B

解析:数组 a 的长度为 10,a 指向了数组的基地址,也就是第 1 个元素的地址。指针变量 p,初始值为 a+3,就表示指向了 数组 a 中的第 4 个元素的地址,打印的是 ++p 之后表示指向了第 5 个元素,也就是数值 4。

  1. 对于下面的程序段,叙述正确的是( )。
char s[]=\"china\", *p=s;

A. *p与 s[0] 相等
B.数组 s 中的内容和指针变量 p 中的内容相等
C. s 和 p 完全相同
D.数组 s 的长度和 p 所指向的字符串长度相等

答:A

解析:

选项 B,数组 s 中的内容是字符串,p 中的内容是一个地址

选项 C,从指针角度看,s 是常量指针,而 p 不是

选项 D,s 数组的长度是 p 所指向的字符串长度 +1

8.下面程序段的运行结果是( )。

char s[] = \"language\", *p = s;
    while (*p++ != \'u\')
    {
        printf(\"%c\", *p - \'a\' + \'A\');
    }

A. LANGUAGE
B. ANGU
C. LANGU
D. LANG

答:B

解析:p 指向字符串首地址,while 判断 p 指向的字符是否为 \'u\',如果是 \'u\' 则循环结束,然后将字符转换为大写字符。这里的一个关键问题是,while 中 p++ != \'u\',是先判断 p != \'u\',然后 p++,因此判断字符 !=\'u\'后,p 接着就指向了下一个字符 \'a\',因此 printf 输出的是 \'A\' ,当 p 指向字符 \'g\' 时,也不等于 \'u\',然后 p 指向下一个字符 \'u\' ,因此会输出 \'U\'。最终输出的字符是\"ANGU\"

二、填空題

1.输出一维数组最大元素和最小元素的下标。査找一维数组的最大元素和最小元素的下示,分別存放在函数 main() 的 maxsub 和 minsub 变量中。请填空。

void find(int *, int, int *, int *);
int main(void)
{
    int maxsub, minsub, a[] = {5, 3, 7, 9, 2, 0, 4, 1, 6, 8};
    find(____________);
    printf(\"maxsub=%d, minsub=%d\\n\", maxsub, minsub);
    return 0;
}
void find(int *a, int n, int *maxsub, int *minsub)
{
    int i;
    *maxsub = *minsub = 0;
    for (i = 1; i < n; i++)
    {
        if (a[i] > a[*maxsub])
            ____________;
        if (a[i] < a[*minsub])
            ____________;
    }
}

答:

a, 10, &maxsub, &minsub

*maxsub = i

*minsub = i

解析:

find() 函数是为了找到最大值和最小值的下标。这里需要 4 个参数,第一个参数是数组,第二个参数是数组的长度,第三个是要存储最大值下标 maxsub,第四个要存储最小值下标 minsub。

所以第二个空,当数组中的元素值大于 最大值下标对应的数组元素值 a[i] > a[*maxsub],那么将 i 的值赋值给最大下标:*maxsub = i

第二个空,当数组中的元素值小于 最小值下标对应的数组元素值 a[i] < a[*minsub],那么将 i 的值赋值给最小下标:*minsub = i

至于第一个空,就是调用函数。传入对应的实参即可。

2.数组插值。函数 insert() 的功能是在一维数组 a 中将 x 插入到下标为 i (i>=0)的元素前,如果 i>=元素个数,则 x 插入到末尾,元素个数存放在指针 n 所指向的变量中,插入后元素个数加 1 。请填空。

void insert(int a[], int *n, int x, int i)
{
    int j;
    if (________)
    {
        for (j = *n - 1; ________; j--)
            ________ = a[j];
    }
    else
    {
        i = *n;
    }
    a[i] = ________;
    (*n)++;
}

答:

i < *n

j >= i

a[j + 1]

x

解析:

第一空,题目说如果 i>=元素个数,则 x 插入到末尾,所以 if 的条件就是 i < *n

第二空,循环将 i 后面的元素向后移动一位。所以第二空是 j >= i。

第三空,向后移动一位。就是 a[j + 1] = a[j]

第四空,将 x 存入到 i 的位置上。a[i] = x。

3.判断回文。先消除输入字符串 s 的前后空格,再判断其是否为“回文”(即字符串正读和倒读都是一样的), 若是则输出 Yes ,否则输出 No。请填空。

    char ch, s[80], *p, *q;
    int i, j, n;
    gets(s);
    p = _________;
    while (*p == \' \')
    {
        _________;
    }
    n = strlen(s);
    q = _________;
    while (*q == \' \')
    {
        q--;
    }
    while (_________ && *p == *q)
    {
        p++;
        _________;
    }
    if (p < q)
        printf(\"No\\n\");
    else
        printf(\"Yes\\n\");

答:

s

p++

s + n - 1

p < q

q--

解析:

首先将指针 p 指向字符串 s ,第一个 while 循环结束后,指针 p 会指到字符串非空的第一个字符,也就是说这个循环用于清除字符串的前面的空格。第二个 while 循环结束后,会去除字符串尾部的空格,指针 q 指向最后一个非空的字符。最后一个 while 循环,这里操作两个指针,判断它俩指向的字符是否相同,如果相同,p 从前向后移动,q 从后向前移动,如果最后 p 和 q 能重合,就说明是回文字符串,否则就不是。

4.最大字符移位。在字符串 str 中找出最大的字符,将在该字符前的所有字符往后顺序移动一位,再把最大字符放在字符串的第一个位置上。如 \" knowedge\" 变成 \"wknoledge\" 。请填空。

char max, str[80], *p = str, *q = str;
    gets(p);
    max = *(p++);
    while (*p != \'\\0\')
    {
        if (max < *p)
        {
            max = *p;
            __________;
        }
        p++;
    }
    p = q;
    while (__________)
    {
        __________;
        p--;
    }
    *p = max;
    puts(p);

答:

q = p

p != str

*p = *(p - 1)

解析:

第一个空,q 指向当前的最大字符,所以一旦判断 max <*p ,那么就取 p 赋值给 q。一直循环到整个字符串结束, q 就指向了整个字符串中的最大字符。

然后将 p 也设置到 q 指向的位置,然后将 p 前面的字符,每一个都向后移动一位。直到字符串开头,所以循环条件就是 p != str。

最后再将 max 的字符,赋值到字符串开头即可。

5.字符传送。将字符串 s1 的所有字符传送到字符串 s2 中,要求每传送 3 个字符就再存放一个星号。如字符串 s1 为 \"abedefg\" ,则字符串 s2 为 \"abe*def*g\"。请填空。

    char s1[80], s2[80], *p = s1;
    int cnt = 0, k = 0;
    gets(p);
    while (*p != \'\\0\')
    {
        s2[k] = *p;
        k++;
        p++;
        cnt++;
        if (_________)
        {
            s2[k] = \'*\';
            _________;
            _________;
        }
    }
    s2[k] = \'\\0\';
    puts(s2);

答:

cnt == 3

cnt = 0

k++

解析:

每传送 3 个字符,就要放一个星号,所以 cnt 为 3 的时候,放置星号,然后 cnt 要重新置为 0 ,k 要继续 ++ 。

三、程序设计题

题目1:拆分实数的整数与小数部分:要求自定义一个函数 void splitfloat (float x,int *intpart, float *fracpart), 其中 x 是被拆分的实数,* intpart* fracpart 分别是将实数 x 拆分出来的整数部分与小数部分。编写主函数,并在其中调用函数 splitfloat() 。试编写相应程序。

答案代码:

#include 
void splitfloat(float x, int *intpart, float *fracpart);
int main(void)
{

    // 习题(8.3.1)
    /*
    拆分实数的整数与小数部分:要求自定义一个函数 void splitfloat (float x,int *intpart, float *fracpart),
    其中 x 是被拆分的实数,* intpart 和 * fracpart 分别是将实数 x 拆分出来的整数部分与小数部分。
    编写主函数,并在其中调用函数 splitfloat() 。

    */

    float x, fracpart;
    int intpart;
    printf(\"input number:\");
    scanf(\"%f\", &x);
    splitfloat(x, &intpart, &fracpart);
    printf(\"intpart=%d\\n\", intpart);
    printf(\"fracpart=%f\\n\", fracpart);
    return 0;
}
void splitfloat(float x, int *intpart, float *fracpart)
{
    *intpart = (int)x;
    *fracpart = x - *intpart;
}

运行结果:

\"浙大版《C语言程序设计》第四版(何钦铭颜晖)

题目2:在数组中查找指定元素:输入一个正整数 n ( 1

答案代码:

#include 

int main(void)
{

    // 习题(8.3.2)
    /*
    在数组中查找指定元素:输入一个正整数 n ( 1

运行结果:

\"浙大版《C语言程序设计》第四版(何钦铭颜晖)

题目3:循环后移:有 n 个整数,使前面各数顺序向后移 m 个位置,移出的数再从开头移入。编写一个函数实现以上功能,在主函数中输入 n 个整数并输出调整后的 n 个数。试编写相应程序。

答案代码:

#include 
void mov(int *x, int n, int m);
int main(void)
{

    // 习题(8.3.3)
    /*
    循环后移:有 n 个整数,使前面各数顺序向后移 m 个位置,移出的数再从开头移入。
    编写一个函数实现以上功能,在主函数中输入 n 个整数并输出调整后的 n 个数。

    */
    int i, m, n;
    int a[80];
    printf(\"input n,m:\");
    scanf(\"%d%d\", &n, &m);
    printf(\"input %d number:\\n\", n);
    for (i = 0; i < n; i++)
        scanf(\"%d\", &a[i]);
    mov(a, n, m);
    printf(\"After move: \");
    for (i = 0; i < n; i++)
        printf(\"%d \", a[i]);
    printf(\"\\n\");
    return 0;
}
/*函数mov(x,m)实现循环移动的功能,函数形参x的类型是整型指针,形参n和m的类型是int, 函数的类型是void。 */
void mov(int *x, int n, int m)
{
    int i, j, k;
    for (i = 1; i <= m; i++)
    {
        k = x[n - 1];
        for (j = n - 1; j > 0; j--)
            x[j] = x[j - 1];
        x[0] = k;
    }
}

运行结果:

\"浙大版《C语言程序设计》第四版(何钦铭颜晖)

题目4:报数:有 n 个人图成一圈,按顺序从 1 到 n 编好号。从第一个人开始报数,报到 m(m

答案代码:

#include 

int main(void)
{

    // 习题(8.3.4)
    /*
    报数:有 n 个人图成一圈,按顺序从 1 到 n 编好号。从第一个人开始报数,报到 m(m

运行结果:

\"浙大版《C语言程序设计》第四版(何钦铭颜晖)

题目5:使用函数实现字符串复制:输入一个字符串 t 和一个正整数 m, 将字符串 t 中从第 m 个字符开始的全部字符复制到字符串 s 中,再输出字符串 s 。要求自定义并调用函数 void strmcpy(char *s, char *t, int m)。试编写相应程序。

答案代码:

#include 
#include 
int main(void)
{

    // 习题(8.3.5)
    /*
    使用函数实现字符串复制:输入一个字符串 t 和一个正整数 m, 将字符串 t 中从第 m 个字符开始的全部字符复制到字符串 s 中,再输出字符串 s 。
    要求自定义并调用函数 void strmcpy(char *s, char *t, int m)。

    */
    char s[80], t[80];
    int m;
    void strmcpy(char *s, char *t, int m);
    printf(\"input string t:\\n\");
    gets(t);
    printf(\"input number m:\");
    scanf(\"%d\", &m);
    getchar();
    if (strlen(t) < m)
        printf(\"error input\");
    else
    {
        strmcpy(s, t, m);
        puts(s);
    }
    return 0;
}
void strmcpy(char *s, char *t, int m)
{
    t = t + m - 1;
    while (*t != \'\\0\')
    {
        *s = *t;
        s++;
        t++;
    }
    *s = \'\\0\';
}

运行结果:

\"浙大版《C语言程序设计》第四版(何钦铭颜晖)

题目6:删除字符:输入一个字符串,再输入一个字符 ch , 将字符串中所有的 ch 字符删除后输出该字符串。要求定义和调用函数 delchar(s, c),该函数将字符串 s 中出现的所有 c 字符删除。试编写相应程序。

答案代码:

#include 
#include 
int main(void)
{

    // 习题(8.3.6)
    /*
    删除字符:输入一个字符串,再输入一个字符 ch , 将字符串中所有的 ch 字符删除后输出该字符串。
    要求定义和调用函数 delchar(s, c),该函数将字符串 s 中出现的所有 c 字符删除。

    */
    char c;
    char str[80];
    void delchar(char *str, char c);
    printf(\"input a string:\\n\");
    gets(str);
    printf(\"input a char:\");
    scanf(\"%c\", &c);
    getchar();
    delchar(str, c);
    printf(\"result: \");
    puts(str);
    return 0;
}
void delchar(char *str, char c)
{
    int i, j;
    i = j = 0;
    while (str[i] != \'\\0\')
    {
        if (str[i] != c)
        {
            str[j] = str[i];
            j++;
        }
        i++;
    }
    str[j] = \'\\0\';
}

运行结果:

\"浙大版《C语言程序设计》第四版(何钦铭颜晖)

题目7:字符串排序:输入5个字符串,按由小到大的顺序输出。试编写相应程序。

答案代码:

#include 
#include 
int main(void)
{

    // 习题(8.3.7)
    /*
    字符串排序:输入5个字符串,按由小到大的顺序输出。

    */

    int i, j, index;
    char sx[5][80], stemp[80];
    printf(\"input 5 string:\\n\");
    for (i = 0; i < 5; i++)
        scanf(\"%s\", sx[i]);
    for (i = 1; i < 4; i++)
    {
        index = i;
        for (j = i + 1; j < 5; j++)
            if (strcmp(sx[j], sx[index]) < 0)
                index = j;
        strcpy(stemp, sx[i]);
        strcpy(sx[i], sx[index]);
        strcpy(sx[index], stemp);
    }
    printf(\"after sorted:\\n\");
    for (i = 0; i < 5; i++)
        puts(sx[i]);
    return 0;
}

运行结果:

\"浙大版《C语言程序设计》第四版(何钦铭颜晖)

题目8:判断回文:判断输入的一串字符是否为“回文”。所谓“回文”是指顺读和倒读都一样的字符串。如 \"XYZYX\" 和 \"xyzzyx\" 都是回文。试编写相应程序。

答案代码:

#include 

int main(void)
{

    // 习题(8.3.8)
    /*
    判断回文:判断输入的一串字符是否为“回文”。所谓“回文”是指顺读和倒读都一样的字符串。
    如 \"XYZYX\" 和 \"xyzzyx\" 都是回文。

    */

    char s[80];
    int mirror(char *p);
    printf(\"input a string:\");
    gets(s);
    if (mirror(s) != 0)
        printf(\"YES\\n\");
    else
        printf(\"NO\\n\");
    return 0;
}
int mirror(char *p)
{
    char *q;
    q = p;
    while (*q != \'\\0\')
        q++;
    q--;
    while (p < q)
    {
        if (*p != *q)
            return 0;
        p++;
        q--;
    }
    return 1;
}

运行结果:

\"WX20220413-143011@2x\"

题目9:分类统计字符个数:输入一行文字,统计其中的大写字母、小写字母、空格、数字以及其他字符各有多少。试编写相应程序。

答案代码:

#include 

int main(void)
{

    // 习题(8.3.9)
    /*
    分类统计字符个数:输入一行文字,统计其中的大写字母、小写字母、空格、数字以及其他字符各有多少。

    */

    char s[80];
    char *p;
    int blank, digit, lower, other, upper;
    gets(s);
    upper = lower = blank = digit = other = 0;
    for (p = s; *p != \'\\0\'; p++)
        if (*p >= \'A\' && *p <= \'Z\')
            upper++;
        else if (*p >= \'a\' && *p <= \'z\')
            lower++;
        else if (*p >= \'0\' && *p <= \'9\')
            digit++;
        else if (*p == \' \')
            blank++;
        else
            other++;
    printf(\"upper: %d lower: %d blank: %d digit: %d other: %d\\n\", upper, lower, blank, digit, other);
    return 0;
}

运行结果:

\"WX20220413-145724@2x\"

题目10:(选做)输出学生成绩(动态分配):输入学生人数后输入每个学生的成绩,最后输出学生的平均成绩、最高成绩和最低成绩。要求使用动态内存分配来实现。试编写相应程序。

答案代码:

#include 
#include 
int main(void)
{

    // 习题(8.3.10)
    /*
    (选做)输出学生成绩(动态分配):输入学生人数后输入每个学生的成绩,最后输出学生的平均成绩、最高成绩和最低成绩。
    要求使用动态内存分配来实现。

    */

    int n, i;
    float *p, sum, max, min, avg;
    printf(\"input students\' number n: \");
    scanf(\"%d\", &n);
    /*为数组p动态分配n个浮点数float 类型大小的空间*/
    if ((p = (float *)calloc(n, sizeof(float))) == NULL)
    {
        printf(\"Not able to allocate memory.\\n\");
        exit(1);
    }
    sum = 0.0;
    max = -1; /*初始化*/
    min = 1000;
    printf(\"input %d students\' scores: \", n); /*提示输入n个整数*/
    for (i = 0; i < n; i++)
    {
        scanf(\"%f\", p + i);
        sum = sum + *(p + i);
        if (min > *(p + i))
            min = *(p + i);
        if (max < *(p + i))
            max = *(p + i);
    }
    avg = sum / n;
    printf(\"The avg is %f, max is %f, min is %f\\n\", avg, max, min);
    free(p); /*释放动态分配的空间*/
    return 0;
}

运行结果:

\"WX20220413-150338@2x\"

ItVuer - 免责声明 - 关于我们 - 联系我们

本网站信息来源于互联网,如有侵权请联系:561261067@qq.com

桂ICP备16001015号