关于c:C语言程序设计谭浩强第五版-第3章-最简单的的C程序设计顺序程序设计-习题解析与答案

41次阅读

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

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

题目 1:如果我国国民生产总值的年增长率为 7%,计算 10 年后我国国民生产总值与当初相比增长多少百分比。计算公式为:

$$
p=(1+r)^n
$$

r 为年增长率,n 为年数,p 为与当初相比的倍数。

解:从主教材附录 D(库函数)能够查到:能够用 pow 函数求 $y^x$ 的值,调用 pow 函数的具体模式是 pow(x,y)。在应用 pow 函数时须要在程序的结尾用# include 指令将 <math.h> 头文件蕴含到本程序模块中。能够用上面的程序求出 10 年后国民生产总值是当初的多少倍。

答案代码:

#include <stdio.h>
#include <math.h>
int main()
{
    float p, r, n;
    r = 0.07;
    n = 10;
    p = pow(1 + r, n);
    printf("p= %f\n", p);
    return 0;
}

运行后果:

即 10 年后国民生产总值是当初的 1.967151 倍。

题目 2:贷款利息的计算。有 1000 元,想存 5 年,可按以下 5 种方法存:

​ (1) 一次存 5 年期。

​ (2) 先存 2 年期,到期后将本息再存 3 年期。

​ (3) 先存 3 年期,到期后将本息再存 2 年期。

​ (4) 存 1 年期,到期后将本息再存 1 年期,间断存 5 次。

​ (5) 存活期存款。定期利息每 - 季度结算一次。

2017 年的银行存款利息如下:

​ 1 年期定期存款利息为 1.5%;

​ 2 年期定期存款利息为 2.1%;

​ 3 年期定期存款利息为 2.75%;

​ 5 年期定期存款利息为 3%;

活期存款利息为 0.35%(活期存款每一季度结算一次利息)。

如果 r 为年利率,n 为贷款年数,则计算本息和的公式如下:

1 年期本息和:$P=1000* (1+r)$

n 年期本息和:$P=1000* (1+n* r);$
存 n 次 1 年期的本息和:$P=1000* (1+r)^n;$

阐明: $1000*(1+\frac{r}{4})$ 是一个季度的本息和。

解:设 5 年期贷款的年利率为 r5,3 年期贷款的年利率为 r3,2 年期贷款的年利率为 r2,1 年期贷款的年利率为 rl,活期存款的年利率为 r0。

设按第 1 种计划贷款 5 年失去的本息和为 p1,按第 2 种计划贷款 5 年失去的本息和为 p2,按第 3 种计划贷款 5 年失去的本息和为 p3,按第 4 种计划贷款 5 年失去的本息和为 p4,按第 5 种计划贷款 5 年失去的本息和为 p5。

答案代码:

#include <stdio.h>
#include <math.h>
int main()

{
    float r5, r3, r2, r1, r0, p, p1, p2, p3, p4, p5;
    p = 1000;
    r5 = 0.03;
    r3 = 0.0275;
    r2 = 0.021;
    r1 = 0.015;
    r0 = 0.0035;
    p1 = p * (1 + r5 * 5);                  // 一次存 5 年期
    p2 = p * (1 + 2 * r2) * (1 + 3 * r3); // 先存 2 年期, 到期后将本息再存 3 年期
    p3 = p * (1 + 3 * r3) * (1 + 2 * r2); // 先存 3 年期, 到期后将本息再存 2 年期
    p4 = p * pow(1 + r1, 5);              // 存 1 年期,到期后将本息再存 1 年期, 间断存 5 次
    p5 = p * pow(1 + r0 / 4, 4 * 5);      // 存活期存款, 定期利息每一季度结算一次
    printf("p1= %f\n", p1);                  // 输入按第 1 种计划失去的本息和
    printf("p2= %f\n", p2);                  // 输入按第 2 种计划失去的本息和
    printf("p3= %f\n", p3);                  // 输入按第 3 种计划失去的本息和
    printf("p4= %f\n", p4);                  // 输入按第 4 种计划失去的本息和
    printf("p5= %f\n", p5);                  // 输入按第 5 种计划失去的本息和
    return 0;
}

运行后果:

探讨:
(1) 程序在编译时呈现正告 (warning),并告知起因是“‘=’: truncation from ‘ const double ‘ to ‘float’”(在执行赋值时,呈现将双精度常量转换为单精度的状况)。这是因为 VisualC++6.0 在编译时把实常数(如程序中的利率) 全副按双精度数解决, 因而在向 r5,r3 等 float 型变量赋值时,就呈现将双精度数赋给单精度变量的状况,这样可能会损失一些精度,故向用户揭示,请用户思考是否要批改。正告只是揭示,程序能够失常运行,但失去的后果可能会呈现一些误差,如果用户认为误差能够容忍,可不理睬正告,持续进行连贯和运行。

(2) 如果不想呈现下面的正告,能够将第 4 行各变量改为 double 型,即

double r5,r3,r2 ,r1,r0,p,p1 ,p2 ,p3,p4,p5;

因为采纳了双精度变量,失去的运算后果会更准确些,最初几位数字与下面的有些差异。

(3) 输入运行后果时,失去 6 位小数,连同整数局部有 10 位数字,而一个 float 型变量只能保障 6 位有效数字,前面几位是无意义的。而且在输入款额时,入们个别只要求准确到两位小数(角、分), 因而能够在 printf 函数中用 %10.2 格局符输入。最初 5 个语句可改为

    printf("p1=%10.2f\n", p1); // 输入按第 1 种计划失去的本息和
    printf("p2=%10.2f\n", p2); // 输入按第 2 种计划失去的本息和
    printf("p3=%10.2f\n", p3); // 输入按第 3 种计划失去的本息和
    printf("p4=%10.2f\n", p4); // 输入按第 4 种计划失去的本息和
    printf("p5=%10.2f\n", p5); // 输入按第 5 种计划失去的本息和

这时的输入后果如下:

题目 3:购房从银行贷了一笔款 d,筹备每月还款额为 p,月利率为 r,计算多少月能还清。设 d 为 300 000 元,p 为 6000 元,r 为 1%。对求得的月份取小数点后一位,对第 2 位按四舍五入解决。

提醒:计算还清月数 m 的公式如下:

$$
m=\frac{log p-log(p-d*r)}{log(1+r)}
$$

能够将公式改写为

$$
m=\frac{log(\frac{p}{p-d*r})}{log(1+r)}
$$

C 的库函数中有求对数的函数 log10,是求以 10 为底的对数,log(p)示意 log p。

解:依据以上公式能够很容易写出以下程序。

答案代码:

#include <stdio.h>
#include <math.h>
int main()

{
    float d = 300000, p = 6000, r = 0.01, m;
    m = log10(p / (p - d * r)) / log10(1 + r);
    printf("m=%6.1f\n", m);
    return 0;
}

运行后果:

即须要 69.7 个月能力还清。为了验证对第 2 位小数是否已按四舍五入解决,能够将程序第 6 行中的“%6.1f”改为“%6.2f””。此时的输入为

题目 4:剖析上面的程序:

#include <stdio.h>
int main()
{
    char c1, c2;
    c1 = 97;
    c2 = 98;
    printf("c1= %c,c2= %c\n", c1, c2);
    printf("c1= %d,c2= %d\n", c1, c2);
    return 0;
}

(1)运行时会输入什么信息? 为什么?

解:运行时输入

第 1 行是将 c1,c2 按 %c 的格局输入,97 是字符 a 的 ASCII 码,98 是字符 b 的 ASCII 码。

第 2 行是将 c1,c2 按 %d 的格局输入,所以输入两个十进制整数。

(2)如果将程序第 4,5 行改为

c1=197;

c2= 198;

运行时会输入什么信息? 为什么?

解:因为 VisualC++6.0 字符型数据是作为 signed char 类型解决的,它存字符的无效范畴为 0~127,超过此范畴的解决办法,不同的零碎失去的后果不同,因此用 %c 格局输入时,后果是不可意料的。

用 %d 格局输入时,输入 c1=-59,c2=-58。这是按补码模式输入的,内存字节中第 1 位为 1 时,作为正数。59 与 197 之和等于 256,58 与 198 之和也等于 256。对此可暂不深究。

只有晓得:用 char 类型变量时,给它赋的值应在 0~127 范畴内。

(3)如果将程序第 3 行改为
int c1,c2;

运行时会输入什么信息? 为什么?

解:如果给 c1 和 c2 赋的值是 97 和 98,则输入后果与 (1) 雷同。如果给 c1 和 c2 赋的值是 197 和 198,则用 %c 输入时是不可意料的字符。用 %d 输入时,输入整数 197 和 198,因为它们在 int 类型的无效范畴内。

题目 5:用上面的 scanf 函数输出数据,使 a =3,b=7,x=8.5,y=71.82,c1=’A’,c2=’a’。在键盘上应如何输出?

#include <stdio.h>
int main()
{
    int a, b;
    float x, y;
    char c1, c2;
    scanf("a=%d b=%d", &a, &b);
    scanf("%f %e", &x, &y);
    scanf("%c %c", &c1, &c2);
    printf("a=%d,b=%d,x=%f,y=%f,c1=%c,c2=%c\n", a, b, x, y, c1, c2);
    return 0;
}

解:按如下形式在键盘上输出:

第 3 行是输入的后果。

留神:在输出 8.5 和 71.82 两个实数给 x 和 y 后,应紧接着输出字符 A,两头不要有空格,,因为 A 是字母而不是数字,零碎在遇到字母 A 时就确定输出给 y 的数值已完结。字符 A 就送到下一个 scanf 语句中的字符变量 c1。如果在输出 8.5 和 71.82 两个实数后输出空格符,会怎么样呢?状况如下:

这时 71.82 前面输出的空格字符就被 c1 读入,c2 读入了字符 A。在输入 c1 时就输入空格,输入 c2 的值为 A。

如果在输出 8. 5 和 71.82 两个实数后按回车键,会怎么样呢?状况如下:

下面 3 行是输出,在输出 71. 82 后按回车键。在这时“回车”被作为一个字符送到内存输出缓冲区,被 c1 读入(实际上 c1 读入的是回车符的 ASCII 码),字符 A 被 c2 读取,所以在执行 printf 函数输入 c1 时,就输入一个换行,在下一行输入逗号和 c2 的值 A。

在用 scanf 函数输出数据时往往会呈现一些意想不到的状况,例如在间断输出不同类型的数据 (特地是数值型数据和字符数据间断输出) 的状况。要留神回车符是可能被作为一个字符读入的。

通过此例,能够理解怎么正确进行输出数据。这些常识不能靠干燥地死记规定,必须长于在实践中留神剖析景象,一直总结经验。

题目 6:请编程序将“China”译成密码,明码法则是:用原来的字母前面第 4 个字母代替原来的字母。例如,字母“A”前面第 4 个字母是“E”,用“E”代替“A”。因而,“China” 应译为“Glmre”。请编一程序,用赋初值的办法使 cl,c2,c3,c4,c5 这 5 个变量的值分为 ’C’,’h’,’i’,’n’,’a’,通过运算,使 c1,c2,c3,c4,c5 别离为 ’G’,’l’,’m’,’r’,’e’。别离用 putchar 函数和 printf 函数输入这 5 个字符。

解:答案代码:

#include <stdio.h>
int main()
{

    char c1 = 'C', c2 = 'h', c3 = 'i', c4 = 'n', c5 = 'a';
    c1 = c1 + 4;
    c2 = c2 + 4;
    c3 = c3 + 4;
    c4 = c4 + 4;
    c5 = c5 + 4;
    printf("password is %c%c%c%c%c\n", c1, c2, c3, c4, c5);
    return 0;
}

运行后果:

题目 7:设圆半径 r =1.5,圆柱高 h =3,求圆周长、圆面积、圆球表面积、圆球体积、圆柱体积。用 scanf 输出数据,输入计算结果,输入时要求有文字说明,取小数点后 2 位数字。请编程序。

解:答案代码:

#include <stdio.h>
int main()
{

    float h, r, l, s, sq, vq, vz;
    float pi = 3.141526;
    printf("请输出圆半径 r, 圆柱高 h:");
    scanf("%f,%f", &r, &h);             // 要求输出圆半径 r 和圆柱高 h
    l = 2 * pi * r;                     // 计算圆周长 l
    s = r * r * pi;                     // 计算圆面积 s
    sq = 4 * pi * r * r;             // 计算圆球表面积 sq
    vq = 3.0 / 4.0 * pi * r * r * r; // 计算圆球体积 vq
    vz = pi * r * r * h;             // 计算圆柱体积 vz
    printf("圆周长为:          l=%6.2f\n", l);
    printf("圆面积为:          s=%6.2f\n", s);
    printf("圆球表面积为:      sq=%6.2f\n", sq);
    printf("圆球体积为:          v=%6.2f\n", vq);
    printf("圆柱体积为:          vz=%6.2f\n", vz);
    return 0;
}

运行后果:

阐明:如果用 VisualC++ 6.0 中文版对程序进行编译,在程序中能够应用中文字符串,在输入时也能显示汉字。如果用英文的 C 编译系统,则无奈应用中文字符串,读者能够改用英文字符串。

题目 8:编程序,用 getchar 函数读入两个字符给 c1 和 c2,而后别离用 putchar 函数和 printf 函数输入这两个字符。思考以下问题:

(1)变量 c1 和 c2 应定义为字符型、整型还是二者皆可?

(2)要求输入 cl 和 c2 值的 ASCII 码,应如何解决? 用 putchar 函数还是 printf 函数?

(3)整型变量与字符变量是否在任何状况下都能够相互代替? 如:
char c1,c2;

int cl,c2;
是否无条件地等价?

解:答案代码:

#include <stdio.h>
int main()
{

    char c1, c2;
    printf("请输出两个字符 c1,c2:");
    c1 = getchar();
    c2 = getchar();
    printf("用 putchar 语句输入后果为:");
    putchar(c1);
    putchar(c2);
    printf("\n");
    printf("用 printf 语句输入后果为:");
    printf("%c %c\n", c1, c2);
    return 0;
}

运行后果:

留神:若间断用两个 getchar 函数,输出字符时 a 和 b 之间没有空格,间断输出。

如果分两行输出:

后果会怎么?

运行后果:

第 1 行是输出数据,输出 a 后按回车键。后果还未来得及输出 b,程序马上输入了其下 4 行后果(包含 2 个空行)。

因为第 1 即将 a 和换行符输出到内存的输出缓冲区,因而 c1 失去 a(ASCII 码为 97),c2 失去换行符(ASCII 码为 10)。再用 putchar 函数输入 c1,就输入了字符 a,在输入 c2 时,就把换行符转换为回车和换行两个操作,输入一个换行,前面的 printf(“\n”)又输入一个换行,所以就相当于输入一个空行,此行不显示任何字符。前面用 printf 函数输入 c1 和 c2,同样也输入了字符 a 和一个空行。

留神:在用间断两个 getchar 输出两个字符时,只有输出了“a”而后回车,零碎就会认为用户已输出了两个字符。所以该当间断输出 ab 两个字符而后再按回车键,这样就保障了 c1 和 c2 别离失去字符 a 和 b。

上面答复思考问题:

(1) cl 和 c2 能够定义为字符型或整型,二者皆可。

(2)能够用 printf 函数输入, 在 printf 函数中用 %d 格局符,即

printf("%d,%d\n" ,c1,c2);

(3)字符变量在计算机内占 1 个字节,而整型变量占 2 个或 4 个字节。因而整型变量在可输入字符的范畴内(ASCII 码为 0~127 的字符)是能够与字符数据相互转换的。如果整数在此范畴外,不能代替。

为了进一步阐明 char 型与 int 型数据的关系,请留神剖析以下 3 个程序。

程序 1:

#include <stdio.h>
int main()
{

    int c1, c2; // 定义整型变量 c1,c2
    printf("请输出两个整数 c1,c2:");
    scanf("%d,%d", &c1, &c2);
    printf("按字符输入后果:\n");
    printf("%c,%c\n", c1, c2);
    printf("按 ASCII 码输入后果为:\n");
    printf("%d,%d\n", c1, c2);
    return 0;
}

运行后果:

程序 2:

#include <stdio.h>
int main()
{

    char c1, c2; // c1,c2 定义为字符型变量
    int i1, i2;     // 定义整型变量
    printf("请输出两个字符 c1,c2:");
    scanf("%c,%c", &c1, &c2);
    i1 = c1; // 赋值给整型变量
    i2 = c2;
    printf("按字符输入后果:\n");
    printf("%c,%c\n", i1, i2);
    printf("按整数输入后果:\n");
    printf("%d,%d\n", c1, c2);
    return 0;
}

运行后果:

程序 3:

#include <stdio.h>
int main()
{
    char c1, c2; // c1,c2 定义为字符型
    int i1, i2;     // i1,i2 定义为整型.
    printf("请输出两个整数 i1,i2:");
    scanf("%d, %d", &i1, &i2);
    c1 = i1; // 将整数赋值给字符变量
    c2 = i2;
    printf("按字符输入后果:\n");
    printf("%c,%c\n", c1, c2);
    printf("按整数输入后果:\n");
    printf("%d,%d\n", c1, c2);
    return 0;
}

运行后果:

请留神 i,i1 和 i2 占 2 个或 4 个字节(Visual C++ 对它调配 4 个字节),而 c1 和 c2 是字符变量,只占 1 个字节。如果是 unsigned char 类型,能够寄存 0~255 的整数;如果是 signed char 类型,能够寄存 -128~127 范畴内的整数。而当初输出给 i1 和 i2 的值已超过 0~255 的范畴,i1 的值为 289,在内存中 i1 的存储状况如图 3.1(a)所示(为简略起见,用 2 个字节示意),在赋给字符变量 c1 时,只将其存储单元中最初一个字节(低 8 位)赋给 c1,见
图 3.1(b)。而图 3.1(b)中的数据是整数 33,是字符 ’!’ 的 ASCII 码,所以用字符模式输入 c1 时,会输入字符 ’!’。图 3.2 示意 i2 和 c2 的状况,c2 的值为 74,是字符 ’J’ 的 ASCII 码,因而,按字符模式输入 c2 时就输入字符 j ’。

正文完
 0