不使用全局变量,重写程序清单12.4
#include<stdio.h>
void critic(int *n){
printf("No luck, my friend. Try again.\n");
scanf("%d",n);
}
int main(void){
int units;
printf("How many pounds to a firkin of butter?\n");
scanf("%d", &units);
while(units != 56) critic(&units);
printf("You must have looked it up!\n");
return 0;
}
在美国,通常以英里/加仑来计算油耗;在欧洲,以升/100公里来计算。下面是程序的一部分,提示用户选择计算模式(美制或公制),然后接收数据并计算油耗。
//pe12-2b.c
//与pe12-2a.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(-1 to quit): ");
scanf("%d", &mode);
}
printf("Done.\n");
return 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 100km.
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函数根据设置的模式计算并显示油耗。可以假设用户输入的都是数值数据。
#ifndef PE12_2A_H_
#define PE12_2A_H_
void set_mode(int mode);
void get_info(void);
void show_info(void);
int mod;
double dis;
double fule;
#endif
#include<stdio.h>
#include "pe12-2a.h"
void set_mode(int m){
if((m !=0) && (m != 1)){
mod = 1;
printf("Invalid mode specified. Mode 1(US) used.");
}else{
mod = m;
}
}
void get_info(){
if(mod == 1){
printf("Enter distance travelde in miles:");
scanf("%lf", &dis);
while(getchar()!= '\n') continue;
printf("Enter fuel consumed in gallons:");
scanf("%lf", &fule);
while(getchar()!= '\n') continue;
}else{
printf("Enter distance travelde in kilometers:");
scanf("%lf", &dis);
while(getchar()!= '\n') continue;
printf("Enter fuel consumed in liters:");
scanf("%lf", &fule);
while(getchar()!= '\n') continue;
}
}
void show_info(){
double n = 0;
if(mod == 1){
n = dis/fule;
printf("Fuel consumption is %.2lf liters per gallon\n", n);
}else{
n = fule / (dis/100);
printf("Fuel consumption is %.2lf liters per 100 km\n", n);
}
}
#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(-1 to quit): ");
scanf("%d", &mode);
}
printf("Done.\n");
return 0;
}
重新设计编程练习2,要求只使用自动变量。该程序提供的用户界面不变,即提示用户输入模式等。但是函数调用要作相应变化。
#ifndef PE12_2A_H_
#define PE12_2A_H_
int set_mode(int mode);
void get_info(int mod, double* dis, double *fule);
void show_info(int mod, double dis,double fule);
#endif
#include<stdio.h>
#include "pe12-2a.h"
int set_mode(int m){
if((m !=0) && (m != 1)){
m = 1;
printf("Invalid mode specified. Mode 1(US) used.\n");
}
}
void get_info(int mod, double* dis, double *fule){
if(mod == 1){
printf("Enter distance travelde in miles:");
scanf("%lf", dis);
while(getchar()!= '\n') continue;
printf("Enter fuel consumed in gallons:");
scanf("%lf", fule);
while(getchar()!= '\n') continue;
}else{
printf("Enter distance travelde in kilometers:");
scanf("%lf", dis);
while(getchar()!= '\n') continue;
printf("Enter fuel consumed in liters:");
scanf("%lf", fule);
while(getchar()!= '\n') continue;
}
}
void show_info(int mod, double dis,double fule){
double n = 0;
if(mod == 1){
n = dis/fule;
printf("Fuel consumption is %.2lf liters per gallon\n", n);
}else{
n = fule / (dis/100);
printf("Fuel consumption is %.2lf liters per 100 km\n", n);
}
}
#include<stdio.h>
#include"pe12-2a.h"
int main(void){
int mode;
double dis,fule;
printf("Enter 0 for metric mode, 1 for US mode: ");
scanf("%d", &mode);
while(mode>=0){
mode = set_mode(mode);
get_info(mode, &dis, &fule);
show_info(mode,dis,fule);
printf("Enter 0 for metric mode, 1 for US mode(-1 to quit): ");
scanf("%d", &mode);
}
printf("Done.\n");
return 0;
}
在一个循环中编写并测试一个函数,该函数返回它被调用的次数。
#include<stdio.h>
int time(void){
static int n=0;
return ++n;
}
int main(void){
for(int i=0;i<10;++i)
printf("该函数被调用了%d次\n", time());
return 0;
}
编写一个程序,生成100个1~10范围内的随机数,并以降序排列(可以把第11章的排序算法稍加改动,便可用于整数排序,这里仅对整数排序)。
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
void sort(int*num, int m){
int t;
for(int i=0;i<m;++i){
for(int j=i;j<m;++j){
if(num[i]>num[j]){
t = num[i];
num[i] = num[j];
num[j] = t;
}
}
}
}
int main(void){
int num[100];
srand((unsigned int)time(0));
printf("生成的整数原来顺序为:\n");
for(int i=0;i<100;++i){
num[i] = rand()%10;
printf("%d\t", num[i]);
}
printf("\n");
sort(num,100);
printf("排序后的整数顺序为:\n");
for(int i=0;i<100;++i){
printf("%d\t", num[i]);
}
printf("\n");
return 0;
}
编写一个程序,生成1000个1~10范围内的随机数。不用保存或打印这些数字,仅打印每个数出现的次数,用10个不同的种子值运行,生成的数字出现的次数是否相同?可以使用本章自定义的函数或ANSIC 的rand和srand函数,他们的格式相同。这是一个测试特定随机数生成器随机性的方法。
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
int main(void){
int num[10]={0};
int n;
for(int t=0;t<10;++t){
srand((unsigned int)t);
printf("\n第%d次测试:\n",t);
for(int i=0;i<1000;++i){
n = rand()%10;
++num[n];
}
for(int i=0;i<10;++i){
printf("%d\t", num[i]);
}
printf("\n");
for(int i=0;i<10;++i) num[i] = 0;
}
return 0;
}
编写一个程序,按照程序清单12.13输出示例后面讨论的内容,修改程序。使其输出类似:
Enter the number of sets; enter q to stop: 18
How many sides and how many dice? 6 3
Here are 18 sets of 3 6-sided throws.
12 10 6 9 14 8 15 9 14 12 17 11 7 10 13 8 14
How many sets? Enter q to stop:q
#include<stdio.h>
#include<stdlib.h>
#include"diceroll.h"
int roll_count = 0;
static int rollem(int sides){
int roll;
roll = rand()%sides +1;
++roll_count;
return roll;
}
int roll_n_dice(int dice, int sides){
int d;
int total = 0;
if(sides<2){
printf("Need at least 2 sides.\n");
return -2;
}
if(sides<1){
printf("Need at least 1 die.\n");
return -1;
}
for(d = 0;d<dice;++d)
total += rollem(sides);
return total;
}
下面是程序的一部分:
//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:");
while(scanf("%d", &size) == 1 && size>0){
printf("Enter the initialization 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):");
}
printf("Done.\n");
return 0;
}
提供make_array和show_array函数的定义,完成该程序。make_array函数接受两个参数,第1个参数是int类型数组的元素个数,第2个参数是要赋给每个元素的值。该函数调用malloc创建一个大小合适的数组,将其每个元素设置为指定的值,并返回一个指向该数组的指针。show_array函数显示数组的内容,一行显示8个数。
#include<stdio.h>
#include<stdlib.h>
int* make_array(int elem, int val){
int* num = (int *)malloc(sizeof(int)*elem);
if(num){
for(int i=0;i<elem;++i)
num[i] = val;
}
return num;
}
void show_array(const int ar[], int n){
for(int i=0;i<n;++i){
printf("%d\t", ar[i]);
if(i%8 == 7) printf("\n");
}
printf("\n");
}
int main(void){
int *pa;
int size;
int value;
printf("Enter the number of elements:");
while(scanf("%d", &size) == 1 && size>0){
printf("Enter the initialization 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):");
}
printf("Done.\n");
return 0;
}
编写一个符合以下描述的函数。首先,询问用户需要输入多少个单词。然后,接受用户输入的单词,并显示出来,使用malloc并回答第1个问题(即要输入多少个单词),创建一个动态数组,该数组内含相应的指向const的指针(注意,由于数组的每个元素都指向char的指针,所以用于储存malloc返回值的指针应该是一个指向指针的指针,且它所指向的指针指向char)。在读取字符串时,该程序应该把单词读入一个临时的char数组,使用malloc分配足够的存储空间来储存单词,并把地址存入该指针数组(该数组中每个元素都是指向char的指针)。然后从临时数组中把单词拷贝到动态分配的存储空间中。因此,有一个字符指针数组,每个指针都指向一个对象,该对象的大小正浩能容纳被储存的特定单词。下面是该程序的一个运行示例:
How many words do you wish to enter? 5
Enter 5 words now:
I enjoyed doing this exerise
Here are your words:
1
I
enjoyed
doing
this
exercise
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
void copy_array(char *p, const char ar[]){
while(*ar)*p++ = *ar++;
}
int main(void){
int size;
printf("How many words do you wish to enter?");
scanf("%d", &size);
while(getchar()!='\n')continue;
char** p = (char**) malloc(sizeof(char*)*size);
printf("Enter %d words now: \n",size);
char t[20];
int i = 0;
while(scanf("%s", t) == 1 && i< size){
p[i] = (char*) malloc(sizeof(char)*strlen(t)+1);
copy_array(p[i],t);
++i;
}
if(p){
for(int j=0;j<i;++j)puts(p[j]);
}
if(p){
for(int j=0;j<i;++j){
if(p[i]) free(p[i]);
}
}
if(p) free(p);
printf("Done.\n");
return 0;
}