C Primer Plus (第五版) 第十二章 存储类、链接和内存管理 编程练习

第十二章 存储类、链接和内存管理

编程练习

1.Q不使用全局变量,重写程序清单13.4

#include <stdio.h>;

int critic(int u);

int main(void)
{
	int units;

	printf("How many pounds to a firkin of butter?\n");
	scanf_s("%d", &units);
	while (units != 56)
		critic(units);
	printf("You must have looked it up!\n");

	return 0;
}

void critic(int u)
{
	printf("No luck, chummy. Try again.\n");
	scanf_s("%d", &u);

	return u;
}

2.在美国通常以英里每加化来计算油耗,在欧洲以升每百公里计算。下面是某程序的一部分,该程序让用户选择一个模式(公制或美制的),然后收集数据来计算油耗。

//pe12-2b.c

#include<stdio.h>

#include"pe12-2a.h"

int main(void)

{

int mode;

printf("Enter 0 for metric mode. 1 for US mode: ");

scnaf("%d", &mode);

while (mode >= 0)

{

set_mode(mode);

get_info();

show_info();

printf("Enter 0 for metric mode. 1 for US mode");

printf(" (-1 to quit):");

scanf("%d", &mode);

}

printf("Done.\n");

retrun 0;

}

下面是一些输出示例:

Enter 0 for metric mode. 1 for US mode :0

Enter distance traveled in kilometers: 600

Enter fuel consumed in liters: 78.8

Fuel consumption is 13.13 liters per 100 km.

Enter 0 for metric mode. 1 for US mode (-1 to quit):1

Enter distance traveled in miles : 434

Enter fuel consumed in gallons : 12.7

Fuel consumption is 34.2 miles per gallon.

Enter 0 for metric mode. 1 for US mode(-1 to quit) : 3

Invalid mode specified.Mode 1(US) used.

Enter distance traveled in miles : 388

Enter fuel consumed in gallons : 15.3

Fuel consumption is 25.4 miles per gallon.

Enter 0 for metric mode. 1 for US mode(-1 to quit) : -1

Done.

如果用户键入了不正确的模式,程序向用户给出提示信息并选取最接近的模式。请提供一个头文件pe12-2a.h和源代码文件pe12-2a.c,来使程序可以运行。源代码文件应定义3个具有文件作用域、内部链接的变量。一个代表模式,一个代表距离,还有一个代表消耗的燃料。函数get_info()根据模式设置提示输入相应的数据,并将用户的回答存入文件作用域变量。函数show_info()根据所选的模式计算并显示燃料消耗值。

//pe12-2b.c
#include <stdio.h>
#include "pe12-2a.h"
int main(void)
{
	int mode;

	printf("Enter 0 for metric mode. 1 for US mode: ");
	scanf("%d", &mode);
	while (mode >= 0)
	{
		set_mode(mode);
		get_info();
		show_info();
		printf("Enter 0 for metric mode. 1 for US mode");
		printf(" (-1 to quit):");
		scanf("%d", &mode);
	}
	printf("Done.\n");
	return 0;
}
//pe12_2a.h
#include <stdio.h>
#define ME 0
#define US 1

void set_mode(int);
void get_info(void);
void show_info(void);
//pe12-2a.c
#include <stdio.h>
#include "pe12-2a.h"

int mode;
double distance;
double fuel;

//根据用户输入确认模式
void set_mode(int n)
{
	if (n != ME && n != US)
	{
		printf("Invalid mode specified.Mode 1(US) used.\n");
		mode = US;
	}
	else
		mode = n;
}

/* 根据模式设置提示输入相应的数据,并将用户的回答存入文件作用域变量。 */
void get_info(void)
{
	if (ME == mode)
	{
		printf("Enter distance traveled in kilometers: ");
		scanf("%lf", &distance);
		printf("Enter fuel consumed in liters: ");
		scanf("%lf", &fuel);
	}
	else
	{
		printf("Enter distance traveled in miles : ");
		scanf_s("%lf", &distance);
		printf("Enter fuel consumed in gallons : ");
		scanf_s("%lf", &fuel);
	}
}
/* 根据所选的模式计算并显示燃料消耗值 */
void show_info(void)
{
	if (ME == mode)
	{
		printf("Fuel consumption is %.2lf liters per 100 km.\n",
			fuel / (distance / 100.00));
	}
	else
	{
		printf("Fuel consumption is %.1lf liters per 100 km.\n",
			distance / fuel);
	}
}

3.重新设计练习2中的程序,使它仅使用自动变量。程序提供相同的用户界面,也就是说,要提示用户输入模式等等。然而,您还必须给出一组不同的函数调用。

//pe12_2a.h
#include <stdio.h>
#define ME 0
#define US 1

void set_mode(int * pmode);
void get_info(int mode, double * distance, double * fuel);
void show_info(int mode, double distance, double fuel);
//pe12-2a.c
#include <stdio.h>
#include "pe12-2a.h"

//根据用户输入确认模式
void set_mode(int * pmode)
{
	if (*pmode != ME && *pmode != US)
	{
		printf("Invalid mode specified.Mode 1(US) used.\n");
		*pmode = US;
	}

}

/* 根据模式设置提示输入相应的数据,并将用户的回答存入文件作用域变量。 */
void get_info(int mode, double * distance, double * fuel)
{
	if (ME == mode)
	{
		printf("Enter distance traveled in kilometers: ");
		scanf("%lf", distance);
		printf("Enter fuel consumed in liters: ");
		scanf("%lf", fuel);
	}
	else
	{
		printf("Enter distance traveled in miles : ");
		scanf_s("%lf", distance);
		printf("Enter fuel consumed in gallons : ");
		scanf_s("%lf", fuel);
	}
}
/* 根据所选的模式计算并显示燃料消耗值 */
void show_info(int mode, double distance, double fuel)
{
	if (ME == mode)
	{
		printf("Fuel consumption is %.2lf liters per 100 km.\n",
			fuel / (distance / 100.00));
	}
	else
	{
		printf("Fuel consumption is %.1lf liters per 100 km.\n",
			distance / fuel);
	}
}
//pe12-2b.c
#include <stdio.h>
#include "pe12-2a.h"
int main(void)
{
	int mode;
	double distance, fuel;

	printf("Enter 0 for metric mode. 1 for US mode: ");
	scanf("%d", &mode);
	while (mode >= 0)
	{
		set_mode(&mode);
		get_info(mode, &distance, &fuel);
		show_info(mode, distance, fuel);
		printf("Enter 0 for metric mode. 1 for US mode");
		printf(" (-1 to quit):");
		scanf("%d", &mode);
	}
	printf("Done.\n");
	return 0;
}

4.编写一个函数,它返回自揣被调用的次数,并在一个循环中测试之。

#include <stdio.h>
int fun(void);

int main(void)
{
	int count;
	int i;
	printf("请输入测试次数:");
	while (scanf("%d", &i) == 1 && i > 0)
	{
		while (i--)
			count = fun();
		printf("函数累记被执行了%d次\n", count);
		printf("请输入测试次数:");
	}
	return 0;
}

int fun(void)
{
	static int count_fun = 0;
	return (++count_fun);
}

5.编写一个产生100个1到10范围内的随机数程序,并且以降序排序(可以将11章中的排序算法稍加改动来对整数进行排序。这里,对数字本身进行排序即可)。

#include <stdio.h>
#include <time.h>
#include <stdlib.h>
#define MAX 100
int main(void)
{
	int array[MAX];
	int i, j, temp;

	srand((unsigned)time(NULL));
	for (i = 0; i < MAX; i++)
	{
		array[i] = rand() % 10 + 1;
		printf("%3d", array[i]);
		if (i % 20 == 19)
			putchar(‘\n‘);
	}

	putchar(‘\n‘);
	for (i = 0; i < MAX - 1; i++)
	{
		for (j = i + 1; j < MAX; j++)
		{
			if (array[i] < array[j])
			{
				temp = array[i];
				array[i] = array[j];
				array[j] = temp;
			}
		}
	}
	for (i = 0; i < MAX; i++)
	{
		printf("%3d", array[i]);
		if (i %20 == 19)
			putchar(‘\n‘);
	}
	putchar(‘\n‘);

	return 0;
}

6.编写一个产生1000个1到10范围内的随机数程序。不必保存或打印数字,仅打印每个数被产生了多少次。让程序对10个不同的种子值进行计算。数字出现的次数想同吗?可以使用本章中的函数或ANSI C中的函数rand()和arand(),它们与我们的函数具有相同的形式。这是一个测试特定随机数发生器的随机性方法。

#include <stdio.h>
#include <time.h>
#include <stdlib.h>
#define MAX 1000
int main(void)
{
	int i, j = 0, num;

	srand((unsigned)time(NULL));
	while (j++ < 10)
	{
		int array[10] = { 0 };
		//srand((unsigned)time(NULL));
		//error: 十次的结果相同,原因可能是多次获取种子的单位时间相同。
		for (i = 0; i < MAX; i++)
		{
			num = rand() % 10 + 1;
			switch (num)
			{
			case 1: ++array[0]; break;
			case 2: ++array[1]; break;
			case 3: ++array[2]; break;
			case 4: ++array[3]; break;
			case 5: ++array[4]; break;
			case 6: ++array[5]; break;
			case 7: ++array[6]; break;
			case 8: ++array[7]; break;
			case 9: ++array[8]; break;
			case 10: ++array[9]; break;
			default:printf("Error\n"); break;
			}
		}
		for (i = 0; i < 10; i++)
		{
			printf("数字%2d共出现%3d次。\n", i + 1, array[i]);
		}
		putchar(‘\n‘);
	}

	return 0;
}

7.编写一个程序,该程序与我们在显示程序清单12.13的输出之后所讨论的修改版程序具有相同表现。也就是说,输出应像下面这样:

Enter the number of sets: enter q to stop.

18

How many sides and how many dice?

6 3

Here are 18 seta of 3 6 sided throws.

12 10 6 9 8 14 8 15 9 14 12 17 11 7 10

13 8 14

Here many sets? Enter q to stop.

q

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

int main(void)
{
	int sets = 0, sides = 0, dice = 0;
	int i, j, sum;

	srand((unsigned)time(NULL));
	puts("Enter the number of sets: enter q to stop.");
	while (scanf_s("%d", &sets) == 1)
	{
		puts("How many sides and how many dice?");
		scanf_s("%d%d", &sides, &dice);
		printf("Here are %d seta of %d %d sided throws.\n\t",
			sets, dice, sides);
		for (i = 0; i < sets; i++)
		{
			for (j = 0, sum =0; j < dice; j++)
			{
				sum += rand() % sides + 1;
			}
			printf("%d ", sum);
			if (i % 15 == 14)
				printf("\n\t");
		}
		puts("\nHere many sets? Enter q to stop.");
	}

	return 0;
}

8.下面是某程序的一部分:

//pe12-8.c

#include <stdio.h>

int * make_array(int elem, int val);

void show_array(const int ar[], int n);

int main(void)

{

int * pa;

int size;

int value;

printf("Enter the number of elements: ");

scanf("%d", &size);

while (size > 0)

{

printf("Enter the initlalization value: ");

scanf("%d", &value);

pa = make_array(size, value);

if (pa)

{

show_array(pa, size);

free(pa);

}

printf("Enter the number of elements (<1 to quit): ");

scanf("%d", &size);

}

printf("Done\n");

return 0;

}

给出函数make_array()和show_array()的定义以使程序完整。函数make_array()接受两个参数。第一个是int数组的元素个数,第二个是要赋给每个元素的值。函数使用malloc()来创建一个适当大小的数组,把每个元素设定为指定的值,并返回一个数组指针。函数show_array()以8个数一行的格式显示数组内容。

#include <stdio.h>
#include <stdlib.h>
int * make_array(int elem, int val);
void show_array(const int ar[], int n);
int main(void)
{
	int * pa;
	int size;
	int value;

	printf("Enter the number of elements: ");
	scanf_s("%d", &size);
	while (size > 0)
	{
		printf("Enter the initlalization value: ");
		scanf_s("%d", &value);
		pa = make_array(size, value);
		if (pa)
		{
			show_array(pa, size);
			free(pa);
		}
		printf("Enter the number of elements (<1 to quit): ");
		scanf_s("%d", &size);
	}
	printf("Done\n");
	return 0;
}
int * make_array(int elem, int val)
{
	int * pa;
	pa = (int *)malloc(sizeof(int)*elem);
	for (int i = 0; i < elem; i++)
		pa[i] = val;
	return pa;
}
void show_array(const int ar[], int n)
{
	int i;
	for (i = 0; i < n; i++)
	{
		printf("%d ", ar[i]);
		if (i % 8 == 7)
			printf("\n");
	}
	if (i%8!=0)
		printf("\n");
}
时间: 2024-10-13 15:21:25

C Primer Plus (第五版) 第十二章 存储类、链接和内存管理 编程练习的相关文章

C#高级编程第11版 - 第十二章

导航 C# 全版本特性一览 全书目录 第十二章 Language Integrated Query 12.1 LINQ 概述 243 12.1.1 列表和实体 244 12.1.2 LINQ 查询 246 12.1.3 扩展方法 246 12.1.4 推迟查询的执行 248 12.2 标准的查询操作符 249 12.2.1 筛选 250 12.2.2 用索引筛选 251 12.2.3 类型筛选 252 12.2.4 复合的from 子句 252 12.2.5 排序 253 12.2.6 分组 2

c++primer第五版第十九章练习

19.1 #include <iostream> #include <cstdlib> void *operator new(std::size_t n){ std::cout << "new(size_t)\n"; if (void *mem = malloc(n)) return mem; else throw std::bad_alloc(); } void operator delete(void *mem) noexcept{ std::c

c++primer第五版第十六章练习

16.1 根据模板参数的类型实例化出一个该类型的函数 16.2 #include <iostream> #include <string> #include <functional> //less //#include "../../7.21/7.21/标头.h" template<typename T> int compare(const T &a, const T &b) { if (std::less<T>

c++primer(第五版) 第十三章 拷贝控制习题答案

纯原创    转载请注明出处:http://blog.csdn.net/axuan_k 13.2    13.3   13.4    13.5 #include<iostream> using namespace std; class Point{ int a; }; Point global; //13.4 Point foo_bar(Point arg) //1 { Point local = arg, *heap = new Point(global); //2,3 *heap = lo

Python核心编程第二版 第十二章课后答案

12-1.路径搜索和搜索路径.路径搜索和搜索路径之间有什么不同? 前者是指查找某个文件的操作,后者是去查找一组目录. 12-2. 导入属性.假设你的模块mymodule里有一个foo()函数. (a)把这个函数导入到你的名称空间有哪两种方法? (b)这两种方法导入后的名称空间有什么不同? import mymodule from mymodule import foo 第一种将mymodule里的属性全部导入,第二种只导入foo 12-3.导入"import module"和"

魏兆辉的IOS基础学习笔记之十二 OC语言基础-07 Foundation内存管理

本篇博文,将给大家介绍下再Objective-C中如何使用内存管理.一个程序运行的时候,如果不及时的释放没有用的空间内存.那么,程序会越来 越臃肿,内存占用量会不断升高.我们在使用的时候,就会感觉很卡,最终使得程序运行奔溃.因此,将无效的内存及时清理释放,是非常有必要的. 一个对象在最初创建使用,到最后的回收释放,经历的是怎样一个过程呢?包括:诞生(通过alloc或new方法实现).生存(接收消息并执行操作).交友(通过复合以及向方法传递参数).最终死去(被释放掉). 一.引用计数 在对象创建的

《Unity_API解析》 第十二章 Transform类

Transform类继承自Component类,并实现了IEnumberable接口.Transform是GameObject必须拥有的一个组件,用来管理所在GameObject对象的坐标位置.旋转角度和大小缩放.由于Transform实现了Ienumberable接口,于是可以在程序中使用foreach()方法快速遍历子物体的Transform结构.即: void Start() { foreach (Transform item in transform) { } } Transform类实

第十二章:类

1:数据抽象,数据封装----类 2:数据抽象技术是接口,实现---分离:低层次的元素组合成高层次实体技术(例如函数). 3:利处:一是避免类内部无意破坏对象状态的用户级错误:二是可以根据需求完善实现,而不需要改变用户级代码. 4:内联函数是代码展开效果,所以使用处必须是定义处-即可见,类里默认定义函数则是内联函数,若体外定义,体内声明,则需要使用出定义函数: 5:不能重新定义:.h文件中不能定义函数,除非它是内联函数. 6:使用引用,或者指针:或者是在定义对象时,该类必须是定义完整的:否则出错

第十二章(类的无参方法)

Java注释:    //:单行注释    /**/:多行注释    /** */:JavaDoc注释 方法:   语法: 访问修饰符 返回值类型 方法名(){       方法体      } 举例:        public void run(){         System.out.println("");        }        public String robball(){         String ball="球";         r