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语言程序设计 现代设计方法_第7章代码、练习题及编程题答案 -> 正文阅读

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

代码

7.1 sum2.c
程序  数列求和(改进版)
6.1节编写了一个程序对用户输入的整数数列求和。该程序的一个问题就是所求出的和(或其中某个输入数)可能会超出int 型变量允许的最大值。如果程序运行在整数长度为16位的机器上,可能会发生下面的情况:
This program sums a series of integers.
Enter integers (0 to terminate): 10000 20000 30000 0
The sum is: -5536
求和的结果应该为60 000,但这个值不在int 型变量表示的范围内,所以出现了溢出。当有符号整数发生溢出时,结果是未定义的,在本例中我们得到了一个毫无意义的结果。为了改进这个程序,可以把变量改换成long 型。

sum2.c
/* Sums a series of numbers (using long int variables) */
#include <stdio.h>
int main(void)
{
	long n, sum = 0;
	printf("This program sums a series of integers.\n");
	printf("Enter integers (0 to terminate): ");
	
	scanf("%ld", &n);
	while (n != 0) {
		sum += n;
		scanf("%ld", &n);
	}
	
	printf("The sum is: %ld\n", sum);
	return 0;
}

这种改变非常简单:将n 和sum 声明为long 型变量而不是int 型变量,然后把scanf 和printf 函数中的转换说明由%d 改为%ld。

7.3 length.c
程序  确定消息的长度
为了说明字符的读取方式,下面编写一个程序来计算消息的长度。在用户输入消息后,程序显示长度:
Enter a message: Brevity is the soul of wit.
Your message was 27 character(s) long.
消息的长度包括空格和标点符号,但是不包含消息结尾的换行符。程序需要采用循环结构来实现读入字符和计数器自增操作,循环在遇到换行符时立刻终止。我们既可以采用scanf 函数也可以采用getchar 函数读取字符,但大多数C程序员愿意采用getchar 函数。采用简明的while 循环书写的程序如下:

/* Determines the length of a message */
#include <stdio.h>
int main(void)
{
	char ch;
	int len = 0;
	printf("Enter a message: ");
	ch = getchar();
	while (ch != '\n') {
		len++;
		ch = getchar();
	}
	printf("Your message was %d character(s) long.\n", len);
	return 0;
}

回顾有关while 循环和getchar 函数惯用法的讨论,我们发现程序可以缩短成如下形式:

length2.c
/* Determines the length of a message */
#include <stdio.h>
int main(void)
{
	int len = 0;
	printf("Enter a message: ");
	while (getchar() != '\n')
		len++;
	printf("Your message was %d character(s) long.\n", len);
	return 0;
}

练习题

  1. 给出下列整数常量的十进制值。
  (a) 077
  (b) 0x77
  (c) 0XABC
(a) 63  
(b) 119  
(c) 2748
  1. 下列哪些常量在C语言中不是合法的?区分每一个合法的常量是整数还是浮点数。
  (a) 010E2
  (b) 32.1E+5
  (c) 0790
  (d) 100_000
  (e) 3.978e-2
(c) and (d) are illegal constants, because of undefined numeral `9` in octal
number `0790`, and underscore in `100_000`.
(a), (b) and (e) are legal, floating point constants.
  1. 下列哪些类型在C语言中不是合法的?
  (a) short unsigned int
  (b) short float
  (c) long double
  (d) unsigned long
(b) `short float` is not a legal type. The only available floating point types
are `float`, `double` and `long double`.
  1. 如果变量c 是char 类型,那么下列哪条语句是非法的?
  (a) i += c; /* i has type int */
  (b) c = 2 * c - 1;
  (c) putchar(c);
  (d) printf(c);
(d) `printf(c);` is illegal, because the `printf` function prints strings, not
individual (numerical representations of) characters.
  1. 下列哪条不是书写数65的合法方式?(假设字符集是ASCII。)
  (a) 'A'
  (b) 0b1000001
  (c) 0101
  (d) 0x41
(b) `0b1000001` is illegal, as C does not allow binary represented numbers.
  1. 对于下面的数据项,指明char 、short 、int 、long 类型中哪种类型是足以存储数据的最小类型。
  (a) 一个月的天数
  (b) 一年的天数
  (c) 一天的分钟数
  (d) 一天的秒数
(a) Max. 31: `char`  
(b) Max. 366: `short`  
(c) Max. 1500: `short`  
(d) Max. 86760: `long`
  1. 对于下面的字符转义,给出等价的八进制转义。(假定字符集是ASCII。)可以参考附录E,其中列出了ASCII字符的数值码。
  (a) \b
  (b) \n
  (c) \r
  (d) \t
(a) `\10`  
(b) `\12`  
(c) `\15`  
(d) `\11`
  1. 重复练习题7,给出等价的十六进制转义。
(a) `\x08`  
(b) `\x0a`  
(c) `\x0d`  
(d) `\x09`

  1. 假设变量i 和变量j 都是int 类型,那么表达式i / j + ‘a’ 是什么类型?
`int`. The expression automatically promotes the `char` value `'a'` to an `int`.
  1. 假设变量i 是int 类型,变量j 是long int 类型,并且变量k 是unsigned int 类型,那么表达式i + (int)j * k 是什么类型?
`unsigned int`. `j` casts to `int`, and `k` promotes the expression to `unsigned
int`.
  1. 假设变量i 是int 类型,变量f 是float 类型,变量d 是double 类型,那么表达式i * f / d 是什么类型?
`double`, as it will promote the other types automatically to `double`.
  1. 假设变量i 是int 类型,变量f 是float 类型,变量d 是double 类型,请解释在执行下列语句时发生了什么转换?
    d = i + f;
The addition operation will require conversion of the value of `i` to `float`,
and the assignment operation will require conversion of the summed value to
`double`.

  1. 假设程序包含下列声明:
char c = '\1';
short s = 2;
int i = -3;
long m = 5;
float f = 6.5f;
double d = 7.5;

给出下列每个表达式的值和类型。

  (a) c * i   (c) f / c   (e) f - d
  (b) s + m   (d) d / s   (f) (int) f
(a) `-3`, `int`  
(b) `7`, `long`  
(c) `6.5f`, `float`  
(d) `3.75`, `double`  
(e) `-1.0`, `double`  
(f) `6`, `int`
  1. 下列语句是否总是可以正确地计算出f 的小数部分(假设f 和frac_part 都是float 类型的变量)?frac_part = f - (int) f;如果不是,那么出了什么问题?
No, the statement could fail if the value of `f` is larger than the largest
value of `int`.
  1. 使用typedef 创建名为Int8 、Int16 和Int32 的类型。定义这些类型以便它们可以在你的机器上分别表示8位、16位和32位的整数。
typedef char Int8;    char uses 1 byte (8 bits) of memory
typedef short Int16;  short uses 2 bytes (16 bits) of memory
typedef int Int32;    int uses 4 bytes (32 bits) of memory

Unlike #define macros, we put our intended variable types at the end of typedef

编程题

  1. 如果i * i 超出了int 类型的最大取值,那么6.3节的程序square2.c 将失败(通常会显示奇怪的答案)。运行该程序,并确定导致失败的n 的最小值。尝试把变量i 的类型改成short 并再次运行该程序。(不要忘记更新printf 函数调用中的转换说明!)然后尝试改成long 。从这些实验中,你能总结出在你的机器上用于存储整数类型的位数是多少吗?
/* Prints a table of squares using a for statement */

#include <stdio.h>

int main(void) {

    short i, n;

    printf("This program prints a table of squares.\n");
    printf("Enter number of entries in table: ");
    scanf("%hd", &n);

    for (i = 1; i <= n; i++)
        printf("%20hd%20hd\n", i, i * i);


    return 0;
}
  1. 修改6.3节的程序square2.c ,每24次平方后暂停并显示下列信息:
    Press Enter to continue…
    显示完上述消息后,程序应该使用getchar 函数读入一个字符。getchar 函数读到用户录入的回车键才允许程序继续。
/* Prints a table of squares using a for statement */

#include <stdio.h>

int main(void) {

    int i, n;

    printf("This program prints a table of squares.\n");
    printf("Enter number of entries in table: ");
    scanf("%d", &n);
    getchar(); /* ungets '\n' from buffer */

    for (i = 1; i <= n; i++) {

        printf("%10d%10d\n", i, i * i);
        if (i % 24 == 0) {
            printf("Press Enter to continue...");
            while (getchar() != '\n')
                ;
        }
    }    
    return 0;
}

3. 修改7.1节的程序sum2.c ,对double 型值组成的数列求和。

/* Sums a series of numbers (using double variables) */

#include <stdio.h>

int main(void) {

    double n, sum = 0.0;

    printf("This program sums a series of floating-point numbers.\n");
    printf("Enter numbers (0 to terminate): ");

    scanf("%lf", &n);
    while (n != 0.0) {
        sum += n;
        scanf("%lf", &n);
    }
    printf("The sum is: %f\n", sum);

    return 0;
}

  1. 编写程序可以把字母格式的电话号码翻译成数值格式:
    Enter phone number: CALLATT
    2255288
    (如果没有电话在身边,参考这里给出的字母在键盘上的对应关系:2=ABC ,3=DEF ,4=GHI ,5=JKL ,6=MNO ,7=PQRS ,8=TUV ,9=WXYZ 。)原始电话号码中的非字母字符(例如数字或标点符号)保持不变:
    Enter phone number: 1-800-COL-LECT
    1-800-265-5328
    可以假设任何用户输入的字母都是大写字母。
#include <stdio.h>

int main(void) {

    char c;

    printf("Enter phone number: ");
    while ((c = getchar()) != '\n') {
        switch (c) {
            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(c);
                break;
        }
    }
    printf("\n");
    return 0;
}

  1. 在十字拼字游戏中,玩家利用小卡片组成单词,每个卡片包含字母和面值。面值根据字母稀缺程度的不同而不同。(面值有:1——
    AEILNORSTU,2——DG,3——BCMP,4——FHVWY,5——K,8——JX,10——QZ。)编写程序通过对单词中字母的面值求和来计算单词的值:
    Enter a word: pitfall
    Scrabble value: 12
    编写的程序应该允许单词中混合出现大小写字母。提示 :使用toupper 库函数。
#include <stdio.h>
#include <ctype.h>

int main(void) {

    char c;
    int sum;

    printf("Enter a word: ");

    while ((c = getchar()) != '\n') {
        switch (toupper(c)) {
            case 'A': case 'E': case 'I': case 'L': case 'N': case 'O': 
            case 'R': case 'S': case 'T': case 'U':
                sum++;
                break;
            case 'D': case 'G':
                sum += 2;
                break;
            case 'B': case 'C': case 'M': case 'P':
                sum += 3;
                break;
            case 'F': case 'H': case 'V': case 'W': case 'Y':
                sum += 4;
                break;
            case 'K':
                sum += 5;
                break;
            case 'J': case 'X':
                sum += 8;
                break;
            case 'Q': case 'Z':
                sum += 10;
                break;
            default:
                break;
        }
    }
    printf("Scrabble value: %d\n", sum);
    return 0;
}

  1. 编写程序显示sizeof(int) 、sizeof(short) 、sizeof(long) 、sizeof(float) 、sizeof(double) 和sizeof(long double) 的值。
#include <stdio.h>

int main(void) {

    printf("%lu, %lu, %lu, %lu, %lu, %lu\n", 
           (unsigned long) sizeof(int), (unsigned long) sizeof(short),
           (unsigned long) sizeof(long), (unsigned long) sizeof(float),
           (unsigned long) sizeof(double), (unsigned long) sizeof(long double));

    return 0;
}

  1. 修改第3章的编程题6,使得用户可以对两个分数进行加、减、乘、除运算(在两个分数之间输入+ 、- 、* 或/ 符号)。
/* Adds two fractions */

#include <stdio.h>

int main(void) {
    int num1, denom1, num2, denom2, result_num, result_denom;
    char operator;

    printf("Enter two fractions separated by an operator: ");
    scanf("%d /%d %c %d /%d", &num1, &denom1, &operator, &num2, &denom2);

    switch (operator) {
        case '+':
            result_num = num1 * denom2 + num2 * denom1;
            result_denom = denom1 * denom2;
            break;
        case '-':
            result_num = num1 * denom2 - num2 * denom1;
            result_denom = denom1 * denom2;
            break;
        case '*':
            result_num = num1 * num2;
            result_denom = denom1 * denom2;
            break;
        case '/':
            result_num = num1 * denom2;
            result_denom = num2 * denom1;
            break;
        default:
            printf("Operation %c not supported.\n", operator);
            return 1; /* operation error */
    }

    int temp, num_temp = result_num, gcd = result_denom;
    while (num_temp != 0) {
        temp = gcd % num_temp;
        gcd = num_temp;
        num_temp = temp;
    }

    if (result_num / gcd == result_denom / gcd)
        printf("Result: %d\n", result_num / gcd);
    else if (result_num > result_denom) {
        printf("Result: %d %d/%d\n",
        result_num / result_denom, result_num % result_denom, result_denom);
    } else
        printf("Result: %d/%d\n", result_num / gcd, result_denom / gcd);

    return 0;
}

  1. 修改第5章的编程题8,要求用户输入12小时制的时间。输入时间的格式为时∶分 后跟A、P、AM或PM(大小写均可)。数值时间和AM/PM之间允许有空白(但不强制要求有空白)。有效输入的示例如下:
    1:15P
    1:15PM
    1:15p
    1:15pm
    1:15 P
    1:15 PM
    1:15 p
    1:15 pm
    可以假定输入的格式就是上述之一,不需要进行错误判定。
#include <stdio.h>
#include <ctype.h>

int main(void) {

    int user_time,
        hour,
        minute,
        d1 = 480,
        d2 = 583,
        d3 = 679,
        d4 = 767,
        d5 = 840,
        d6 = 945,
        d7 = 1140,
        d8 = 1305;

    char c;

    printf("Enter a 12-hour time with AM/PM indicator: ");
    scanf("%d :%d %c", &hour, &minute, &c);
    user_time = (((toupper(c) == 'P' ? 12 : 0) + hour) * 60) + minute;

    printf("Closest departure time is ");

    if (user_time <= d1 + (d2 - d1) / 2)
        printf("8:00 a.m., arriving at 10:16 a.m.\n");
    else if (user_time < d2 + (d3 - d2) / 2)
        printf("9:43 a.m., arriving at 11:52 a.m.\n");
    else if (user_time < d3 + (d4 - d3) / 2)
        printf("11:19 a.m., arriving at 1:31 p.m.\n");
    else if (user_time < d4 + (d5 - d4) / 2)
        printf("12:47 p.m., arriving at 3:00 p.m.\n");
    else if (user_time < d5 + (d6 - d5) / 2)
        printf("2:00 p.m., arriving at 4:08 p.m.\n");
    else if (user_time < d6 + (d7 - d6) / 2)
        printf("3:45 p.m., arriving at 5:55 p.m.\n");
    else if (user_time < d7 + (d8 - d7) / 2)
        printf("7:00 p.m., arriving at 9:20 p.m.\n");
    else
        printf("9:45 p.m., arriving at 11:58 p.m.\n");

    return 0;
}
  1. 编写程序要求用户输入12小时制的时间,然后用24小时制显示该时间:
    Enter a 12-hour time: 9:11 PM
    Equivalent 24-hour time: 21:11
    参考编程题8中关于输入格式的描述。
#include <stdio.h>
#include <ctype.h>

int main(void) {

    int user_time,
        hour,
        minute;
    char c;

    printf("Enter a 12-hour time with AM/PM indicator: ");
    scanf("%d :%d %c", &hour, &minute, &c);
    user_time = (toupper(c) == 'P' ? 12 : 0) + hour;

    printf("Closest departure time is %d:%d\n", user_time, minute);

    return 0;
}

与第五章第二题类似
存在问题: 未考虑12点的
12 : 36 AM 00:36
12:36 PM – 12:36

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

int main(void) {


    int hour, minute;
    char c;

    printf("Enter a 12-hour time: ");
    scanf("%d :%d %c", &hour, &minute, &c);

    hour = (hour == 12 ? 0 : hour);
    if (toupper(c) == 'P')
        hour += 12;

    printf("Equivalent 24-hour time: %.2d:%.2d\n", hour, minute);

    return 0;
}

  1. 编写程序统计句子中元音字母(a、e、i、o、u)的个数:
    Enter a sentence: And that’s the way it is.
    Your sentence contains 6 vowels.
#include <stdio.h>
#include <ctype.h>

int main(void) {

    char c;
    int vowels = 0;
    
    printf("Enter a sentence: ");

    while ((c = getchar()) != '\n') {
        switch (toupper(c)) {
            case 'A': case 'E': case 'I': case 'O': case 'U':
                vowels++;
                break;
            default:
                break;
        }
    }
    printf("Your sentence contains %d vowels.\n", vowels);
    return 0;
}
  1. 编写一个程序,根据用户输入的英文名和姓先显示姓氏,其后跟一个逗号,然后显示名的首字母,最后加一个点:
    Enter a first and last name: Lloyd Fosdick
    Fosdick, L.
    用户的输入中可能包含空格(名之前、名和姓之间、姓氏之后)。
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <ctype.h>

int main(void) {

    char first;
    char ch;

    printf("Enter a first and last name: ");

    while ((ch = getchar()) == ' ') {
        ;
    }
    first = ch;

    while (getchar() != ' ') {
        ;
    }

    while ((ch = getchar()) == ' ') {
        ;
    }
    printf("%c", ch);
    while ((ch = getchar()) != '\n') {
        printf("%c", ch);
    }
    printf(", %c.\n", first);

    return 0;
}

存在问题:
太多循环了

#include <stdio.h>

int main(void) {

    char c, initial;

    printf("Enter a first and last name: ");
    scanf(" %c", &initial);
    
    while ((c = getchar()) != ' ')
        ;

    while ((c = getchar()) == ' ')
        ;

    do {
        putchar(c);
    } while ((c = getchar()) != '\n' && c != ' ');

    printf(", %c.\n", initial);

    return 0;
}
  1. 编写程序对表达式求值:
    Enter an expression: 1+2.53
    Value of expression: 10.5
    表达式中的操作数是浮点数,运算符是+ 、- 、
    和/ 。表达式从左向右求值(所有运算符的优先级都一样)。
#include <stdio.h>

int main(void) {

    double num = 0.0, total = 0.0;
    char c;

    printf("Enter an expression: ");
    scanf("%lf", &total);

    while ((c = getchar()) != '\n') {
        switch (c) {
            case '+':
                scanf("%lf", &num);
                total += num;
                break;
            case '-':
                scanf("%lf", &num);
                total -= num;
                break;
            case '*':
                scanf("%lf", &num);
                total *= num;
                break;
            case '/':
                scanf("%lf", &num);
                total /= num;
                break;
            default: 
                break;
        }
    }

    printf("Value of expression: %f\n", total);
    return 0;
}
  1. 编写程序计算句子的平均词长:
    Enter a sentence: It was deja vu all over again.
    Average word length: 3.4
    简单起见,程序中把标点符号看作其前面单词的一部分。平均词长显示一个小数位。
#include <stdio.h>

int main(void) {

    char c;
    double length = 0.0;
    int words = 1;

    printf("Enter a sentence: ");

    while ((c = getchar()) != '\n') {
        if (c == ' ')
            words++;
        else 
            length++;
    }

    printf("Average word length: %.1f\n", length / words);
    return 0;
}
  1. 编写程序,用牛顿方法计算正浮点数的平方根:
    Enter a positive number: 3
    Square root: 1.73205
    设x是用户输入的数。牛顿方法需要先给出x平方根的猜测值y(我们使用1)。后续的猜测值通过计算y和x/y的平均值得到。下表给出了求解3的平方根的过程。
    x y x/y y和x/y的平均值
    3 1 3 2
    3 2 1.5 1.75
    3 1.75 1.71429 1.73214
    3 1.73214 1.73196 1.73205
    3 1.73205 1.73205 1.73205
    注意, y的值逐渐接近x的平方根。为了获得更高的精度,程序中应使用double 类型的变量代替float 类型的变量。当y的新旧值之差的绝对值小于0.00001和y的乘积时程序终止。提示 :调用fabs 函数求double 类型数值的绝对值。(为了使用fabs 函数,需要在程序的开头包含<math.h> 头。)
#include <stdio.h>
#include <math.h>

int main(void) {

    double x, y = 1.0;

    printf("Enter a positive number: ");
    scanf("%lf", &x);

    while (fabs((y + x / y) / 2 - y) > .00001 * y)
        y = (y + x / y) / 2;

    printf("Square root: %f\n", y);

    return 0;
}
  1. 编程计算正整数的阶乘:
    Enter a positive integer: 6
    Factorial of 6: 720
      (a) 用short 类型变量存储阶乘的值。为了正确打印出 的阶乘, 的最大值是多少?
      (b) 用int 类型变量重复(a)。
      ? 用long 类型变量重复(a)。
      (d) 如果你的编译器支持long long 类型,用long long 类型变量重复(a)。
      (e) 用float 类型变量重复(a)。
      (f) 用double 类型变量重复(a)。
      (g) 用long double 类型变量重复(a)。
      在(e)~(g)几种情况下,程序会显示阶乘的近似值,不一定是准确值。
#include <stdio.h>

int main(void) {

    int i, n;
    long double fact = 1.0;

    printf("Enter a positive integer: ");
    scanf("%d", &n);

    for (i = n; i > 1; i--)
        fact *= i;

    printf("Factorial of %d: %Lf\n", n, fact);

    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-24 17:55:54  更:2022-05-24 17:58:10 
 
开发: 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/12 22:59:25-

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