关于c:浙大版C语言程序设计第四版何钦铭颜晖-第7章-数组-课后习题答案

8次阅读

共计 9587 个字符,预计需要花费 24 分钟才能阅读完成。

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

一、选择题
1. 假设 int 类型变量占用两个字节,则以下定义的数组 a 在内存中所占字节数是()。

int a[10]={10,2,4};

A. 20
B.10
C.6
D.3

答:A

解析:题目中,依据 int a[10],示意定义了数组的长度是 10,每个变量占用两个字节,一共就是 20 个字节。

2. 若有定义:int a[2][3];以下选项中对数组元素正确援用的是()。
A. a[2][0]
B. a[2][3]
C. a[0][3]
D. a[1>2][1]

答:D

解析:

题目中定义了二维数组 a[2][3],那么该数组示意一个 2 行 3 列的矩阵,行的下标(第一个下标)的取值范畴就是 0,1,列的下标(第二个下标)的取值范畴就是 0,1,2。这里是有选项 D,a[1>2][1],实际上是 a[0][1],下标的数值没有越界。

3. 以下程序段的输入后果是()。

int aa[4][4]={{1,2,3,4},{5,6,7,8},{3,9,10,2},{4,2,9,6}};
int i, s=0;
for(i=0; i<4; i++)
    s+=aa[i][3];
printf("%d\n", s);

A.11
B.19
C.13
D.20

答:D

解析:

题目中定义的是二维数组,4X4 的矩阵。

1    2 3 4
5 6 7 8
3 9 10 2
4 2 9 6

循环中 i 的值示意行,从 0 取到 3,而列的下标固定是 3,所以示意累加最初一列的值。4+8+2+6 = 20。

4. 设有数组定义:char array[]=”China” ; 则数组 array 所占的空间为()字节。

A.4 个
B.5 个
C.6 个
D.7 个

答:C

解析:在题目的定义形式中,零碎会主动在数组最初退出一个 ’\0’,示意字符数组的完结,因而数组的长度就是 6 个字节。

5. 下述对字符数组的形容中谬误的是()。

A. 字符数组能够寄存字符串

B. 字符数组中的字符串能够整体输出、输入

C. 能够在赋值语句中通过赋值运算符 ”=” 对字符数组整体赋值

D. 不能够用关系运算符对字符数组中的字符串进行比拟

答:C

解析:

选项 A 正确,在 C 语言中能够将字符串作为一个非凡的一位字符数组来解决。例如:char array[]=”China” ;

选项 B 正确,因为字符数组中间接应用数组名称时数组会进化为指针而且字符串结尾会有“\0”,指针遇到“\0”会完结输出或者输入。用到的代码是:char ch[100]; gets(ch); // 整体输出 puts(ch); 整体输入。(同时这里提个醒字符数组能够进行整体的输入输出,然而整型输入是不能够进行的整体输入输出)

选项 C 不正确。在赋值语句中通过赋值运算符 ”=” 对字符数组整体赋值,则就须要用到字符数组名,而对字符数组名进行操作时其会进化为常量指针,而进行赋值时左值必须是能够批改的变量。所以谬误。

选项 D 正确。数组名会进化为指针,所以比拟的其实就是指针所指向的内存地址的大小,这个跟比拟字符串的大小没有关系。

6. 对于以下定义,正确的叙述为()。

char x[]="abcdefg", char y[]={'a','b','c','a','e','f','g'};

A. 数组 x 和数组 y 等价
B. 数组 x 的长度大于数组 y 的长度
C. 数组 x 和数组 y 的长度雷同
D. 数组 x 的长度小于数组 y 的长度

答:B

解析:

char x[]=”abcdefg”,数组 x 的长度是 8,7 个字符,以及零碎主动加的 ‘\0’。

char y[]={‘a’,’b’,’c’,’a’,’e’,’f’,’g’},数组 y 的长度是 7。

char x[]=”abcdefg”;
// 等价于
char x[]={‘a’,’b’,’c’,’d’,’e’,’f’,’g’,’\0′};

二、填空题
1. 写出以下程序段的输入后果:输出 4, 则输入(),输出 5,则输入(),输出 12,则输入(),输出 -5,则输入()。

int i, n = 5, x, a[10] = {1, 3, 5, 7, 9};
scanf("%d", &x);
    for (i = n - 1; i >= 0; i--)
        if (x < a[i])
            a[i + 1] = a[i];
        else
            break;
    a[i + 1] = x;
    n++;
    printf("%d", i + 1);

答:2 3 5 0

解析:

循环中 i 的取值为 4,3,2,1,0。当取到 -1 时完结 for 循环。循环里就是在比拟 x 和 a[i] 的大小。

第一个空,当 x 的值为 4 时,下标 i 的值为 1,对应数组中的 3,if 语句不成立,break 了循环,此时 i 的值为 1。最终打印 i+ 1 的值就是 2。

第二个空,当 x 的值为 5 时,下标 i 的值为 2,对应数组中的的 5,if 语句不成立,break 了循环,此时 i 的值为 2。最终打印 i+1 的值就是 3。

第三个空,当 x 的值为 12 时,下标 i 的值为 4,对应数组中的 9,if 语句不成立,break 循环,此时 i 的值为 4。最终打印 i+1 的值就是 5。

第四个空,当 x 的值为 -5 时,整个数组中的所有值都比 x 大,循环完结时 i 的值为 -1。最终打印 i+1 的值就是 0。

2. 求数组中相邻元素之和。将数组 x 中相邻两个元素的和顺次寄存到 a 数组中。请填空。

    int i, a[9], x[10];
    for (i = 0; 1 < 10; i++)
        scanf("%d", &x[i]);
    for (_______; i < 10; i++)
        a[i - 1] = _______ + x[i];

答:i = 1 x[i – 1]

解析:因为要示意数组中相邻的元素,能够应用 x[i-1] 和 x[i],所以在第二个 for 循环中,i 的初始值为 1。

3. 简化的插入法排序。将一个给定的整数 x 插到已按升序排列的整型数组 a 中,使 a 数组依然按升序排列。假设变量都已正确定义并赋值,请填空。

    for (i = 0; i < n; i++)
    {if (________)
        {break;}
    }
    for (________)
    {a[j + 1] = a[j];
    }
    ________;
    n++;

答:

x < a[i]

j = n – 1; j >= i; j–

a[i] = x

解析:

这里的思路是:第一个 for 循环,比拟 x 和 数组中的元素,直到 x 大于数组中的某一个元素。而后记录该值的下标。

而后第二个循环将 i 后的每一个元素向后挪动一个地位。

最初将 x 插入到 下表 i 的地位上。

4. 输出 8,以下程序段的输入后果为(),输出 5,输入后果为()。

    int i, max_sum, n, this_sum, a[] = {-1, 3, -2, 4, -6, 1, 6, -1};
    scanf("%d", &n);
    max_sum = this_sum = 0;
    for (i = 0; i < n; i++)
    {this_sum += a[i];
        if (this_sum > max_sum)
            max_sum = this_sum;
        else if (this_sum < 0)
            this_sum = 0;
    }
    printf("%d\n", max_sum);

答:7 5

解析:

第一空,当 n = 8 时,for 循环遍历了数组中的所有的元素,下标从 0 到 7。

i = 0 时,循环条件成立,进入循环,this_sum 累加完 a[0] = -1,值为 -1,执行 else if 的内容,this_sum 的值被批改为 0。

i = 1 时,循环条件成立,进入循环,this_sum 累加完 a[1] = 3,值为 3,执行 if 的内容,max_sum 的值为 3。

i = 2 时,循环条件成立,进入循环,this_sum 累加完 a[2] = -2,值为 1,不执行 if 也不执行 else if,而后下一次循环。

i = 3 时,循环条件成立,进入循环,this_sum 累加完 a[3] = 4,值为 5,执行 if 的内容,max_sum 的值为 5。

i = 4 时,循环条件成立,进入循环,this_sum 累加完 a[4] = -6,值为 -1,执行 else if 的内容,this_sum 的值被批改为 0。

i = 5 时,循环条件成立,进入循环,this_sum 累加完 a[5] =1,值为 1,不执行 if 也不执行 else if,而后下一次循环。

i = 6 时,循环条件成立,进入循环,this_sum 累加完 a[6]= 6,值为 7,执行 if 的内容,max_sum 的值批改为 7。

i = 7 时,循环条件成立,进入循环,this_sum 累加完 a[7] = -1,值为 6。不执行 if 也不执行 else if。

i = 8 时,完结循环。

第二空,当 n = 5 时,for 循环遍历了下标从 0 到 4。数值的遍历从 -1 到 -6。剖析过程如上。

5. 输出 1 2 3 4 5 6,则程序段 A 的输入后果是(),程序段 B 的输入后果是()。

程序段 A

int i, j, table[3][2];
    for (i = 0; i < 3; i++)
        for (j = 0; j < 2; j++)
            scanf("%d", &table[i][j]);
    for (i = 0; i < 3; i++)
        for (j = 0; j < 2; j++)
            printf("%d#", table[i][j]);

程序段 B

    int i, j, table[3][2];
    for (j = 0; j < 2; j++)
        for (i = 0; i < 3; i++)
            scanf("%d", &table[i][j]);
    for (i = 0; i < 3; i++)
        for (j = 0; j < 2; j++)
            printf("%d#", table[i][j]);

答:

1#2#3#4#5#6#

1#4#2#5#3#6#

剖析:

6. 判断二维数组是否对称。查看二维数组 a 是否对称,即对所有 i,j 都满足 a[i][j]a[j][i] 的值相等。假设变量都已正确定义并赋值,请填空。

    found = 1;
    for (i = 0; i < n; i++)
    {for (j = 0; j < n; j++)
        {if (___________)
            {
                ___________;
                break;
            }
        }
        if (___________)
            break;
    }
    if (found != 0)
        printf("该二维数组对称 \n");
    else
        printf("该二维数组不对称 \n");

答:

a[i][j] != a[j][i]

found = 0

found == 0

解析:

由打印输出条件能够看的进去,found 的值为 1 时,是对称数组,found 为 0 时,是非对称数组。

所以第一个空,填入 a[i][j] != a[j][i],他俩的值不想等,那么就把 found 批改为 0。所以第二个空为 found = 0,执行了 break,完结这个 j 这个循环。第三个空要判断 found 的值是否为 0,如果是 0 就完结整个 i 的循环,因为一旦 found 被批改为 0,那么这个数组就不是对称的了,前面的其余数值也不须要判断了。

7. 字符串复制。将字符串 str1 的内容复制到字符串 str2。假设变量都已正确定义并赋值,请填空。

    i = 0;
    while (___________)
    {
        ___________;
        i++;
    }
    ___________;

答:

str1[i] != ‘\0’

str2[i] = str1[i]

str2[i] = ‘\0’

解析:这里循环复制就能够了。只不过应用 char[] 数组操作字符串,最初一个字符存储 ‘\0’。

8. 删除字符串中的空格。将字符串 str 中的所有空格都删除。假设变量都已正确定义并赋值,请填空。

    i = j = 0;
    while (__________)
    {if (__________)
        {str[j] = str[i];
            __________
        }
        i++;
    }
    __________

答:

str[i] != ‘\0’

str[i] != ‘ ‘

j++;

str[j] = ‘\0’;

解析:

循环遍历字符串,通过两个下标 i 和 j 来操作。i 用于遍历字符串中的每个字符,j 用于存储非空格的字符。如果这个字符不是空格,就复制到 j 对应的地位上。最初要记得开端加 ‘\0’。

三、程序设计题
题目 1:抉择法排序。输出一个正整数 n (1<n≤10),再输出 n 个整数,将它们从大到小排序后输入。试编写相应程序。

答案代码:

#include <stdio.h>
int max(int a[], int len);
int main()
{// 习题(7.3.1)
    /*
    抉择法排序。输出一个正整数 n (1<n≤10),再输出 n 个整数,将它们从大到小排序后输入。*/

    // 数据存入
    int i, n;
    printf("input n number:");
    scanf("%d", &n);
    int a[n];
    for (i = 0; i < n; i++)
    {scanf("%d", &a[i]);
    }

    int len = sizeof(a) / sizeof(a[0]);
    // 抉择排序
    for (i = len - 1; i > 0; i--)
    {int maxid = max(a, i + 1);
        int t = a[maxid];
        a[maxid] = a[i];
        a[i] = t;
    }

    for (i = len - 1; i >= 0; i--)
    {printf("%d", a[i]);
    }
    printf("\n");
    return 0;
}
int max(int a[], int len) // 找出数组中最大数
{
    int i, maxid = 0;
    for (i = 1; i < len; i++)
    {if (a[i] > a[maxid])
        {maxid = i;}
    }
    return maxid;
}

运行后果:

题目 2:求一批整数中呈现最多的数字。输出一个正整数 n(1<n≤1 000),再输出 n 个整数,剖析每个整数的每一位数字,求呈现次数最多的数字。例如输出 3 个整数 1234、2345、3456,其中呈现次数最多的数字是 3 和 4,均呈现了 3 次。试编写相应程序。

答案代码:

#include <stdio.h>
int main()
{// 习题(7.3.2)
    /*
    求一批整数中呈现最多的数字。输出一个正整数 n(1<n≤1 000),再输出 n 个整数,剖析每个整数的每一位数字,求呈现次数最多的数字。例如输出 3 个整数 1234、2345、3456,其中呈现次数最多的数字是 3 和 4,均呈现了 3 次。*/

    int n, i, max = 0, temp, time[10] = {0};
    printf("input n:");
    scanf("%d", &n);
    printf("input %d integers:", n);
    for (i = 0; i < n; i++)
    {scanf("%d", &temp);
        while (temp != 0)
        {time[temp % 10]++;
            temp /= 10;
        }
    }
    for (i = 0; i < 10; i++)
    {if (max < time[i])
            max = time[i];
    }
    printf("呈现最多次数 %d 次的数字是:", max);
    for (i = 0; i < 10; i++)
        if (time[i] == max)
            printf("%d", i);

    printf("\n");
    return 0;
}

运行后果:

再输出一组:

题目 3:判断上三角矩阵。输出一个正整数 n(1≤n≤6)和 n 阶方阵 a 中的元素,如果 a 是上三角矩阵,输入“YES”,否则,输入“NO”。上三角矩阵指主对角线以下的元素都为 0 的矩阵,主对角线为从矩阵的左上角至右下角的连线。试编写相应程序。

答案代码:

#include <stdio.h>
int main()
{// 习题(7.3.3)
    /*
    判断上三角矩阵。输出一个正整数 n(1≤n≤6)和 n 阶方阵 a 中的元素,如果 a 是上三角矩阵,输入“YES",否则,输入“NO"。上三角矩阵指主对角线以下的元素都为 0 的矩阵,主对角线为从矩阵的左上角至右下角的连线。*/
    int a[6][6], flag, i, j, n;
    printf("input n:");
    scanf("%d", &n);
    printf("input array: \n");
    for (i = 0; i < n; i++)
        for (j = 0; j < n; j++)
            scanf("%d", &a[i][j]);
    flag = 1;
    for (i = 0; i < n; i++)
        for (j = 0; j < i; j++)
            if (a[i][j] != 0)
                flag = 0;
    if (flag)
        printf("YES\n");
    else
        printf("NO\n");
    return 0;
}

运行后果:

题目 4:求矩阵各行元素之和。输出 2 个正整数 m 和 n(1≤m≤6,1≤n≤6),而后输出矩阵 a(m 行 n 列)中的元素,别离求出各行元素之和,并输入。试编写相应程序。

答案代码:

#include <stdio.h>
int main()
{// 习题(7.3.4)
    /*
    求矩阵各行元素之和。输出 2 个正整数 m 和 n(1≤m≤6,1≤n≤6),而后输出矩阵 a(m 行 n 列)中的元素,别离求出各行元素之和,并输入。*/

    int a[6][6], i, j, m, n, sum;
    printf("input m,n :");
    scanf("%d%d", &m, &n);
    printf("input array:\n");
    for (i = 0; i < m; i++)
        for (j = 0; j < n; j++)
            scanf("%d", &a[i][j]);
    for (i = 0; i < m; i++)
    {
        sum = 0;
        for (j = 0; j < n; j++)
            sum = sum + a[i][j];
        printf("sum of row %d is %d\n", i, sum);
    }
    return 0;
}

运行后果:

题目 5:找鞍点。输出 1 个正整数 n(1≤n≤6)和 n 阶方阵 a 中的元素,假如方阵 a 最多有 1 个鞍点,如果找到 a 的鞍点,就输入其下标,否则,输入“NO”。鞍点的元素值在该行上最大,在该列上最小。试编写相应程序。

答案代码:

#include <stdio.h>
int main()
{// 习题(7.3.5)
    /*
    找鞍点。输出 1 个正整数 n(1≤n≤6)和 n 阶方阵 a 中的元素,假如方阵 a 最多有 1 个鞍点,如果找到 a 的鞍点,就输入其下标,否则,输入“NO"。鞍点的元素值在该行上最大,在该列上最小。*/

    int flag, i, j, k, row, col, n, a[6][6];
    printf("input n:");
    scanf("%d", &n);
    printf("input array:\n");
    for (i = 0; i < n; i++)
        for (j = 0; j < n; j++)
            scanf("%d", &a[i][j]);
    for (i = 0; i < n; i++)
    {
        flag = 1;
        col = 0;
        for (j = 0; j < n; j++)
            if (a[i][col] < a[i][j])
                col = j;
        for (k = 0; k < n; k++)
            if (a[i][col] > a[k][col])
            {
                flag = 0;
                break;
            }
        if (flag)
        {
            row = i;
            break;
        }
    }
    if (flag)
        printf("a[%d][%d]=%d\n", row, col, a[row][col]);
    else
        printf("NO\n");
    return 0;
}

运行后果:

再输出一组:

题目 6:统计大写辅音字母。输出一个以回车完结的字符串(少于 80 个字符),统计并输入其中大写辅音字母的个数。大写辅音字母是指除 ‘A’,’E’,’I’,’O’,‘U’ 以外的大写字母。试编写相应程序。

答案代码:

#include <stdio.h>
int main()
{// 习题(7.3.6)
    /*
    统计大写辅音字母。输出一个以回车完结的字符串(少于 80 个字符),统计并输入其中大写辅音字母的个数。大写辅音字母是指除 'A','E','T','O','U' 以外的大写字母。*/

    int count, i;
    char ch, str[80];
    printf("input a string:");
    i = 0;
    while ((ch = getchar()) != '\n')
    {str[i++] = ch;
    }
    str[i] = '\0';
    count = 0;
    for (i = 0; str[i] != '\0'; i++)
        if (str[i] <= 'Z' && str[i] > 'A' && str[i] != 'E' && str[i] != 'I' && str[i] != 'O' && str[i] != 'U')
            count++;
    printf("count = %d\n", count);
    return 0;
}

运行后果:

题目 7:字符串替换。输出一个以回车完结的字符串(少于 80 个字符),将其中的大写字母用上面列出的对应大写字母替换,其余字符不变,输入替换后的字符串。试编写相应程序。
原字母对应字母
A→Z
B→Y
C→X
D→W

X→C
Y→B
Z→A

答案代码:

#include <stdio.h>
int main()
{// 习题(7.3.7)
    /*
    字符串替换。输出一个以回车完结的字符串(少于 80 个字符),将其中的大写字母用上面列出的对应大写字母替换,其余字符不变,输入替换后的字符串。试编写相应程序。原字母对应字母
    A→Z
    B→Y
    C→X
    D→W
    ...
    X→C
    Y→B
    Z→A

    */

    int i;
    char ch, str[80];
    printf("input a string:");
    i = 0;
    while ((ch = getchar()) != '\n')
    {str[i++] = ch;
    }
    str[i] = '\0';
    for (i = 0; str[i] != '\0'; i++)
        if (str[i] <= 'Z' && str[i] >= 'A')
            str[i] = 'A' + 'Z' - str[i];
    printf("After replaced:");
    for (i = 0; str[i] != '\0'; i++)
        putchar(str[i]);
    putchar('\n');
    return 0;
}

运行后果:

题目 8:字符串转换成十进制整数。输出一个以字符“#”完结的字符串,滤去所有的非十六进制字符(不分太小写),组成一个新的示意十六进制数字的字存串,而后将其转换为十进制数后输入。如果过滤后字符串的首字符为“-“代表该数是正数。试编写相应程序。

答案代码:

#include <stdio.h>
int main()
{// 习题(7.3.2)
    /*
    求一批整数中呈现最多的数字。输出一个正整数 n(1<n≤1 000),再输出 n 个整数,剖析每个整数的每一位数字,求呈现次数最多的数字。例如输出 3 个整数 1234、2345、3456,其中呈现次数最多的数字是 3 和 4,均呈现了 3 次。*/

    char str_old[81], str_new[81];
    int i = 0, j, flag = 0, temp; // flag 用来示意是否有负号存在,0 示意正数,1 示意负数
    long sum = 0;
    printf("input s string:");
    while ((str_old[i] = getchar()) != '#')
        i++; // 输出一个以 '#' 完结的非空字符串

    str_old[i] = '\0';

    for (i = 0; str_old[i] != '\0'; i++)
        if (str_old[i] == '-')
        {
            temp = i;
            break;
        } // 找到第一个 '-' 呈现的地位,用 temp 保留

    for (i = 0; i < temp; i++)
    {if ((str_old[i] >= '0' && str_old[i] <= '9') || (str_old[i] >= 'a' && str_old[i] <= 'f') || (str_old[i] >= 'A' && str_old[i] <= 'F'))
        {
            flag = 1;
            break;
        }
    } // 遍历字符串至 temp, 如果第一个 '-' 之前存在十六进制数字,那么 '-' 有效,该数为正

    for (i = 0, j = 0; str_old[i] != '\0'; i++)
    {if ((str_old[i] >= '0' && str_old[i] <= '9') || (str_old[i] >= 'a' && str_old[i] <= 'f') || (str_old[i] >= 'A' && str_old[i] <= 'F'))
        {str_new[j] = str_old[i];
            j++;
        }
    } // 滤去所有与十六进制数无关的字符

    str_new[j] = '\0';

    for (j = 0; str_new[j] != '\0'; j++)
    {if (str_new[j] >= '0' && str_new[j] <= '9')
            sum = 16 * sum + str_new[j] - '0';
        else if (str_new[j] >= 'a' && str_new[j] <= 'f')
            sum = 16 * sum + str_new[j] - 'a' + 10;
        else if (str_new[j] >= 'A' && str_new[j] <= 'F')
            sum = 16 * sum + str_new[j] - 'A' + 10;
    } // 十六进制转化为十进制数

    if (flag == 0)
        sum = -sum;

    printf("%ld\n", sum);

    return 0;
}

运行后果:

正文完
 0