• 抬起头,继续前进吧,去把这个不完美的故事,变成你成所期望的样子
  • 登山路上我们会放弃很多东西,但这些被我们丢掉在我们登上山顶之际,都会一一回来
  • 不论开发还是逆向,数学水平的高低直接决定了”你的饭碗里有没有肉”
  • 万丈高楼平地起,勿在浮沙筑高台

《C语言程序设计:现代方法》第八章练习

C 菜鸟 2年前 (2018-02-24) 18626次浏览 已收录 0个评论
[隐藏]

        本篇为菜鸟在学习《C 语言程序设计:现代方法》中第八章数组时做的练习题,如果有错误或疑问的话,欢迎大家指正~

1、重复数字 1

修改程序 repdigit.c,要求修改后的程序可以显示出重复的数字(如果有的话)
Enter a number: 939577
Repeated digit(s): 7 9
答:

#include <stdio.h>

#define TRUE 1
#define FALSE 0
#define N 10 

typedef int Bool;

main()
{
    Bool digit_seen[N] = {0};
    int digit, sameDigit = N, i;
    long int n;

    printf("Enter a number: ");
    scanf("%ld", &n);

    while (n > 0) {
        digit = n % N;
        if (digit_seen[digit]) {
            digit_seen[digit] = digit;
            sameDigit--;
        } else {
            digit_seen[digit] = TRUE;
        }
        n /= N;
    }

    if (sameDigit < N) {
        printf("Repeated digit(s):");
        for (i = 0; i < N; i++) {
            if (digit_seen[i] > 1) {
                printf(" %d", digit_seen[i]);
            }
        }
        printf("\n\n");
    } else {
        printf("No repeated digit\n\n");
    }

    return 0;
}

2、重复数字 2

修改程序 repdigit.c,要求修改后的程序可以显示出一张列表,表内显示出每种数字在数中出现的次数
Enter a number: 41271092
Digit: 0 1 2 3 4 5 6 7 8 9
Occurrences: 1 2 2 0 1 0 0 1 0 1

#include <stdio.h>

#define N 10

typedef int Bool;

main()
{
    Bool digit_seen[N] = {0};
    int digit, i;
    long int n;

    printf("Enter a number: ");
    scanf("%ld", &n);

    while (n > 0) {
        digit = n % N;
        digit_seen[digit]++;
        n /= N;
    }

    printf("Digit:\t\t0 1 2 3 4 5 6 7 8 9\n");
    printf("Occurrences:\t");
    for (i = 0; i < N; i++) {
        printf("%d ", digit_seen[i]); 
    }
    printf("\n");

    return 0;
}

3、重复数字 3

修改程序 repdigit.c,要求修改后的程序可以让用户录入多于一个的数进行重复数字的判断。当用户录入的数小于等于 0 时,程序终止
答:

#include <stdio.h>

#define TRUE 1
#define FALSE 0
#define N 10

typedef int Bool;

main()
{
    Bool digit_seen[N] = {0};
    long int number_array[N];
    int digit, n, i, numberCounter;

    printf("Enter numbers: ");
    for (i = 0; ;i++) {
        scanf("%ld", &number_array[i]);
        if (number_array[i] <= 0) {
            break;
        }
        numberCounter++;
    }

    if (!numberCounter) {
        return -1;
    }
    for (i = 0; i < numberCounter; i++) {
        n = number_array[i];
        while (n > 0) {
            digit = n % 10;
            if (digit_seen[digit]) {
                break;
            }
            digit_seen[digit] = TRUE;
            n /= 10;
        }
    }

    if (n > 0) {
        printf("Repeated digit\n");
    } else {
        printf("No repeated digit\n");
    }

    return 0;
}

4、数组长度

表达式 sizeof(a) / sizeof(a[0]) 进行数组个数计算。表达式 sizeof(a) / sizeof(t) 也可以完成同样的工作,其中 t 表示数组 a 中的元素类型,但这被认为是一种较差的技术。为什么?
答:因为如果更改数组的声明类型时,也要更改表达式 size(a) / sizeof(t),而表达式 sizeof(a) / sizeof(a[0])不需要修改

5、反向输出

修改程序 reverse.c,利用表达式 sizeof(a) / sizeof(a[0]) (或者这个值的宏)来计算数组的长度
答:

/* Reverses a series of numbers */
#include <stdio.h>

#define A_ARRAY_SIZE (sizeof(a) / sizeof(a[0]))

main()
{
    int a[10], i;

    printf("Enter 10 number: ");
    for (i = 0; i < A_ARRAY_SIZE; i++) {
        scanf("%d", &a[i]);
    }

    printf("Inreverse order:");
    for (i = A_ARRAY_SIZE - 1; i >= 0; i--) {
        printf(" %d", a[i]);
    }
    printf("\n");
    
    return 0;
}

6、利息计算

修改 interest.c,使得修改后的程序可以每月整合一次利息,而不再是每年整合一次利息。程序的输出格式不用改变,余额应该始终按每年一次的间隔显示
答:

/* Prints a table of sompound interest */
#include <stdio.h>

#define NUM_RATES (sizeof(value) / sizeof(value[0]))
#define INITIAL_BALANCE 100.00

main()
{
	int i, low_rate, num_years, year, j;
	float value[5];

	printf("Enter interest rate: ");
	scanf("%d", &low_rate);
	printf("Enter number of years: ");
	scanf("%d", &num_years);

	printf("\nYears");
	for (i = 0; i < NUM_RATES; i++) {
		printf("%8d%% ", (low_rate + i));
		value[i] = INITIAL_BALANCE;
	}
	printf("\n");

	for (year = 1; year <= num_years; year++) {
		printf("%3d   ", year);
		for (i = 0; i < NUM_RATES; i++) {
			for (j = 0; j <= 12; j++) {
				value[i] += (low_rate + i) / 100.0 * value[i];
			}
			printf("%10.2f", value[i]);
		}
		printf("\n");
	}

	return 0;
}

7、B1FF 公告

在线运动的名人之一是一个称为 B1FF 的家伙,他在编写消息上有一种独一无二的方法。下面是一条典型的 B1FF 公告:
H3Y DUD3, C 15 R1LLY C00L!!!!!!!!!!
编写一个”B1FF 过滤器”,它可以读取用户录入的消息并且把此消息翻译成 B1FF 的表达风格:
Enter message: Hey dude, C is rilly cool
In B1FF-speak: H3Y DUD3, C 15 R1LLY C00L!!!!!!!!!!
程序需要把消息转换成大写字母,用数字代替特定的字母(A-4,B-8,E-3,I-1,O-0,S-5),然后添加 10 个感叹号。
提示:在字符数组中存储原始消息,然后从数组头开始逐个翻译并且显示字符
答:

#include <stdio.h>
#include <ctype.h>

main()
{
    int i;
    char a[30]; 
    printf("Enter message: ");
    a[0] = toupper(getchar());
    for (i = 0; a[i] != '\n'; ) {
        a[++i] = toupper(getchar());
    }

    printf("In B1FF-speak: ");
    for (i = 0; a[i] != '\n'; i++) {
        switch(a[i]) {
            case 'A':
                a[i] = '4';
                break;
            case 'B':
                a[i] = '8';
                break;
            case 'E':
                a[i] = '3';
                break;
            case 'I':
                a[i] = '1';
                break;
            case 'O':
                a[i] = '0';
                break;
            case 'S':
                a[i] = '5';
                break;
        }
        putchar(a[i]);
    }
    printf("!!!!!!!!!!\n");

    return 0;
}

8、数组下标

之前介绍过使用字母作为数组下标的方法。请描述下如何使用数字(字符格式的)作为数组下标
答:通过减去’0’来实现。例如,’2’作为下标,实际是十进制数 50 作为下标,’0’十进制数为 48,这样’2′-‘0’就代表以实际 2 作为下标

9、电子数字段

计算器、手表和其他电子设备经常依靠七段显示器进行数值的输出。为了组成数字,这类设备需要打开 7 个显示段中的某些部分,同时还需要关闭 7 个显示段中的其他部分
编号从 0 开始,从最顶端的开始顺时针计数,最中间的段编号为 6
下面是数组可能的样子,其中数组的每一行表示一个数字:
const int segments[10][7] = {{1, 1, 1, 1, 1, 1, 0}, …};
上面已给出第一行的初始化式,请填充余下部分
答:
{…,
{0, 1, 1, 0, 0, 0, 0},
{1, 1, 0, 1, 1, 0, 1},
{1, 1, 1, 1, 0, 0, 1},
{0, 1, 1, 0, 0, 1, 1},
{1, 0, 1, 1, 0, 1, 1},
{1, 0, 1, 1, 1, 1, 1},
{1, 1, 1, 0, 0, 0, 0},
{1, 1, 1, 1, 1, 1, 1},
{1, 1, 1, 1, 0, 1, 1}}

10、数组化简

对练习九中的数组 segments 的初始化式尽可能简化
答:
{{1, 1, 1, 1, 1, 1},
{0, 1, 1},
1, 1, 0, 1, 1, 0, 1,
1, 1, 1, 1, 0, 0, 1,
0, 1, 1, 0, 0, 1, 1,
1, 0, 1, 1, 0, 1, 1,
1, 0, 1, 1, 1, 1, 1,
{1, 1, 1},
1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 0, 1, 1}

知识点:
        数组简化
        1、如果初始化式不大到足以填满整个多维数组,那么把数组中剩余的元素赋值为 0
        2、如果内层的列表不大到足以填满数组的一行,则将此行剩余的元素初始化为 0
        3、可以忽略掉内层的大括号

11、二维数组求和

编写程序,要求此程序可以用来读取一个 5×5 的整数数组,然后显示出每行的求和结果和每列的求和结果
Enter row 1: 8 3 9 0 10
Enter row 2: 3 5 17 1 1
Enter row 3: 2 8 6 23 1
Enter row 4: 15 7 3 2 9
Enter row 5: 6 14 2 6 0

Row toatals: 30 27 40 36 28
Column totals: 34 37 37 32 21
答:

#include <stdio.h>

#define N 5

main()
{
    int a[N][N], i, j, rowSum, columnSum;

    for (i = 0; i < N; i++) {
        printf("Enter row %d: ", (i + 1));
        for (j = 0; j < N; j++) {
            scanf("%d", &a[i][j]);
        }
    }
    printf("\n");

    printf("Row toatals: ");
    for (i = 0; i < N; i++) {
        rowSum = 0;
        for (j = 0; j < N; j++) {
            rowSum += a[i][j];
        }
        printf(" %d", rowSum);
    }
        
    printf("\n");

    printf("Column totals: ");
    for (j = 0; j < N; j++) {
        columnSum = 0;
        for (i = 0; i < N; i++) {
            columnSum += a[i][j];
        } 
        printf(" %d", columnSum);
    }

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

12、成绩计算

修改练习 11,要求修改后的程序可以提示每个学生 5 门测验的成绩,一共有五个学生,然后计算每个学生的 5 门测验的总分和平均分,还要列出每门测验的平均分、最高分和最低分
Student score 1: 89 73 64 58 98
Student score 2: 23 45 89 56 89
Student score 3: 34 58 23 52 10
Student score 4: 99 12 24 89 27
Student score 5: 47 28 39 40 99

The average sorce of every student: 76 60 35 50 50
The all sorce of every student: 382 302 177 251 253
The average sorce of every subject: 58 43 47 59 64
The max sorce of every subject: 99 73 89 89 99
The min sorce of every subject: 23 12 23 40 10
答:

#include <stdio.h>

#define N 5

main()
{
    int a[N][N], i, j, rowSum[N], columnSum[N], minScore[N], maxScore[N];
    
    for (i = 0; i < N; i++) {
        printf("Student score %d: ", (i + 1));
        for (j = 0; j < N; j++) {
            scanf("%d", &a[i][j]);
        }
    }
    printf("\n");
    
    printf("The average sorce of every student: ");
    for (i = 0; i < N; i++) {
        rowSum[i] = 0;
        columnSum[i] = 0;
        maxScore[i] = 0;
        minScore[i] = 1000;
        for (j = 0; j < N; j++) {
            rowSum[i] += a[i][j];
            columnSum[i] += a[j][i];
            if (a[j][i] > maxScore[i]) {
                maxScore[i] = a[j][i];
            } else if (a[j][i] < minScore[i]) {
                minScore[i] = a[j][i];
            }
        }
        printf(" %d", (rowSum[i] / N));
    }
    printf("\n");

    printf("The all sorce of every student: ");
    for (i = 0; i < N; i++) {
        printf(" %d", rowSum[i]);
    }
    printf("\n");

    printf("The average sorce of every subject: ");
    for (i = 0; i < N; i++) {
        printf(" %d", (columnSum[i] / N));
    }
    printf("\n");

    printf("The max sorce of every subject: ");
    for (i = 0; i < N; i++) {
        printf(" %d", maxScore[i]);
    }
    printf("\n");

    printf("The min sorce of every subject: ");
    for (i = 0; i < N; i++) {
        printf(" %d", minScore[i]);
    }
    printf("\n");

    return 0;
}

13、字母随机移动

编写程序,要求此程序可以产生一种贯穿 10×10 数组的随机步。数组将包含字符(初始时所有数组元素为字符’.’)。程序必须是从一个元素随机”走到”另一个元素,对一个元素来说这种走始终向上
、向下、向左或向右。程序访问到的元素将用从 A 到 Z 的字母进行标记,而且是按顺序进行的访问。下面是一个期望输出的示例:

[root@localhost lianxiti_8]# ./tRandAlpha 
A . . . . . . . . . 
B . . . . . . . . . 
C . . . . . . . . . 
D E . . . . . . . . 
G F . . . . . . . . 
H . . . . . . . . . 
I J K L . . . . . . 
. . . M N O P . . . 
. . . V W R Q . . . 
. . . U T S . . . . 

要求:不能超出数组的范围,而且不要选取已经标记了字母的元素。如果 4 个方向都锁定了,则程序必须终止
答:

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

#define NUM_ALPHA 26 
#define NUM_DIRECTION 4
#define TRUE 1
#define FALSE 0
#define N 10

void printArray(char a[][N]){
    int i, j;
    for (i = 0; i < N; i++) {
        for (j = 0; j < N; j++) {
            printf("%c ", a[i][j]);
        }   
        printf("\n");
    }
}

typedef int Bool;

int main()
{
    int n = 1, i = 0, j = 0, direction, iTmp, jTmp;
    const char alpha[NUM_ALPHA] = {'A', 'B', 'C', 'D', 'E', 'F', 'G',
                                   'H', 'I', 'J', 'K', 'L', 'M', 'N', 
                                   'O', 'P', 'Q', 'R', 'S', 'T', 'U', 
                                   'V', 'W', 'X', 'Y', 'Z'};  
    char output[N][N];
    for (i = 0; i < N; i++) {
        for (j = 0; j < N; j++) {
            output[i][j] = '.';
        }
    }
    srand((unsigned) time(0));
    
    i = 0;
    j = 0;
    output[i][j] = 'A';

    while (n < NUM_ALPHA) {
        Bool directionBool[NUM_DIRECTION] = {0};
        iTmp = i;
        jTmp = j;

        for (;;) {
            i = iTmp;
            j = jTmp;
            direction = rand() % NUM_DIRECTION;
            if ((directionBool[0] && directionBool[1] 
            && directionBool[2] && directionBool[3])) {
                printArray(output);
                return 0;
            } else if (directionBool[direction]) {
                continue;
            }

            switch (direction) {
                case 0:
                    i--;
                    break;
                case 1:
                    i++;
                    break;
                case 2:
                    j--;
                    break;
                case 3:
                    j++;
                    break;
            }

            if (j < 0 || i < 0 || j >= N || i >= N 
            || output[i][j] != '.') {
                directionBool[direction] = TRUE;
                continue;
            } else {
                output[i][j] = alpha[n];
                break;
            }
        }
        n++;
    }    
    printArray(output);
    
    return 0;
}

学习心得 , 版权所有丨如未注明 , 均为原创丨本网站采用BY-NC-SA协议进行授权 , 转载请注明《C 语言程序设计:现代方法》第八章练习
喜欢 (2)
[]
分享 (0)
发表我的评论
取消评论
表情 贴图 加粗 删除线 居中 斜体 签到

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址