前言

本人在通过《C语言程序设计:现代方法(第2版)》自学C语言时,发现国内并没有该书完整的课后习题答案,所以就想把自己在学习过程中所做出的答案分享出来,以供大家参考。这些答案是本人自己解答,并参考GitHub上相关的分享和Chegg.com相关资料。因为并没有权威的答案来源,所以可能会存在错误的地方,如有错误还希望大家能够帮助指出。

第三章练习题和编程题答案

练习题

3.1节

1.下面的printf函数调用产生的输出分别是什么?

(a)  printf("6d,%4d", 86, 1040);

(b) printf("%12.5e", 30.253);

(c) printf("%.4f", 83.162);

(d) printf("%-6.2g", .0000009979);

答:

(a) ┗━┛┗━┛┗━┛┗━┛86, 1040                   “%6d”表示右对齐、最小6个字段宽,数字只占了2个字段宽,所以前面用4个空格(┗━┛)补齐。同理“%4d”也是右对齐、最小4个字段宽,数字正好为4个字段宽,所有没有空格。
(b) 3.02530e+001                                             “%12.5e”表示右对齐、最小12个字段宽,同时小数点后显示5位数字,因为.0253不足5位,所以小数部分末尾会添加零占位。
(c) 83.1620                                                       “%.4f”表示小数点后显示4位,因为.162不足4位,所以小数部分末尾会添加零占位。
(d) 1e-006                                                        “%-6.2g”表示左对齐、最小6个字段宽,.2表示可以显示最大2个(去掉小数点后)有效数字。之所以显示1e是因为数字9979只能显示99这两个有效数字,所有后面的7会四舍五入向前进位,这样实际要显示的 数字就从.0000009979变成了.0000010000,所以结果显示为1e,如果将.2变为.3的话就会显示为9.98e-007。在%f和%e当中,如果需要舍弃小数点后部分数字,同样会使用这种四舍五入的显示方式。

2.编写printf函数调用,以下列格式显示float型变量x:

(a) 指数表示形式,字段宽度8,左对齐,小数点后保留1位数字。

(b) 指数表示形式,字段宽度10,右对齐,小数点后保留6位数字。

(c) 定点十进制表示形式,字段宽度8,左对齐,小数点后保留3位数字。

(d) 定点十进制表示形式,字段宽度6,右对齐,小数点后无数字。

答:

(a)  printf("%-8.1e", x);

(b)  printf("%10.6e", x);

(c)  printf("%-8.3f", x);

(d)  printf("6.0f", x);

3.2节

3.说明下列每对scanf格式串是否等价?如果不等价,请指出它们的差异。

(a) "%d"与" %d"

(b)"%d-%d-%d"与"%d -%d -%d"

(c)"f"与"%f "

(d)"%f,%f"与"%f, %f"

答:

(a) 等价,因为scanf在开始寻找数的时候会忽略掉空格,所以即使在前面添加任意个空格均不影响结果。

(b)不等价,虽然在开始是是scanf会忽略掉空格,但是开始读入之后并不会忽略。所以前者%d-%d-%d中不能在“-”之间加入任何空格,否则会异常退出,而后者%d -%d -%d则可以在“-”之间加入或不加入任意个空格

(c)不等价,第二个格式串中以空格作为结尾,虽然不影响录入%f中的数字,但是第二个格式串并不会在回车或空格后结束,它会一直等到读入第一个非空字符时才会结束。而第一个%f会在遇到空格或回车之类的符号后就结束运行。

(d)不等价,与(b)理由相同,第一个格式串中逗号直接不能加入任何空格,而第二个则可以加入0个或n个空格。

4.假设scanf函数调用的格式如下:

scanf("%d%f%d", &i, &x, &j);

如果用户录入

10.3 5 6

调用执行后,变量i、x和j的值分别是多少?(假设变量i和变量j都是int型,而变量x是float型。)

答:

最后的结果是i=10,x=0.3,j=5,

首先因为i是int型所以scanf会读入“10.”,但因为后面出现了小数点(“.”),而i中不能有小数点,所以只将10存入一种并将小数点“放回”去。

之后x是float型,但读入.3后因为遇到了非数字空格,所以scanf会将.3存入x中,而将空格“放回”。

最后的变量j在读取时会像跳过空白字符,直到遇到非空白字符5,而5之后又是非数字的空格,所以只会将5存入变量j中。

而因为此时这个scanf函数结束了,所以最后的数字6会被保留到下一次scanf函数调用时再读取。

5.假设scanf函数调用的是格式如下:

scanf("%f%d%f", &x, &i, &y);

如果用户输入

12.3 45.6 789

调用执行后,变量x、i和y的值分别是多少?(假设变量x和变量y都是float型,变量i是int型。)

答:

最后的结果是x=12.3,i=45,y=0.6

与上一道题类似,首先因为x是float型,所以scanf会读入“12.3”,之后遇到空格,此时结束读入并将12.3存入x中。

之后因为i是int型不能有小数点,所以scanf在读入“45.6”时只会将45存入i中,并将“.6”放回。

y是float型可以有小数点,所以scanf会将上次没有读入的“.6”存入y中,并在遇到空格时结束这次读入。

因为此时scanf函数已经执行完毕,所以最后的789会在下次scanf执行时才被读入。

6.指出如何修改3.2节中的addfrac.c程序,使用户可以输入在字符/的前后都有空格的分数

答:

 /*只需要在原程序中的/前后各加入一个空格即可 */
/* Adds two fractions */ #include <stdio.h> int main(void)
{
int num1, denom1, num2, denom2, result_num, result_denom; printf("Enter first fraction: ");
scanf("%d / %d", &num1, &denom1); /*至于要在原程序中的/前后各加入一个空格即可 */ printf("Enter second fraction: ");
scanf("%d / %d", &num2, &denom2); result_num = num1 * denom2 + num2 * denom1;
result_denom = denom1 * denom2;
printf("The sum is %d/%d\n", result_num, result_denom); return ;
}

编程题

1.编写一个程序,以月/日/年(即mm/dd/yy)的格式接受用户录入的日期信息,并以年月日(即yy/mm/dd)的格式将其显示出来:

Enter a date (mm/dd/yyyy): 2/17/2011

You entered the date 20110217

答:

 /*月日年转成年月日*/
#include <stdio.h> int main(void)
{
int day = , month = , year = ; printf("Enter a date (mm/dd/yyyy): ");
scanf("%d/%d/%d", &month, &day, &year); printf("You entered the date %.2d%.2d%d", year, month, day); /*月和日用%.2d显示,保证月份和日期会以两位数形式显示 */ return ;
}

2.编程一个程序,对于用户录入的产品信息进行格式化,程序会话应类似下面这样:

Enter item number: 583
Enter unit price: 13.5
Enter purchase date (mm/dd/yyyy): 10/24/2010
Item  Unit       Purchase
    price     Date
583   $   13.50    10/24/2010

其中,产品编号和日期项采用左对齐方式,单位价格采用右对齐方式,允许最大取值为9999.99的美元。提示:各个列使用制表符控制。

答:

 /*输入信息并显示,产品编号和日期左对齐,价格右对齐*/

 #include <stdio.h>

 int main(void)
{
/* 声明item number变量item_num,unit price变量price,日期变量day、month和year */
int item_num = , day = , month = , year = ;
/* unit price包含小数点,所以其变量应为float型 */
float price = 1.0f; /* 用户输入数据,程序录入对应变量中 */
printf("Enter item number: ");
scanf("%d", &item_num);
printf("Enter unit price: ");
scanf("%f", &price);
printf("Enter purchase date (mm/dd/yyyy): ");
scanf("%d/%d/%d", &month, &day, &year); printf("Item\t\tUnit\t\tPurchase\n"); /* 第一行显示,中间通过两个制表符\t分隔 */
printf("\t\tprice\t\tDate\n"); /* 第二行显示,中间通过两个制表符\t分隔 */
/* 编号和日期是左对齐,所以要在前面加上负号。价格采用%7.2f显示,是因为最大价格是9999.99共七位,在小于七位时用空格占位,.2则是保证小数点后只显示2位数字。 */
/* 日期中的.2是为了让最少以两位数形式显示,年份为四位数,所以采用.4保证最少显示四位数 */
printf("%-d\t\t$%7.2f\t%-.2d/%-.2d/%-.4d\n", item_num, price, month, day, year); return ;
}

3.图书用国际标准书号(ISBN)进行标识。2007年1月1日之后分配的ISBN包含13位数字(旧的ISBN使用10位数字),分为5组,如978-0-393-97950-3.第一组(GS1)目前为978或979.第二组(组标识)指明语言或者原出版社国(如0和1用于英语的国家)。第三组(出版商编号)便是出版商(393是W.W.Norton出版社的编号)。第四组(产品编号)是由出版商分配的用于识别具体哪一本书的(97950)。ISBN的末尾是一个校验数字,用于验证前面数字的准确性。编写一个程序来分解用户录入的ISBN信息:

Enter ISBN: 978-0-393-97950-3
GS1 prefix: 978
Group identifier: 0
Publish code: 393
Item number: 97950
Check digit: 3

注意:每组中数字的个数是可变的,不能认为每组的长度都与示例一样。用实际的ISBN值(通常放在书的封底和版权页上)测试你编写的程序。

答:

 /*ISBN分解*/

 #include <stdio.h>

 int main(void)
{
/* 第一组数字的变量定义为gs1,第二组数字的变量定义为group_id,第三组数字的变量定义为pub_code,第四组数字的变量定义为item_num,校验位定义为check_d */
int gs1 = , group_id = , pub_code = , item_num = , check_d = ; printf("Enter ISBN: ");
/* 每组数字看成一个整体,通过-来识别每组数字,并将其存入对应的变量中,这样每组数字个数即使发生变化也能正确的显示出来 */
scanf("%d-%d-%d-%d-%d", &gs1, &group_id, &pub_code, &item_num, &check_d); /* 直接将每组变量分别显示出来即可 */
printf("GS1 prefix: %d\nGroup identifier: %d\nPublish code: %d\nItem number: %d\nCheck digit: %d\n", gs1, group_id, pub_code, item_num, check_d); return ;
}

4.编写一个程序,提示用户以[(xxx)xxx-xxx]的格式输入电话号码,并以xxx.xxx.xxxx的格式显示该号码:

Enter phone number [(xxx) xxx-xxxx]: (404) 817-6900
You entered: 404.817.6900

答:

 /*输入电话号码(xxx) xxx-xxxx并转换格式显示xxx.xxx.xxxx */

 #include <stdio.h>

 int main(void)
{
/* 将电话号码拆分成3组,分别定义成num1、num2和num3 */
int num1 = , num2 = , num3 = ; printf("Enter phone number [(xxx) xxx-xxxx]: ");
/* 根据提示的格式分别将3组数字存入变量中 */
scanf("(%d) %d-%d", &num1, &num2, &num3); printf("You entered: %d.%d.%d\n", num1, num2, num3); return ;
}

5.编写一个程序,要求用户(按任意次序)输入从1到16的所有整数,然后用4×4矩阵的形式将它们显示出来,再计算每行、每列和每条对角线上的和:

Enter the numbers from 1 to 16 in any order: 16 3 2 13 5 10 11 8 9 6 7 12 4 15 14 1
16    3      2    13
5    10    11      8
9      6      7    12
4    15    14      1

Row sums: 34 34 34 34
Column sums: 34 34 34 34
Diagonal sums: 34 34

如果行、列和对角线上的和都一样(如本例所示),则称这些数组成一个幻方(magic square)。这里给出的幻方出现于艺术家和数学家Albrecht Dürer在1514年的一幅画中。(注意,矩阵的最后一行中间的两个数给出了该画的创作年代。)

答:

 /*输入1到16所有整数,以4*4显示,并计算每行、每列、和对角线的和 */

 #include <stdio.h>

 int main(void)
{
/* 定义十六个数字的变量,从num1到num16 */
int num1 = , num2 = , num3 = , num4 = , num5 = , num6 = , num7 = , num8 = ;
/* 拆成两行定义是因为写在一行里实在是太长了,不方便阅读 */
int num9 = , num10 = , num11 = , num12 = , num13 = , num14 = , num15 = , num16 = ;
/* 定义4×4矩阵的每行和的变量,从row1到row4 */
int row1 = , row2 = , row3 = , row4 = ;
/* 定义4×4矩阵的每列和的变量,从col1到col4 */
int col1 = , col2 = , col3 = , col4 = ;
/* 定义两个对角线和的变量dia1和dia2 */
int dia1 = , dia2 = ; printf("Enter the numbers from 1 to 16 in any order: ");
/* 将十六个数字分别存入到16个变量里 */
scanf("%d%d%d%d%d%d%d%d", &num1, &num2, &num3, &num4, &num5, &num6, &num7, &num8);
/* 同样因为太长了,所以拆成两行写 */
scanf("%d%d%d%d%d%d%d%d", &num9, &num10, &num11, &num12, &num13, &num14, &num15, &num16); /* 显示出矩阵,根据题目示例,每个数字应该保证两个字符宽,右对齐。通过制表符来使每行和每列对齐 */
printf("%2d\t%2d\t%2d\t%2d\t\n%2d\t%2d\t%2d\t%2d\t\n", num1, num2, num3, num4, num5, num6, num7, num8);
printf("%2d\t%2d\t%2d\t%2d\t\n%2d\t%2d\t%2d\t%2d\t\n\n\n", num9, num10, num11, num12, num13, num14, num15, num16); /* 计算每行的和 */
row1 = num1 + num2 + num3 + num4;
row2 = num5 + num6 + num7 + num8;
row3 = num9 + num10 + num11 + num12;
row4 = num13 + num14 + num15 + num16; /* 计算每列的和 */
col1 = num1 + num5 + num9 + num13;
col2 = num2 + num6 + num10 + num14;
col3 = num3 + num7 + num11 + num15;
col4 = num4 + num8 + num12 + num16; /* 计算两个对角线的和 */
dia1 = num1 + num6 + num11 + num16;
dia2 = num4 + num7 + num10 + num13; /* 显示结果 */
printf("Row sums: %d %d %d %d \nColumn sums: %d %d %d %d \n", row1, row2, row3, row4, col1, col2, col3, col4);
printf("Diagonal sums: %d %d \n", dia1, dia2); return ;
}

6.修改3.2节的addfrac.c程序,使用户可以同时输入两个分数,中间用加好隔开:

Enter two fractions separated by a plus sign: 5/6+3/4
The sum is: 38/24

答:

 /*同时输入两个分数并计算*/

 #include <stdio.h>

 int main(void)
{
/* 定义两个分数的变量,分子分别是x1和x2,分母是y1和y2 */
int x1 = , y1 = , x2 = , y2 = ;
/* 计算出的分子用result_num变量表示,分母用result_denom变量表示 */
int result_num = , result_denom = ; printf("Enter two fractions separated by a plus sign: ");
/* 读取两个分数 */
scanf("%d/%d+%d/%d", &x1, &y1, &x2, &y2); /* 计算两个分数的和 */
result_num = x1 * y2 + x2 * y1;
result_denom = y1 * y2;
printf("The sum is: %d/%d\n", result_num, result_denom); return ;
}

C语言程序设计:现代方法(第2版)第三章全部习题答案的更多相关文章

  1. C语言程序设计:现代方法(第2版)第二章全部习题答案

    前言 本人在通过<C语言程序设计:现代方法(第2版)>自学C语言时,发现国内并没有该书完整的课后习题答案,所以就想把自己在学习过程中所做出的答案分享出来,以供大家参考.这些答案是本人自己解 ...

  2. CSAPP深入理解计算机系统(第二版)第三章家庭作业答案

    <深入理解计算机系统(第二版)>CSAPP 第三章 家庭作业 这一章介绍了AT&T的汇编指令 比较重要 本人完成了<深入理解计算机系统(第二版)>(以下简称CSAPP) ...

  3. C语言学习书籍推荐《C语言程序设计 现代方法(第2版)》下载

    下载地址:点我 C语言仍然是计算机领域的通用语言之一,但现在的C语言已经和当初的时候大不相同了.本书主要的一个目的就是通过一种“现代方法”来介绍C语言,书中强调标准C,强调软件工程,不再强调“手工优化 ...

  4. C语言程序设计现代方法_基本类型(第七章)

    C语言支持两种不同的数值类型,整数类型,浮点类型. C语言的整数类型有不同的尺寸.int类型通常为32位,但在老的CPU上可能是16位.有些可能是64位. 因此,int型如果在16位CPU上最大值就是 ...

  5. C语言程序设计现代方法1,2,3章

    1:浮点型(float)运算比int慢,并且可能存在舍入误差 如float存储0.1,以后使用可能会变成0.099999999987 2:宏定义只用大写,这是大多数C程序猿遵循的规范! C语言区分大小 ...

  6. Java语言程序设计(第三版)第二章课后习题答案(仅供参考)

    2.1   注意不同类型转换 import java.util.Scanner; public class Ch02 { public static void main(String[] args) ...

  7. java编程思想第四版第三章要点习题

    使用"简短的" 和正常的 打印语句来编写一个程序 package net.mindview.util; public class Print { /** * 不带有回车 * @pa ...

  8. python语言程序设计基础(嵩天)第三章课后习题部分个人练习

    p69: *题3.5: 源代码: (1)print(30-3**2+8//3**2*10)     答案:21 (2)print(3*4**2/8%5)     答案:1.0 (3)print(2** ...

  9. C语言程序设计-现代方法(笔记1)

    第一章 C语言概述 1.C语言的历史(1.1) 起源:贝尔实验室开发的UNIX操作系统的副产品.标准化:C89和C99.基于C的语言:C++,Java,C#,Perl. 2.C语言的优缺点(1.2) ...

随机推荐

  1. [翻译] WZFlashButton

    WZFlashButton This is a custom button with flash-like effect. Inspired by Ripple Effect. 这是一个自定义的按钮, ...

  2. INSERT CLAUSE

    a.single table insert INSERT INTO jobs(job_id,job_title,min_salary,Max_Salary) VALUES('IT_PM','PROJE ...

  3. 计算机作业(Excel工资表) 物联网 王罗红

  4. 【心得体会】我考完MOS我明白了…

    [心得体会]我考完MOS我明白了… 原创 2017-11-10 MSP-李桑榆 MSPrecious成长荟 MOS备考 这篇文章写给还没有考或者准备考MOS的同学 网上有很多介绍MOS考试的 http ...

  5. ELK系统分析Nginx日志并对数据进行可视化展示

    结合之前写的一篇文章:ELK日志分析平台搭建全过程,上篇文章主要讲了部署方法.而这篇文章介绍的是单独监控nginx 日志分析再进行可视化图形展示. 本文环境与上一篇环境一样,前提 elasticsea ...

  6. SQL server reporting service - rsReportServerNotActivated error solution

    描述: 今天在原有的数据库版本上增加了Reporting Service 功能,数据库完成安装后,没有发现ReportServer和 ReportServerTemp 两个数据库 于是从其他服务器上, ...

  7. December 29th 2016 Week 53rd Thursday

    The true nobility is in being superior to your previous self. 真正的高贵在于超越过去的自己. It is really difficult ...

  8. Spotlight监控Linux服务器

    1.安装 Spotlight on Unix 下载地址:http://worlddownloads.quest.com.edgesuite.net/Repository/www.quest.com/l ...

  9. 虚拟机下的CentOS无法上网的解决办法

    1.首先保证虚拟机的网络适配器为NAT模式 2.设置虚拟机的“编辑”-->“虚拟网络编辑器”中的VMnet8的DHCP的设置两个选项都勾选上. 3.设置物理主机,保证虚拟网关的IP地址为自动获取 ...

  10. c++ 基类,派生类的类型兼容性

    #include <iostream> using namespace std; class CFather { public: void display() const { cout&l ...