《C语言程序设计》(谭浩强第五版) 第3章 最简单的的C程序设计——顺序程序设计 习题解析与答案

你也可以上程序咖(https://meta.chengxuka.com),打开大学幕题板块,不但有答案,讲解,还可以在线答题。

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

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

解:从主教材附录D(库函数)可以查到:可以用pow函数求的值,调用pow函数的具体形式是pow(x,y)。在使用pow函数时需要在程序的开头用# include指令将头文件包含到本程序模块中。可以用下面的程序求出10年后国民生产总值是现在的多少倍。

答案代码:

#include 
#include 
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年期本息和:

n年期本息和:
存n次1年期的本息和:

说明: 是一个季度的本息和。

解:设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 
#include 
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的公式如下:

可以将公式改写为

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

解:根据以上公式可以很容易写出以下程序。

答案代码:

#include 
#include 
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 
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 
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 
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 
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 
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 
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 
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 
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类型,可以存放-128127范围内的整数。而现在输入给i1和i2的值已超过0255的范围,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'。

你可能感兴趣的:(《C语言程序设计》(谭浩强第五版) 第3章 最简单的的C程序设计——顺序程序设计 习题解析与答案)