C Primer Plus (中文版)第12章编程练习 参考答案(仅供参考~)

C Primer Plus (中文版)第12章编程练习 参考答案(仅供参考~)

🌴 C Primer Plus第12章编程练习~ 加油加油!🍭
🍭这一章主要是各种存储变量的应用 同时也有多文件应用的题~
🌈加油,我们都会闪闪发光~⭐️

☘️欢迎大家讨论 批评指正~

第1题

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

**程序清单12.4**
#include <stdio.h>
int units = 0;    /* 外部变量 */
void critic(void);
int main(void)
{
    extern int units; /* 可选的重复声明 */
    printf("How many pounds to a firkin of butter?\n");
    scanf("%d", &units);
    while (units != 56) critic();
    printf("You must have looked it up!\n");
    return 0;
}
void critic(void)
{
    /* 删除了可选的重复声明 */
    printf("No luck, my friend. Try again.\n");
    scanf("%d", &units);
}
#include <stdio.h>
int critic(int units);
int main(void)
{
    int units,t; 
    printf("How many pounds to a firkin of butter?\n");
    scanf("%d", &units);
    while (units != 56) units=critic(units);
    printf("You must have looked it up!\n");
    return 0;
}
int critic(int units)
{
    /* 删除了可选的重复声明 */
    printf("No luck, my friend. Try again.\n");
    scanf("%d", &units);
    return units;
}

第2题

🍐2.在美国,通常以英里/加仑来计算油耗;在欧洲,以升/100 公里来计算。下面是程序的一部分,提示用户选择计算模式(美制或公制),然后接收数据并计算油耗。下面给出主程序。如果用户输入了不正确的模式,程序向用户给出提示消息并使用上一次输入的正确模式。
🍊 请提供pe12-2a.h头文件和pe12-2a.c源文件。
1️⃣源代码文件应定义3个具有文件作用域、内部链接的变量。一个表示模式、一个表示距离、一个表示消耗的燃料。2️⃣get_info()函数根据用户输入的模式提示用户输入相应数据,并将其储存到文件作用域变量中。3️⃣show_info()函数根据设置的模式计算并显示油耗。可以假设用户输入的都是数值数据。

#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;
}


下面是是一些输出示例:
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.c文件

#include"pe12-2a.h"
float distance=0.0,fuel_consumed=0.0;
int Mode=0;
void set_mode(int mode){    
    if(mode>1 && mode<0){
         printf("Invalid mode specified.");
         if(Mode==1) printf(" Mode 1(US) used.\n");
         else printf(" Mode 0(UK) used.\n");
         mode=Mode;
    }
    Mode=mode;

}
void get_info(void){
    if(Mode==0){
        printf("Enter distance traveled in kilometers:");
        scanf("%f",&distance);
        printf("Enter fuel consumed in liters: ");
        scanf("%f",&fuel_consumed);
    }
    if(Mode==1){
        printf("Enter distance traveled in miles:");
        scanf("%f",&distance);
        printf("Enter fuel consumed in gallons: ");
        scanf("%f",&fuel_consumed);
    }
    
}

void show_info(void){
    if(Mode==0){
        printf("Fuel consumption is %.2f liters per 100 km.\n",distance/fuel_consumed);
    }
    if(Mode==1){
        printf("Fuel consumption is %.2f miles per gallon.\n",distance/fuel_consumed);
    }
}

pe12-2a.h文件

/*
 * @Description:  pe12-2a.h
 * @Author: ~光~~
 * @Date: 2024-01-03 11:25:37
 * @LastEditTime: 2024-01-03 11:37:21
 * @LastEditors:  
 */
 
#ifndef _PE12_2A_H_
#define _PE12_2A_H_
#include<stdio.h>
void set_mode(int mode);
void get_info(void);
void show_info(void);


#endif 

第3题

🍌3.重新设计编程练习2,要求只使用自动变量。该程序提供的用户界面不变,即提示用户输入模式等。但是,函数调用要作相应变化。

1️⃣ 主函数

#include "pe12-2a.h"
int main(void)
{
    int mode,t=0;
    printf("Enter 0 for metric mode, 1 for US mode: ");
    scanf("%d",&mode);
    while (mode >= 0)
    {   
        t=set_mode(mode,t);
        show_info(t,get_info(t));
        printf("Enter 0 for metric mode, 1 for US mode");
        printf(" (-1 to quit): ");
        scanf("%d", &mode);
    }
    printf("Done.\n");
    return 0;
}

2️⃣pe12-2a.c文件

/*
 * @Description:  
 * @Author: ~光~~
 * @Date: 2024-01-03 12:51:01
 * @LastEditTime: 2024-01-03 13:14:07
 * @LastEditors:  
 */
/*下面是是一些输出示例:
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.*/


#include"pe12-2a.h"

int set_mode(int mode,int Mode){  
  
    if(mode!=1 && mode!=0){
         printf("Invalid mode specified.");
         if(Mode==1) printf(" Mode 1(US) used.\n");
         else printf(" Mode 0(UK) used.\n");
         mode=Mode;
    }
    Mode=mode;
    return Mode;
}
float get_info(int mode){
    float distance=0.0,fuel_consumed=0.0,res;
    if(mode==0){
        printf("Enter distance traveled in kilometers:");
        scanf("%f",&distance);
        printf("Enter fuel consumed in liters: ");
        scanf("%f",&fuel_consumed);
    }
    if(mode==1){
        printf("Enter distance traveled in miles:");
        scanf("%f",&distance);
        printf("Enter fuel consumed in gallons: ");
        scanf("%f",&fuel_consumed);
    }
    res=distance/fuel_consumed;
    return res;
}

void show_info(int mode,float res){
    if(mode==0){
        printf("Fuel consumption is %.2f liters per 100 km.\n",res);
    }
    if(mode==1){
        printf("Fuel consumption is %.2f miles per gallon.\n",res);
    }
}

3️⃣pe12-2a.h文件

/*
 * @Description:  pe12-2a.h
 * @Author: ~光~~
 * @Date: 2024-01-03 11:25:37
 * @LastEditTime: 2024-01-03 13:19:33
 * @LastEditors:  
 */
 
#ifndef _PE12_2A_H_
#define _PE12_2A_H_
#include<stdio.h>
int set_mode(int mode,int Mode);
float get_info(int mode);
void show_info(int mode,float res);


#endif 

第4题

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

/*
 * @Description:  在一个循环中编写并测试一个函数,该函数返回它被调用的次数。
 * @Author: ~光~~
 * @Date: 2024-01-03 14:26:53
 * @LastEditTime: 2024-01-03 14:31:24
 * @LastEditors:  
 */
#include<stdio.h>
int test(void);
int main(void){
    int t=0,count;
    printf("plese enter:(input is the numbers!):");
    while((1==scanf("%d",&t))){
        printf("输入字母退出\n");
        count=test();
        printf("count is %d\n",count);
        printf("enter:");
    }
    return 0; 
}
int test(void){
    static int i=0;
    printf("这是第%d次进入该函数\n",i+1);
    i++;
    return i;
}

第5题

🌿编写一个程序,生成100个1~10范围内的随机数,并以降序排列(可
以把第11章的排序算法稍加改动,便可用于整数排序,这里仅对整数排序)。

/*
 * @Description:  编写一个程序,生成100个1~10范围内的随机数,并以降序排列(可
以把第11章的排序算法稍加改动,便可用于整数排序,这里仅对整数排序)。
 * @Author: ~光~~
 * @Date: 2024-01-03 14:33:00
 * @LastEditTime: 2024-01-03 14:46:01
 * @LastEditors:  
 */
#include<stdio.h>
#include<stdlib.h>
#define SIZE 10 //可以更改SIZE的大小
int main(void){
    int nums[SIZE]={0};
    int i,j,max_j,tmp,max;

    //生成随机序列
    for(i=0;i<SIZE;i++){
        nums[i]=rand()%10+1;
    }
    printf("original nums are:");
    for(i=0;i<SIZE;i++){
        printf("%d ",nums[i]);
    }
    //选择排序
    for(i=0;i<SIZE;i++){
        max=nums[i];
        for(j=i;j<SIZE;j++){
            if(nums[j]>=max){
                max=nums[j];
                max_j=j;
            }
        }
        tmp=nums[i];
        nums[i]=nums[max_j];
        nums[max_j]=tmp;
    }

    printf("\nafter sort,nums are:");
    for(i=0;i<SIZE;i++){
        printf("%d ",nums[i]);
    }
    return 0; 
}

第6题

🌺6.编写一个程序,生成1000个1~10范围内的随机数。不用保存或打印这些数字,仅打印每个数出现的次数。
用 10 个不同的种子值运行,生成的数字出现的次数是否相同?//不同
可以使用本章自定义的函数或ANSI C的rand()和srand()函数,它们的格式相同。这是一个测试特定随机数生成器随机性的方法。

/*
 * @Description:  编写一个程序,生成1000个1~10范围内的随机数。不用保存或打印
这些数字,仅打印每个数出现的次数。用 10 个不同的种子值运行,生成的
数字出现的次数是否相同?//不同
可以使用本章自定义的函数或ANSI C的rand()和
srand()函数,它们的格式相同。这是一个测试特定随机数生成器随机性的方
法。
 * @Author: ~光~~
 * @Date: 2024-01-03 14:46:05
 * @LastEditTime: 2024-01-03 15:23:27
 * @LastEditors:  
 */
#include<stdio.h>
#include<stdlib.h>
#include <time.h>     
#define SIZE 10
int main(void){

    int t,i,nums,j,k=1;
    int count[SIZE+1]={0};
    do{
        srand((unsigned int)time(NULL));//随机种子
        printf("=====================\n");
        for(i=0;i<SIZE;i++){
            t=rand()%10+1;
           // printf("t is %d\n",t);//调试可用
            //count[t]++; 下面的相当于这一句;
            switch(t){
                case 1: count[t]++;
                break;
                case 2:count[t]++;
                break;
                case 3:count[t]++;
                break;
                case 4:count[t]++;
                break;
                case 5:count[t]++;
                break;
                case 6:count[t]++;
                break;
                case 7:count[t]++;
                break;
                case 8:count[t]++;
                break;
                case 9:count[t]++;
                break;
                case 10:count[t]++;
                break;
                
                default:break;
            }
        }
        
        printf("这是第%d次生成\n",k);
        printf("nums:counts \n");
        for(i=0;i<SIZE+1;i++){
            printf("%2d : %2d \n",i,count[i]);
        }
        //其中num是出现的数字  counts 是对应数字出现的次数
        
        //每一次整理完,再清空一次 否则会累加
        for(i=0;i<SIZE+1;i++){
            count[i]=0;
        }
    }while(k++<3);
    
    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 sets of 3 6-sided throws.
12 10 6 9 8 14 8 15 9 14 12 17 11 7 10 13 8 14
How many sets? Enter q to stop: q

/*
 * @Description:  
 注:此代码注释部分 均为可自用调试部分
 编写一个程序,按照程序清单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 8 14 8 15 9 14 12 17 11 7 10
13 8 14
How many sets? Enter q to stop: q

 * @Author: ~光~~
 * @Date: 2024-01-03 15:23:27
 * @LastEditTime: 2024-01-04 10:39:55
 * @LastEditors:  
 */
 
#include<stdio.h>
#include<string.h>
#include<ctype.h>
#include<stdlib.h>
#include<time.h>
int get_int(void);//又有数字又有字母
int get_int1(void);//对于纯数字的取值
int main(void){
    int i,j,number=0,sides,dice;
    printf("Enter the number of sets; enter q to stop : ");
    while(1){
        srand((unsigned int)time(0));
        number=get_int();
        printf("How many sides and how many dice?");
        printf("sides:");
        sides=get_int1();
        printf("dice:");
        dice=get_int1();
        printf("Here are %d sets of %d %d-sided throws.\n",number,sides,dice);
        for(i=0;i<number;i++) printf("%d ",rand()%number+1);
        printf("\nHow many sets? Enter q to stop:");
    }
    return 0; 
}
int get_int(void){
    int i,flag;
    int number=0;
    char input[10];
    while(1){ 
        flag=1;
        fflush(stdin);
        fgets(input,10,stdin);
        //printf("strlen(num) is %d\n",strlen(input));
        for(i=0;i<strlen(input)-1;i++){
         // printf("input[%d] is %c\n",i,input[i]);
            if(!isdigit(input[i])){
                //printf("%c不是数字\n",input[i]);
                flag=0;
                break;
            }
        }
       // printf("flag is %d\n",flag);
        if(flag){
            sscanf(input,"%d",&number);
           // printf("number is %d\n",number);
            return number;
        }else if(input[0]=='q'||input[0]=='Q') exit(0);
        else printf("incorrect type! please enter again:");
        
    }
}

int get_int1(void){
    int t,flag=1;
    int num;
    char c;
    while(flag){
        while((t=scanf("%d",&num))!=1){
            fflush(stdin);
            printf("incorrect type,try again:");
        }
        c=getchar();
        if(c!='\n') printf("incorrect type,try agein:");
        else  if(c=='\n') return num;
        fflush(stdin);
    }
    //为什么这么取 因为防止出现输入的是小数的情况 小数也是不合法的 
    //只有输入的是完全的整数才是合法的
}

第8题

🐬 8.提供make_array()和show_array()函数的定义,完成该程序。make_array()函数接受两个参数,第1个参数是int类型数组的元素个数,第2个参数是要赋给每个元素的值。该函数调用malloc()创建一个大小合适的数组,将其每个元素设置为指定的值,并返回一个指向该数组的指针。show_array()函数显示数组的内容,一行显示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: ");
	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;
}

解答部分

/*
 * @Description:  提供make_array()和show_array()函数的定义,完成该程序。make_array()
函数接受两个参数,第1个参数是int类型数组的元素个数,第2个参数是要赋
给每个元素的值。该函数调用malloc()创建一个大小合适的数组,将其每个
元素设置为指定的值,并返回一个指向该数组的指针。show_array()函数显
示数组的内容,一行显示8个数。
 * @Author: ~光~~
 * @Date: 2024-01-04 10:40:11
 * @LastEditTime: 2024-01-04 10:51:24
 * @LastEditors:  
 */
// 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;
}


int * make_array(int elem, int val){
/*make_array()
函数接受两个参数,第1个参数是int类型数组的元素个数,第2个参数是要赋
给每个元素的值。该函数调用malloc()创建一个大小合适的数组,将其每个
元素设置为指定的值,并返回一个指向该数组的指针。*/
    int *p;
    int i;
    p= (int *)malloc(elem * sizeof(int));
    if(p!=NULL){
        for(i=0;i<elem;i++){
            p[i]=val;
        }
    }
    
    return p;


}
void show_array(const int ar [], int n){
    int i;
    for(i=0;i<size;i++){
        printf("%d ",ar[i]);
        if((i+1)%8==0) printf("\n");
    }
}

🌿注意
在使用malloc()函数分配内存时,可能会出现分配失败的情况。如果分配失败,malloc()函数会返回一个空指针(NULL),表示无法分配指定大小的内存。在make_array()函数中,我们使用malloc()分配内存,并将返回的指针赋给arr。通过检查arr是否为空(即arr != NULL),我们可以判断内存是否分配成功。如果分配失败,arr将是一个空指针,无法访问和操作数组。因此,为了确保安全操作,我们需要在使用arr之前检查其是否有效。

在程序中,如果make_array()函数无法成功分配内存,则会返回一个空指针。在主函数中,我们通过条件判断if (pa)来检查是否分配成功。只有当pa不为空时,即分配成功时,才调用show_array()函数,避免访问无效的指针。

因此,添加if (arr != NULL)的判断是为了确保在成功分配内存后才继续操作数组,避免因为内存分配失败而导致程序出错。

第9题

🐋9.编写一个符合以下描述的函数。
1️⃣首先,询问用户需要输入多少个单词。
2️⃣然后,接收用户输入的单词,并显示出来,使用malloc()并回答第1个问
题(即要输入多少个单词),创建一个动态数组,该数组内含相应的指向
char的指针(注意,由于数组的每个元素都是指向char的指针,所以用于储
存malloc()返回值的指针应该是一个指向指针的指针,且它所指向的指针指向char
)。
3️⃣在读取字符串时,该程序应该把单词读入一个临时的char数组,使用malloc()分配足够的存储空间来储存单词,并把地址存入该指针数组(该数组中每个元素都是指向 char 的指针)。
4️⃣然后,从临时数组中把单词拷贝到动态分配的存储空间中。因此,有一个字符指针数组,每个指针都指向一个对象,该对象的大小正好能容纳被储存的特定单词。

下面是该程序的一个运行示例:

How many words do you wish to enter? 5
Enter 5 words now:
I enjoyed doing this exerise
Here are your words:
I
enjoyed
doing
this
exercise

解答部分

/*
 * @Description:  
 * @Author: ~光~~
 * @Date: 2024-01-04 10:56:58
 * @LastEditTime: 2024-01-04 12:03:40
 * @LastEditors:  
 */
/*
 * @Description:  编写一个符合以下描述的函数。首先,询问用户需要输入多少个单
词。然后,接收用户输入的单词,并显示出来,使用malloc()并回答第1个问
题(即要输入多少个单词),创建一个动态数组,该数组内含相应的指向
char的指针(注意,由于数组的每个元素都是指向char的指针,所以用于储
存malloc()返回值的指针应该是一个指向指针的指针,且它所指向的指针指向char)。
在读取字符串时,该程序应该把单词读入一个临时的char数组,
使用malloc()分配足够的存储空间来储存单词,并把地址存入该指针数组
(该数组中每个元素都是指向 char 的指针)。然后,从临时数组中把单词
拷贝到动态分配的存储空间中。因此,有一个字符指针数组,每个指针都指
向一个对象,该对象的大小正好能容纳被储存的特定单词。

How many words do you wish to enter? 5
Enter 5 words now:
I enjoyed doing this exercise
Here are your words:
I
enjoyed
doing
this
exercise

 * @Author: ~光~~
 * @Date: 2024-01-04 10:56:58
 * @LastEditTime: 2024-01-04 10:57:05
 * @LastEditors:  
 */
#include<stdio.h>
#include<ctype.h>
#include<stdlib.h>
#define SIZE 20 //每个单词至多20个字母
#define LEN 1000 //一行字符串的个数
int get_int1(void);//对于纯数字的取值
char *get_char(void);
int main(void){
    int num,i,j=0,k=0;
    char **words;
    char tmp[LEN];//临时的字符串数组
    printf("How many words do you wish to enter:");
    num=get_int1();
    printf("Enter %d words now:\n",num);
    words=(char**)malloc(sizeof(char*)*num); 
    if(words == NULL){
        printf("Error allocating memory\n");
        exit(EXIT_FAILURE);
    }
    fgets(tmp,LEN,stdin);
    words[0]=(char*)malloc(sizeof(char)*SIZE);
    if(words[0] == NULL){
        printf("Error allocating memory\n");
        exit(EXIT_FAILURE);
    }
    //一共有num个单词
    for(i=0;tmp[i]!='\0';i++){
        if(isalpha(tmp[i])){
            words[j][k]=tmp[i];
            k++;
        }
        if(tmp[i]==' '){
            words[j][k]='\0';
            j++;
            k=0;
            words[j]=(char*)malloc(sizeof(char)*SIZE);
            if(words[j] == NULL){
                printf("Error allocating memory\n");
                exit(EXIT_FAILURE);
            }
        }                
    }
    
   
    printf("Here are your words:\n");
    for(i=0;i<num;i++){
        fputs(words[i],stdout);
        printf("\n");
    }

    return 0; 
}

int get_int1(void){
    int t;
    int num;
    char c;
    while(1){
        while((t=scanf("%d",&num))!=1){
            fflush(stdin);
            printf("incorrect type,try again:");
        }
        c=getchar();
        if(c!='\n') printf("incorrect type,try agein:");
        else  if(c=='\n') return num;
        fflush(stdin);
    }
    //为什么再加getchar() 因为防止出现输入的是小数的情况 小数也是不合法的 
    //只有输入的是完全的整数才是合法的
}

⛵️完成啦~
☘️如果有其他解法~ 欢迎大家讨论 批评指正~
🌈 此编程练习参考答案为本人所写,如有错误欢迎大家批评指正~~ 如转载请说明来源~

🌈ok,完结~(●’◡’●) 看到这里 点个赞叭 (●’◡’●)

  • 33
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

~光~~

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值