第十二章 存储类、链接和内存管理
编程练习
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"); }