IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> C语言程序设计 现代设计方法_第8章代码、练习题及编程题答案 -> 正文阅读

[C++知识库]C语言程序设计 现代设计方法_第8章代码、练习题及编程题答案

程序

8.1 reverse.c
程序  数列反向
第一个关于数组的程序要求用户录入一串数,然后按反向顺序输出这些数:
Enter 10 numbers: 34 82 49 102 7 94 23 11 50 31
In reverse order: 31 50 11 23 94 7 102 49 82 34
方法是在读入数时将其存储在一个数组中,然后反向遍历数组,一个接一个地显示出数组元素。换句话说,不会真的对数组中的元素进行反向,只是使用户这样认为。

/* reverse.c (Chapter 8, page 164) */
/* Reverses a series of numbers */

#include <stdio.h>

#define N 10

int main(void)
{
  int a[N], i;

  printf("Enter %d numbers: ", N);
  for (i = 0; i < N; i++)
    scanf("%d", &a[i]);

  printf("In reverse order:");
  for (i = N - 1; i >= 0; i--)
    printf(" %d", a[i]);
  printf("\n");

  return 0;
}

8.1 repdigit.c
程序  检查数中重复出现的数字
接下来这个程序用来检查数中是否有出现多于一次的数字。用户输入数后,程序显示信息Repeated digit 或No Repeated digit:
Enter a number: 28212
Repeated digit
数28212有一个重复的数字(即2),而9357这样的数则没有。程序采用布尔值的数组跟踪数中出现的数字。名为digit_seen 的数组元素的下标索引从0到9,对应于10个可能的数字。最初的时候,每个数组元素的值都为假。(digit_seen 的初始化式为{false} ,这实际上只初始化了数组的第一个元素。但是,编译器会自动把其他元素初始化为0,而0跟false 是相等的。)当给定数n 时,程序一次一个地检查n 的数字,并且把每次的数字存储在变量digit 中,然后用这个数字作为数组digit_seen 的下标索引。如果digit_seen[digit] 为真,那么表示digit 至少在n中出现了两次。另一方面,如果digit_seen[digit] 为假,那么表示digit 之前未出现过,因此程序会把digit_seen[digit] 设置为真并且继续执行。

/* repdigit.c (Chapter 8, page 166) */
/* Checks numbers for repeated digits */

#include <stdbool.h>   /* C99 only */
#include <stdio.h>

int main(void)
{
  bool digit_seen[10] = {false};
  int digit;
  long n;

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

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

8.1 interest.c 20220506
程序  计算利息
下面这个程序显示一个表格,这个表格显示了在几年时间内100美元投资在不同利率下的价值。用户输入利率和要投资的年数。投资总价值每年计算一次,表格将显示出在输入利率和紧随其后的4个更高的利率下投资的总价值。程序会话如下:
Enter interest rate: 6
Enter number of years: 5
Years 6% 7% 8% 9% 10%
1 106.00 107.00 108.00 109.00 110.00
2 112.36 114.49 116.64 118.81 121.00
3 119.10 122.50 125.97 129.50 133.10
4 126.25 131.08 136.05 141.16 146.41
5 133.82 140.26 146.93 153.86 161.05
很明显地,可以使用for 语句显示出第一行信息。第二行的显示有点小窍门,因为它的值要依赖于第一行的数。我们的解决方案是在计算第一行的数时把它们存储到数组中,然后使用数组中的这些值计算第二行的内容。当然,从第三行到最后一行可以重复这个过程。我们总共需要用到两个for 语句,其中一个嵌套在另一个里面。外层循环将从1计数到用户要求的年数,内层循环将从利率的最低值递增到最高值。

/* interest.c (Chapter 8, page 169) */
/* Prints a table of compound interest */

#include <stdio.h>

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

int main(void)
{
  int i, low_rate, num_years, year;
  double 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("%6d%%", 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++) {
      value[i] += (low_rate + i) / 100.0 * value[i];
      printf("%7.2f", value[i]);
    }
    printf("\n");
  }

  return 0;
}

8.2 deal.c 20220506
下面这个程序说明了二维数组和常量数组的用法。程序负责发一副标准纸牌。每张标准纸牌都有一个花色 (梅花、方块、红桃或黑桃)和一个等级 (2、3、4、5、6、7、8、9、10、J、Q、K或A)。程序需要用户指明手里应该握有几张牌:
Enter number of cards in hand: 5
Your hand: 7c 2s 5d as 2h
不能明显地看出如何编写这样一个程序。如何从一副牌中随机抽取纸牌呢?如何避免两次抽到同一张牌呢?下面将分别处理这两个问题。为了随机抽取纸牌,可以采用一些C语言的库函数。time 函数(?26.3节,来自于<time.h> )返回当前的时间,用一个数表示。srand 函数(?26.2节,来自于<stdlib.h> )初始化C 语言的随机数生成器。通过把time 函数的返回值传递给函数srand 可以避免程序在每次运行时发同样的牌。rand 函数(?26.2节,来自于<stdlib.h> )在每次调用时会产生一个看似随机的数。通过采用运算符% ,可以缩放rand 函数的返回值,使其落在0~3(用于表示牌的花色)的范围内,或者是落在0-12(用于表示纸牌的等级)的范围内。
为了避免两次都拿到同一张牌,需要记录已经选择过的牌。为了这个目的,程序将采用一个名为in_hand 的二维数组,数组有4行(每行表示一种花色)和13列(每列表示一种等级)。换句话说,数组中的每个元素对应着52张纸牌中的一张。在程序开始时,所有数组元素都为假。每次随机抽取一张纸牌时,将检查数组in_hand 中的对应元素为真还是为假。如果为真,那么就需要抽取其他纸牌;如果为假,则把true 存储到与这张纸牌相对应的数组元素中,以提醒我们这张纸牌已经抽取过了。
一旦证实纸牌是“新”的(还没有选取过),就需要把牌的等级和花色数值翻译成字符,然后显示出来。为了把纸牌的等级和花色翻译成字符格式,程序将设置两个字符数组(一个用于纸牌的等级,另一个用于纸牌的花色),然后用等级和花色对数组取下标。这两个字符数组在程序执行期间不会发生改变,所以也可以把它们声明为const 。

/* Deals a random hand of cards */
#include <stdbool.h> /* C99 only */
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define NUM_SUITS 4
#define NUM_RANKS 13
int main(void)
{
    bool in_hand[NUM_SUITS][NUM_RANKS] = { false };
    int num_cards, rank, suit;
    const char rank_code[] = { '2','3','4','5','6','7','8',
    '9','t','j','q','k','a' };
    const char suit_code[] = { 'c','d','h','s' };
    srand((unsigned)time(NULL));
    printf("Enter number of cards in hand: ");
    scanf("%d", &num_cards);
    printf("Your hand:");
    while (num_cards > 0) {
        suit = rand() % NUM_SUITS; /* picks a random suit */
        rank = rand() % NUM_RANKS; /* picks a random rank */
        if (!in_hand[suit][rank]) {
            in_hand[suit][rank] = true;
            num_cards--;
            printf(" %c%c", rank_code[rank], suit_code[suit]);
        }
    }
    printf("\n");
    return 0;
}

注意,数组in_hand 的初始化式:bool in_hand[NUM_SUITS][NUM_RANKS] = {false};尽管in_hand 是二维数组,C语言仍允许只使用一对花括号(不过编译器可能会产生警告消息)。跟前面一样,由于我们在初始化式中只给出了一个值,编译器会把其他数组元素填充为值0(假)。

练习题

  1. 前面讨论过,可以用表达式sizeof(a) / sizeof(a[0]) 计算数组元素个数。表达式sizeof(a) / sizeof(t) 也可以完成同样的工作,其中t表示数组a 中元素的类型,但我们认为这是一种较差的方法。这是为什么呢?

Solution
The second expression may not necessarily reflect the type of a value in a. For example, if a was changed from an array of ints to an array of longs, then each instance of sizeof(t) would have to be changed.

  1. “问与答”部分介绍了使用字母 作为数组下标的方法。请描述一下如何使用数字 (字符格式的)作为数组的下标。
Solution
If `c` is a `char` containing a digit character `'5'`:
`digit_count[c - '0'] == digit_count[5]; /* true */`
  1. 声明一个名为weekend 的数组,其中包含7个bool 值。要求用一个初始化式把第一个和最后一个值置为true ,其他值都置为false 。
Solution
int weekend[7] = {1, 0, 0, 0, 0, 0, 1};
  1. (C99)重复练习题3,但这次用指定初始化式。要求初始化式尽可能地简短。
Solution
bool weekend[7] = {[0] = true, [6] = true};
  1. 斐波那契数为0, 1, 1, 2, 3, 5, 8, 13,…,其中每个数是其前面两个数的和。编写一个程序片段,声明一个名为fib_number 的长度为40的数组,并填入前40个斐波那契数。提示 :先填入前两个数,然后用循环计算其余的数。
Solution
int i, fib_numbers[40] = {0, 1};

for (i = 2; i < (int) (sizeof(fib_numbers) / sizeof(fib_numbers[0])); i++)
    fib_numbers[i] = fib_numbers[i-1] + fib_numbers[i-2];
  1. 计算器、电子手表和其他电子设备经常依靠七段显示器 进行数值的输出。为了组成数字,这类设备需要“打开”7个显示段中的某些部分,同时“关闭”其他部分:
    在这里插入图片描述
    假设需要设置一个数组来记住显示每个数字时需要“打开”的显示段。各显示段的编号如下所示:
    在这里插入图片描述
    下面是数组的可能形式,每一行表示一个数字:const int segments[10][7] = {{1, 1, 1, 1, 1, 1, 0}, …}; 上面已经给出了初始化式的第一行,请填充余下的部分。
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}};
  1. 利用8.2节的简化方法,尽可能地缩短(练习题6中)数组segments 的初始化器。
const int segments[10][7] = {{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. 为一个名为temperature_readings 的二维数组编写声明。该数组存储一个月中每小时的温度读数。(简单起见,假定每个月有30天。)数组的每一行对应一个月中的每一天,每一列对应一天中的小时数。
double temperature_readings[30][24] = {0};
  1. 利用练习题8中的数组,编写一段程序计算一个月的平均温度(对一月中的每一天和一天中的每个小时取平均)。
#define DAYS 30
#define HOURS 24
int i, j;
double average = 0.0,
       temperature_readings[DAYS][HOURS];

for (i = 0; i < DAYS; i++) {
    for (j = 0; j < HOURS; j++) {
        average += temperature_readings[i][j];
    }
}
average /= DAYS * HOURS;
  1. 为一个8×8的字符数组编写声明,数组名为chess_board 。用一个初始化式把下列数据放入数组(每个字符对应一个数组元素):
    在这里插入图片描述
char chess_board[8][8] = {{'r', 'n', 'b', 'q', 'k', 'b', 'n', 'r'},
                          {'p', 'p', 'p', 'p', 'p', 'p', 'p', 'p'},
                          {0, '.', 0, '.', 0, '.', 0, '.'},
                          {'.', 0, '.', 0, '.', 0, '.'},
                          {0, '.', 0, '.', 0, '.', 0, '.'},
                          {'.', 0, '.', 0, '.', 0, '.'},
                          {'P', 'P', 'P', 'P', 'P', 'P', 'P', 'P'},
                          {'R', 'N', 'B', 'Q', 'K', 'B', 'N', 'R'}};

11. 为一个8×8的字符数组编写声明,数组名为checker_board。然后用一个循环把下列数据写入数组(每个字符对应一个数组元素):
B R B R B R B R
R B R B R B R B
B R B R B R B R
R B R B R B R B
B R B R B R B R
R B R B R B R B
B R B R B R B R
R B R B R B R B
提示 :如果i+j为偶数,则i行j列的元素为B 。

char checker_board[8][8];
int i, j;

for (i = 0; i < 8; i++) {
    for (j = 0; j < 8; j++) {
        checker_board[i][j] = (i + j) % 2 == 0 ? 'B' : 'R';
    }
}

编程题

  1. 修改8.1节的程序repdigit.c ,使其可以显示出哪些数字有重复(如果有的话):
    Enter a number: 939577
    Repeated digit(s): 7 9
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdbool.h>      /* C99 only */

int main(void) {

    bool digit_seen[10] = { false },
        repeated[10] = { false };
    int digit, i;
    long n;

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

    while (n > 0) {
        digit = n % 10;
        if (digit_seen[digit])
            repeated[digit] = true;
        digit_seen[digit] = true;
        n /= 10;
    }

    printf("Repeated digit(s): ");

    for (i = 0; i < 10; i++) {
        if (repeated[i])
            printf("%d ", i);
    }
    printf("\n");
    return 0;
}
  1. 修改8.1节的程序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
/* Checks numbers for repeated digits */

#include <stdio.h>

int main(void) {

    int digit, i, occurrences[10] = {0};
    long n;

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

    while (n > 0) {
        digit = n % 10;
        occurrences[digit]++;
        n /= 10;
    }
    
    printf("Digit:\t\t 0  1  2  3  4  5  6  7  8  9\n");
    printf("Occurrences:\t");

    for (i = 0; i < 10; i++) {
            printf("%2d ", occurrences[i]);
    }
    printf("\n");
    return 0;
}

  1. 修改8.1节的程序repdigit.c ,使得用户可以录入多个数进行重复数字的判断。当用户录入的数小于或等于0时,程序终止。
/* Checks numbers for repeated digits */

#include <stdio.h>

int main(void) {

    int digit, i, occurrences[10] = {0};
    long n;

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

    if (n <= 0) {
        printf("Digit:\t\t 0  1  2  3  4  5  6  7  8  9\n");
        printf("Occurrences:\t 0  0  0  0  0  0  0  0  0  0\n");
    }

    while (n > 0) {        
        while (n > 0) {
            digit = n % 10;
            occurrences[digit]++;
            n /= 10;
        }
    
        printf("Digit:\t\t 0  1  2  3  4  5  6  7  8  9\n");
        printf("Occurrences:\t");

        for (i = 0; i < 10; i++) {
            printf("%2d ", occurrences[i]);
            occurrences[i] = 0;
        }
        printf("\nEnter a number: ");
        scanf("%ld", &n);
    }
    return 0;
}

  1. 修改8.1节的程序reverse.c ,利用表达式(int)(sizeof(a) / sizeof(a[0])) (或者具有相同值的宏)来计算数组的长度。
/* Reverse a series of numbers */

#include <stdio.h>

#define SIZE (int) (sizeof(a) / sizeof(a[0]))

int main(void) {

    int a[10], i;

    printf("Enter %d numbers: ", SIZE);
    for (i = 0; i < SIZE; i++)
        scanf("%d", &a[i]);

    printf("In reverse order:");
    for (i = SIZE - 1; i >= 0; i--)
        printf(" %d", a[i]);
    printf("\n");

    return 0;
}

  1. 修改8.1节的程序interest.c ,使得修改后的程序可以每月整合一次利息,而不是每年整合一次利息。不要改变程序的输出格式,余额仍按每年一次的时间间隔显示。
/* Prints a table of compound interest */

#include <stdio.h>

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

int main(void) {

    int i, low_rate, num_years, month, year;
    double value[5];

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

    printf("\n Years");
    for (i = 0; i < NUM_RATES; i++) {
        printf("%6d%%", 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 (month = 1; month <= 12; month++)
                value[i] *= (double) ((low_rate + i) / 12.0 / 100.0 + 1.0);
            printf("%7.2f", value[i]);
        }
        printf("\n");
    }
    return 0;
}

  1. 网络新手的原型是一个名为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>

#define MAX_SIZE 100

int main(void) {

    char c, message[MAX_SIZE] = {0};
    int i = 0;

    printf("Enter message: ");
    while((c = getchar()) != '\n' && i < MAX_SIZE)
        message[i++] = c;
    
    printf("In B1FF-speak: ");

    for (i = 0; i < MAX_SIZE; i++) {
        switch (c = toupper(message[i])) {
            case 'A':
                putchar('4');
                break;
            case 'B':
                putchar('8');
                break;
            case 'E':
                putchar('3');
                break;
            case 'I':
                putchar('1');
                break;
            case 'O':
                putchar('0');
                break;
            case 'S':
                putchar('5');
                break;
            default:
                putchar(c);
                break;
        }
    }
    printf("!!!!!!!!!!\n");

    return 0;
}

  1. 编写程序读取一个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 totals: 30 27 40 36 28
    Column totals: 34 37 37 32 21
#include <stdio.h>

int main(void) {

    int i, j, temp_total;
    int n[5][5];

    for (i = 0; i < 5; i++) {
        printf("Enter row %d: ", i + 1);

        for (j = 0; j < 5; j++) {
            scanf("%d", &n[i][j]);
        }
    }

    printf("Row totals: ");

    for (i = 0; i < 5; i++) {
        temp_total = 0;
        for (j = 0; j < 5; j++) {
            temp_total += n[i][j];
        }
        printf("%d ", temp_total);
    }

    printf("\nColumn totals: ");
    for (i = 0; i < 5; i++) {
        temp_total = 0;
        for (j = 0; j < 5; j++) {
            temp_total += n[j][i];
        }
        printf("%d ", temp_total);
    }

    printf("\n");

    return 0;
}

  1. 修改编程题7,使其提示用户输入每个学生5门测验的成绩,一共有5个学生。然后计算每个学生的总分和平均分,以及每门测验的平均分、高分和低分。
#include <stdio.h>

int main(void) {

    int i, j, temp_total, high, low;
    int n[5][5];

    for (i = 0; i < 5; i++) {
        printf("Enter quiz grades for student %d: ", i + 1);

        for (j = 0; j < 5; j++) {
            scanf("%d", &n[i][j]);
        }
    }

    printf("\n");

    for (i = 0; i < 5; i++) {
        printf("\nTotal and average score for student %d: ", i + 1);
        temp_total = 0;
        for (j = 0; j < 5; j++) {
            temp_total += n[i][j];
        }
        printf("%d %.2f", temp_total, (double) temp_total / 5);
    }

    printf("\n");

    for (i = 0; i < 5; i++) {
        printf("\nAverage, high and low scores for quiz %d: ", i + 1);
        temp_total = 0;
        high = low = n[0][i];

        for (j = 0; j < 5; j++) {
            temp_total += n[j][i];
            if (n[j][i] > high)
                high = n[j][i];
            if (n[j][i] < low)
                low = n[j][i];
        }
        printf("%f %d %d", (double) temp_total / 5, high, low);
    }

    printf("\n");


    return 0;
}

  1. 编写程序,生成一种贯穿10×10字符数组(初始时全为字符’.')的“随机步法”。程序必须随机地从一个元素 “走到”另一个元素,每次都向上、向下、向左或向右移动一个元素位置。已访问过的元素按访问顺序用字母A 到Z 进行标记。下面是一个输出示例:
    在这里插入图片描述
    提示 :利用srand 函数和rand 函数(见程序deal.c )产生随机数,然后查看此数除以4的余数。余数一共有4种可能的值(0、1、2和3),指示下一次移动的4种可能方向。在执行移动之前,需要检查两项内容:一是不能走到数组外面,二是不能走到已有字母标记的位置。只要有一个条件不满足,就得尝试换一个方向移动。如果4个方向都堵住了,程序就必须终止了。下面是提前结束的一个示例:
    在这里插入图片描述  
    因为Y 的4个方向都堵住了,所以没有地方可以放置下一步的Z了。
#include <stdio.h>
#include <stdlib.h> /* srand(), rand() */
#include <time.h> /* time() */

int main(void) {

    char letter = 'A', 
         grid[10][10] = {0};
    int i = 0,
        j = 0,
        up = 0,   /* directions are essentially bools, written as ints to */
        down = 0, /* conform with C89 standard.                           */
        left = 0,
        right = 0,
        move = 0;

    srand((unsigned) time(NULL));

    grid[i][j] = letter++;

    while (letter <= 'Z') {
        up = down = left = right = move = 0;

        if (j + 1 < 10 && grid[i][j + 1] == 0)
            up = 1;
        if (j - 1 >= 0 && grid[i][j - 1] == 0)
            down = 1;
        if (i + 1 < 10 && grid[i + 1][j] == 0)
            right = 1;
        if (i - 1 >= 0 && grid[i - 1][j] == 0)
            left = 1;

        if (up + down + left + right == 0)
            break;

        move = rand() % 4;
        

        /* Intentional fallthrough if direction fails */
        switch(move) {
            case 0:
                if (up) {
                    grid[i][++j] = letter++;
                    break;
                }
            case 1:
                if (down) {
                    grid[i][--j] = letter++;
                    break;
                }
            case 2:
                if (right) {
                    grid[++i][j] = letter++;
                    break;
                }
            case 3:
                if (left) {
                    grid[--i][j] = letter++;
                    break;
                }
            default:
                break;
        }
    }

    for (i = 0; i < 10; i++) {
        for (j = 0; j < 10; j++) {
            if (grid[i][j] == 0) 
                grid[i][j] = '.';
            printf("%c ", grid[i][j]);
        }
        printf("\n");
    }
    
    return 0;
}

  1. 修改第5章的编程题8,用一个数组存储起飞时间,另一个数组存储抵达时间。(时间用整数表示,表示从午夜开始的分钟数。)程序用一个循环搜索起飞时间数组,以找到与用户输入的时间最接近的起飞时间。
#include <stdio.h>

int main(void) {

    int i,
        user_time,
        hour,
        d_hour,
        d_minute,
        a_hour,
        a_minute,
        minute,
        dep[8] = {480, 583, 679, 767, 840, 945, 1140, 1305},
        arr[8] = {616, 712, 811, 900, 968, 1075, 1280, 1438};

    printf("Enter a 24-hour time: ");
    scanf("%d :%d", &hour, &minute);
    user_time = hour * 60 + minute;

    printf("Closest departure time is ");

    for (i = 0; i < 7; i++) {
        if (user_time <= dep[i] + 
            (dep[i + 1] - dep[i]) / 2) {

            d_hour = dep[i] / 60 > 12 ? dep[i] / 60 - 12 : dep[i] / 60;
            d_minute = dep[i] % 60;
            a_hour = arr[i] / 60 > 12 ? arr[i] / 60 - 12 : arr[i] / 60;
            a_minute = arr[i] % 60;

            printf("%d:%.2d %c.m., arriving at %d:%.2d %c.m.\n", 
                   d_hour, d_minute, dep[i] / 60 > 11 ? 'p' : 'a',
                   a_hour, a_minute, arr[i] / 60 > 11 ? 'p' : 'a');
            return 0;
        }
    }

    d_hour = dep[7] / 60 > 12 ? dep[7] / 60 - 12 : dep[7] / 60;
    d_minute = dep[7] % 60;
    a_hour = arr[7] / 60 > 12 ? arr[7] / 60 - 12 : arr[7] / 60;
    a_minute = arr[7] % 60;
   
    printf("%d:%.2d %c.m., arriving at %d:%.2d %c.m.\n",
           d_hour, d_minute, dep[7] / 60 > 11 ? 'p' : 'a',
           a_hour, a_minute, arr[7] / 60 > 11 ? 'p' : 'a');
   return 0;
}

  1. 修改第7章的编程题4,给输出加上标签:
    Enter phone number: 1-800-COL-LECT
    In numeric form: 1-800-265-5328
      在显示电话号码之前,程序需要将其(以原始格式或数值格式)存储在一个字符数组中。可以假定电话号码的长度不超过15个字符。
#include <stdio.h>

int main(void) {

    char phone[15] = {0};
    int i = 0;

    printf("Enter phone number: ");
    while ((phone[i++] = getchar()) != '\n')
        ;
    printf("In numeric form: ");

    for (i = 0; i < 15; i++) {
        switch (phone[i]) {
            case 'A': case 'B': case 'C':
                putchar('2');
                break;
            case 'D': case 'E': case 'F':
                putchar('3');
                break;
            case 'G': case 'H': case 'I':
                putchar('4');
                break;
            case 'J': case 'K': case 'L':
                putchar('5');
                break;
            case 'M': case 'N': case 'O':
                putchar('6');
                break;
            case 'P': case 'R': case 'S':
                putchar('7');
                break;
            case 'T': case 'U': case 'V':
                putchar('8');
                break;
            case 'W': case 'X': case 'Y':
                putchar('9');
                break;
            default:
                putchar(phone[i]);
                break;
        }
    }
    printf("\n");
    return 0;
}

  1. 修改第7章的编程题5,用数组存储字母的面值。数组有26个元素,对应字母表中的26个字母。例如,数组元素0存储1(因为字母A的面值为1),数组元素1存储3(因为字母B的面值为3),等等。每读取输入单词中的一个字母,程序都会利用该数组确定字符的拼字值。使用数组初始化式来建立该数组。
#include <stdio.h>
#include <ctype.h>

int main(void) {

    char c;
    int sum,
        scrabble[26] = {1, 3, 3, 2, 1, 4, 2, 4, 1, 8, 
                        5, 1, 3, 1, 1, 3, 10, 1, 1, 1, 
                        1, 4, 4, 8, 4, 10};

    printf("Enter a word: ");

    while ((c = getchar()) != '\n') {
        sum += scrabble[toupper(c) - 'A'];
    }
    printf("Scrabble value: %d\n", sum);
    return 0;
}

  1. 修改第7章的编程题11,给输出加上标签:
    Enter a first and last name: Lloyd Fosdick
    You enered the name: Fosdick, L.
    在显示姓氏(不是名字)之前,程序需要将其存储在一个字符数组中。可以假定姓氏的长度不超过20个字符。
#include <stdio.h>

int main(void) {

    int i;
    char c, initial, last[20] = {0};

    printf("Enter a first and last name: ");
    
    while ((c = getchar()) == ' ')
        ;
    initial = c;
    while ((getchar() != ' '))
        ;
    for (i = 0; (c = getchar()) != '\n'; i++)
        last[i] = c;

    printf("You entered the name: ");
    for (i = 0; last[i] != '\0'; i++)
        putchar(last[i]);
    printf(", %c.\n", initial);

    return 0;
}
  1. 编写程序颠倒句子中单词的顺序:
    Enter a sentence: you can cage a swallow can’t you?
    Reversal of sentence: you can’t swallow a cage can you?
      提示 :用循环逐个读取字符,然后将它们存储在一个一维字符数组中。当遇到句号、问号或者感叹号(称为“终止字符”)时,终止循环并把终止字符存储在一个char 类型变量中。然后再用一个循环反向搜索数组,找到最后一个单词的起始位置。显示最后一个单词,然后反向搜索倒数第二个单词。重复这一过程,直至到达数组的起始位置。最后显示出终止字符。
#include <stdio.h>

#define MAX_VALUE 100

int main(void) {

    int i = 0,
        j;
    char c, 
         terminating_char,
         words[MAX_VALUE] = {0};

    printf("Enter a sentence: ");
    for (i = 0; (c = getchar()) != '\n' && i < MAX_VALUE; i++) {
        if (c == '.' || c == '!' || c == '?') {
            terminating_char = c;
            break;
        }
        words[i] = c;
    }

    printf("Reversal of sentence: ");
    while (i >= 0) {
        while (words[--i] != ' ' && i != 0)
            ;
        j = i == 0 ? 0 : i + 1;
        while (words[j] != ' ' && words[j] != '\0')
            putchar(words[j++]);
        if (i >= 0)
            putchar(' ');
    }

    printf("\b%c\n", terminating_char);

    return 0;
}

  1. 已知的最古老的一种加密技术是凯撒加密(得名于Julius Caesar)。该方法把一条消息中的每个字母用字母表中固定距离之后的那个字母来替代。(如果越过了字母Z,会绕回到字母表的起始位置。例如,如果每个字母都用字母表中两个位置之后的字母代替,那么 就被替换为 , 就被替换为 。)编写程序用凯撒加密方法对消息进行加密。用户输入待加密的消息和移位计数(字母移动的位置数目):
    Enter message to be encrypted: Go ahead, make my day.
    Enter shift amount (1-25): 3
    Encrypted message: Jr dkhdg, pdnh pb gdb.
      注意,当用户输入26与移位计数的差值时,程序可以对消息进行解密:
    Enter message to be encrypted: Jr dkhdg, pdnh pb gdb.
    Enter shift amount (1-25): 23
    Encrypted message: Go ahead, make my day.
      可以假定消息的长度不超过80个字符。不是字母的那些字符不要改动。此外,加密时不要改变字母的大小写。提示 :为了解决前面提到的绕回问题,可以用表达式((ch - ‘A’) + n) % 26 + 'A’计算大写字母的密码,其中ch 存储字母,n 存储移位计数。(小写字母也需要一个类似的表达式。)
#include <stdio.h>

#define MAX_VALUE 80

int main(void) {

    char c, sentence[MAX_VALUE] = {0};

    int i, n, length;

    printf("Enter message to be encrypted: ");
    for (i = 0, length = 0; (c = getchar()) != '\n' && i < MAX_VALUE; i++) {
        length++;
        sentence[i] = c;
    }

    printf("Enter shift amount (1-25): ");
    scanf("%d", &n);

    printf("Encrypted message: ");
    for (i = 0; i < length; i++) {
        if (sentence[i] >= 'A' && sentence[i] <= 'Z')
            sentence[i] = ((sentence[i] - 'A') + n) % 26 + 'A';
        else if (sentence[i] >= 'a' && sentence[i] <= 'z')
            sentence[i] = ((sentence[i] - 'a') + n) % 26 + 'a';
        
        putchar(sentence[i]);
    }
    printf("\n");

    return 0;
}

  1. 编程测试两个单词是否为变位词(相同字母的重新排列):
    Enter first word: smartest
    Enter second word: mattress
    The words are anagrams.
    Enter first word: dumbest
    Enter second word: stumble
    The words are not anagrams.
      用一个循环逐个字符地读取第一个单词,用一个26元的整数数组记录每个字母的出现次数。(例如,读取单词smartest 之后,数组包含的值为10001000000010000122000000 ,表明smartest 包含一个a 、一个e 、一个m 、一个r 、两个s 和两个t 。)用另一个循环读取第二个单词,这次每读取一个字母就把相应数组元素的值减1。两个循环都应该忽略不是字母的那些字符,并且不区分大小写。第二个单词读取完毕后,再用一个循环来检查数组元素是否为全0 。如果是全0 ,那么这两个单词就是变位词。提示 :可以使用<ctype.h> 中的函数,如isalpha 和tolower 。
#include <stdio.h>
#include <ctype.h> /* toupper, isalpha */

int main(void) {

    int i,
        same = 1,
        letters[26] = {0};
    char c;

    printf("Enter first word: ");
    while ((c = getchar()) != '\n') {
        if (isalpha(c))
            letters[toupper(c) - 'A']++;
    }
    printf("Enter second word: ");
    while ((c = getchar()) != '\n') {
        if (isalpha(c))
            letters[toupper(c) - 'A']--;
    }

    for (i = 0; i < 26; i++) {
        if (letters[i] != 0) {
            same = 0;
            break;
        }
    }
    if (same) {
        printf("The words are anagrams.\n");
        return 0;
    }
    printf("The words are not anagrams.\n");
    return 0;
}

  1. 编写程序打印 的幻方( 的方阵排列,且每行、每列和每条对角线上的和都相等)。由用户指定 的值:
    This program creates a magic square of a specified size.
    The size must be an odd number between 1 and 99.
    Enter size of magic square: 5
    17 24 1 8 15
    23 5 7 14 16
    4 6 13 20 22
    10 12 19 21 3
    11 18 25 2 9
      把幻方存储在一个二维数组中。起始时把数1放在0行的中间,剩下的数 依次向上移动一行并向右移动一列。当可能越过数组边界时需要“绕回”到数组的另一端。例如,如果需要把下一个数放到-1行,我们就将其存储到 行(最后一行);如果需要把下一个数放到 列,我们就将其存储到0列。如果某个特定的数组元素已被占用,那就把该数存储在前一个数的正下方。如果你的编译器支持变长数组,声明数组有 行 列,否则声明数组有99行99列。
#include <stdio.h>

int main(void) {

    int count, n, x, y, x_last, y_last;
    

    printf("This program creates a magic square of a specified size.\n");
    printf("The size must be an odd number between 1 and 99.\n");
    printf("Enter size of magic square: ");
    scanf("%d", &n);

    int square[n][n];
    
    for (x = 0; x < n; x++) {
        for (y = 0; y < n; y++) {
            square[x][y] = 0;
        }
    }

    x = n / 2; 
    y = 0;
    square[x][y] = 1;

    count = 2;
    while (count <= n * n) {
        
        x_last = x;
        y_last = y;

        if (x_last + 1 >= n)
            x = 0;
        else 
            x = x_last + 1;
        if (y_last - 1 < 0)
            y = n - 1;
        else 
            y = y_last - 1;
        
        if (square[x][y] == 0) {
            square[x][y] = count++;
        } else {
            if (y_last + 1 >= n)
                square[x = x_last][y = 0] = count++;
            else
                square[x = x_last][y = y_last + 1] = count++;
        }
    }

    for (y = 0; y < n; y++) {
        for (x = 0; x < n; x++) {
            printf("%4d", square[x][y]);
        }
        printf("\n");
    }
    
    return 0;
}

  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2022-05-09 12:22:52  更:2022-05-09 12:25:25 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/20 21:41:01-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码