C Primer Plus 第四章 复习题&编程练习 答案

复习题

1. 再次运行程序清单 4.1,但是在要求输入名时,请输入名和姓(根据英文书写习惯,名和姓中间有一个空格),看看会发生什么情况?为什么?

  程序不能正常运行。第1个 scanf()语句只读取用户输入的名,而用户输入的姓仍留在输入缓冲区中(缓冲区是用于储存输入的临时存储区)。下一条 scanf()语句在输入缓冲区查找重量时,从上次读入结束的地方开始读取。这样就把留在缓冲区的姓作为体重来读取,导致 scanf()读取失败。另一方面,如果在要求输入姓名时输入 Lasha144,那么程序会把144作为用户的体重(虽然用户是在程序提示输入体重之前输入了144)。

2. 假设下列示例都是完整程序中的一部分,它们打印的结果分别是什么?

a. printf(“He sold the painting for $%2.2f.\n”, 2.345e2);
b. printf(%c%c%c\n", ‘H’, 105, ‘\41’);
c. #define Q “His Hamlet was funny without being vulgar.”
  printf("%s\nhas %d characters.\n", Q, strlen(Q));
d. printf(“ls %2.2e the same as %2.2f?\n”, 1201.0, 1201.0);

a.He sold the painting for $234.50.
b.Hi!
c.His Hamlet was funny without being vulgar.
   has 42 characters.
d.Is 1.20e+003 the same as 1201.00?

3. 在第2题的c中,要输出包含双引号的字符串Q,应如何修改?

  printf(""%s"\nhas %d characters.\n", Q, strlen(Q));

4. 找出下面程序中的错误

define B booboo 
define X 10 
main(int) 
{ 
    int age; 
    char name; 
    printf("Please enter your first name."); 
    scanf("%s", name); 
    printf("All right, %c, what's your age?\n", name); 
    scanf("%f", age); 
    xp = age + X; 
    printf("That's a %s! You must be at least %d.\n", B, xp);
    rerun 0; 
}

答:

#include  			//别忘了要包含合适的头文件
#define B "booboo" 			//添加#和双引号
#define X 10 				//添加#
int main(void) 
{ 
    int age; 
    char name[20]; 			//把name声明为数组
    int xp;					//声明所有变量
    printf("Please enter your first name.\n");						//添加\n,提高可读性 
    scanf("%s", name); 
    printf("All right, %s, what's your age?\n", name); 				//%s 用于打印字符串
    scanf("%d", &age); 												//把%f改成%d,把age改成&age
    xp = age + X; 
    printf("That's a %s! You must be at least %d.\n", B, xp);
    return 0; 				//不是rerun
}

5. 假设一个程序的开头是这样:

#define BOOK “War and Peace”
int main(void) {
  float cost =12.99;
  float percent = 80.0;
请构造一个使用BOOK,cost和percent的printf()语句,打印以下内容:
This copy of “War and Peace” sells for $12.99.
That is 80% of list.

printf("This copy of \"%s\" sells for $%0.2f.\n", Book, cost);
printf("This is %0.0f%% of list\n", percent);

6. 打印下列各项内容要分别使用什么转换说明?

a. 一个字段宽度与位数相同的十进制整数       %d
b. 一个形如8A、字段宽度为4的十六进制整数     %4x
c. 一个形如232.346、字段宽度为10的浮点数     %10.3f
d. 一个形如2.33e+002、字段宽度为12的浮点数    %12.2e
e. 一个字段宽度为30、左对齐的字符串       %-30s

7. 打印下面各项内容要分别使用什么转换说明?

a. 一个字段宽度为15的unsigned long整数            %15lu
b. 一个形如0x8a、字段宽度为4的十六进制整数          %4x
c. 一个形如2.33E+02、字段宽度为12、左对齐的浮点数       %-12.2E
d. 一个形如+232.346、字段宽度为10的浮点数           %+10.3f
e. 一个字符串的前8个字符,字段宽度为8字符            %8.8s

8. 打印下面各项内容要分别使用什么转换说明?

a. 一个字段宽度为6、最少有4位数字的十进制整数          %6.4d
b. 一个在参数列表中给定字段宽度的八进制整数           % * o
c. 一个字段宽度为2的字符                   %2c
d. 一个形如+3.13、字段宽度等于数字中字符数的浮点数      %+0.2f
e. 一个字段宽度为7、左对齐字符串中的前5个字符          %-7.5s

9. 分别写出读取下列各输入行的scanf()语句,并声明语句中用到变量和数组。

a. 101
b. 22.32 8.34E-09
c. linguini
d. catch 22
e. catch 22(但是跳过catch)

a.

int a;
scanf("%d", &a)

b.

float a, b;
scanf("%f %f", &a, &b);

c.

char name[20];
scanf("%s", name)

d.

char zifu[20];
int value;
scanf("%s %d", zifu, &d);

e.

int value;
scanf("%*s %d", &value);

10. 什么是空白?

  包括:空格、制表符和换行符。

  C语言用空白分隔记号。

  scanf()使用空格分隔连续的输入项。

11. printf(“The double type is %z bytes…\n”, sizeof(double));这个语句有什么问题?如何修正?

  %z中的z是修饰符,不是转换字符,所以要在修饰符后面加上一个它修饰的转换字符。可以使用%zd打印十进制数,或用不同的说明符打印不同进制的数,例如,%zx打印十六进制的数。

12. 假设要在程序中用圆括号代替花括号,以下方法是否可行?

#define ( {
#define ) }

  可以,但是预编译器无法区分哪些该换哪些不该换,所有的()都会被替换为{}

编程练习

1. 编写一个程序,提示用户输入名和姓,然后以“名,姓”的格式打印出来。

#include
int main(void)
{
	char name[20];
	char surname[20];
	
	printf("输入名和姓:"); 
	scanf("%s %s", name, surname);
	printf("%s,%s",name,surname);
	
	return 0;
 } 

运行结果:
C Primer Plus 第四章 复习题&编程练习 答案_第1张图片

2. 编写一个程序,提示用户输入名和姓,并执行一下操作:

a. 打印名字,包括双引号
b. 在宽度为20的字段右端打印名和姓,包括双引号
c. 在宽度为20的字段左端打印名和姓,包括双引号
d. 在比姓名宽度宽3的字段中打印名字。

#include
#include  //包含strlen()函数的头文件
int main(void)
{
	char name[20];
	int nameLength; 
	
	printf("输入名和姓:");
	scanf("%s",name);
	nameLength = strlen(name);
	
	printf("\"%s\"\n",name);		//a. 打印名字,包括双引号
	printf("\"%20s\"\n",name);		//b. 在宽度为20的字段右端打印名和姓,包括双引号
	printf("\"%-20s\"\n",name);		//c. 在宽度为20的字段左端打印名和姓,包括双引号	
	printf("\"%*s\"\n",nameLength+3,name);	//d. 在比姓名宽度宽3的字段中打印名字。
	
	return 0;
 } 

运行结果:
C Primer Plus 第四章 复习题&编程练习 答案_第2张图片

3. 编写一个程序,读取一个浮点数,首先以小数点记数法打印,然后以指数记数法打印。用下面的格式进行输出(系统不同,指数记数法显示的位数可能不同):

a. The input is 21.3 or 2.1e+001.
b. The input is +21.290 or 2.129E+001.

#include 
int main(void)
{
	float count;
	printf("输入一个浮点数:"); 
	scanf("%f", &count);
	printf("The input is %.1f or %.1e.\n", count, count);
	printf("The input is %+.3f or %.3E.\n", count, count);
	return 0;
}

运行结果:
C Primer Plus 第四章 复习题&编程练习 答案_第3张图片

4. 编写一个程序,提示用户输入身高(单位:英寸)和姓名,然后以后面的格式显示用户刚输入的信息:Dabney, you are 6.208 feet tall 使用float类型,并用/作为除号。如果你愿意,可以要求用户以厘米为单位输入身高,并以米为单位显示出来

#include 
int main(void)
{
	float height;
	char name[20]; 
	printf("输入身高(单位:英寸)和姓名:");
	scanf("%f %s",&height,name);
	printf("%s, you are %.3f feet tall\n",name,height);
	
	float cmheight;
	char cmname[20];
	
	printf("输入身高(单位:厘米)和姓名:");
	scanf("%f %s",&cmheight,cmname);
	printf("%s, you are %.3f metre tall\n",cmname,cmheight/100);
	
	return 0; 
}

运行结果:
C Primer Plus 第四章 复习题&编程练习 答案_第4张图片

5. 编写一个程序,提示用户输入以兆位每秒(Mb/s)为单位的下载速度和以兆字节(MB)为单位的文件大小。程序中应计算文件的下载时间。注意,这里1字节等于8位。使用float类型,并用/作为除号。该程序要以下面的格式打印 3 个变量的值(下载速度、文件大小和下载时间),显示小数点后面两位数字:

At 18.12 megabits per second, a file of 2.20 megabytes
downloads in 0.97 seconds.

#include 
int main(void)
{
	float speed, size, time;
	printf("输入下载速度(Mb/s)和文件大小(MB):");
	scanf("%f %f",&speed,&size);
	time = size/(speed/8);
	printf("At %.2f megabits per second, a file of %.2f megabytes\n",speed,size);
	printf("downloads in %.2f seconds.\n",time);
	
	return 0;
}

运行结果:
C Primer Plus 第四章 复习题&编程练习 答案_第5张图片

6. 编写一个程序,先提示用户输入名,然后提示用户输入姓。在一行打印用户输入的名和姓,下一行分别打印名和姓的字母数。字母数要与相应名和姓的结尾对齐,如下所示:

Melissa Honeybee
    7     8
接下来,再打印相同的信息,但是字母个数与相应名和姓的开头对齐,如下所示:
Melissa Honeybee
7   8

#include 
#include 
int main(void){
	char first_name[20], last_name[20];
	int first_count, last_count;
	
    printf("先输入名,后输入姓:\n");
	scanf("%s %s",first_name,last_name);
	first_count = strlen(first_name);
	last_count = strlen(last_name);
	printf("打印用户输入的名和姓:%s %s\n",first_name,last_name);
	printf("分别打印名和姓的字母数:%d %d\n",first_count,last_count); 
    
	return 0;
}

运行结果:
C Primer Plus 第四章 复习题&编程练习 答案_第6张图片

7. 编写一个程序,将一个double类型的变量设置为1.0/3.0,一个float类型的变量设置为1.0/3.0。分别显示两次计算的结果各3次:一次显示小数点后面6位数字;一次显示小数点后面12位数字;一次显示小数点后面16位数字。程序中要包含float.h头文件,并显示FLT_DIG和DBL_DIG的值。1.0/3.0的值与这些值一致吗?

#include 
#include 
int main(void)
{
	double a = 1.0/3.0;
	float b = 1.0/3.0;
	
	printf("%.6f %.6f\n",a,b);
	printf("%.12f %.12f\n",a,b);
	printf("%.16f %.16f\n",a,b);
	printf("FLT_DIG=%d DBL_DIG=%d",FLT_DIG,DBL_DIG); //float类型、double类型最少有效数字位数
	
	return 0;
}

运行结果:
C Primer Plus 第四章 复习题&编程练习 答案_第7张图片

8. 编写一个程序,提示用户输入旅行的里程和消耗的汽油量。然后计算并显示消耗每加仑汽油行驶的英里数,显示小数点后面一位数字。接下来,使用1加仑大约3.785升,1英里大约为1.609千米,把单位是英里/加仑的值转换为升/100公里(欧洲通用的燃料消耗表示法),并显示结果,显示小数点后面 1 位数字。注意,美国采用的方案测量消耗单位燃料的行程(值越大越好),而欧洲则采用单位距离消耗的燃料测量方案(值越低越好)。使用#define 创建符号常量或使用 const 限定符创建变量来表示两个转换系数。

#include 
#define distance_CONVERT  1.609
#define Gasoline_CONVERT  3.785
int main(void)
{
	float distance, Gasoline_quantity; 
	printf("请输入旅行的里程(英里)和消耗的汽油量(加仑):");
	scanf("%f %f",&distance,&Gasoline_quantity);
	printf("显示消耗每加仑汽油行驶的英里数:%.1f\n",distance/Gasoline_quantity);
	printf("把单位是英里/加仑的值转换为升/100公里:%.1f\n",(Gasoline_quantity*Gasoline_CONVERT)/(distance*distance_CONVERT)*100);
	
	return 0;
}

运行结果:
C Primer Plus 第四章 复习题&编程练习 答案_第8张图片
在单位转换软件上,验证了一下运行结果:
C Primer Plus 第四章 复习题&编程练习 答案_第9张图片

你可能感兴趣的:(C Primer Plus 第四章 复习题&编程练习 答案)