C primer plus (第六版)第十二章 编程练习第3题

题目:

3.重新设计编程练习2,要求只使⽤⾃动变量。该程序提供的⽤⼾界⾯不变,即提⽰⽤⼾输⼊模式等。但是,函数调⽤要作相应变化。

思路1:

  • 因为在编程练习2中用的是全局变量在函数set_mode(); get_info(); show_info();之间传递mode值,fuel_consume值与distance值,相对简单,如果限定只使用自动变量,需要注意的是get_info()函数,因为正常函数只能返回一个值,但是get_info()之前的功能是需要读入fuel_consume与distance这2个值并在show_info()函数中计算并显示,这种情况下需要将计算步骤迁移至get_info()函数,并让get_info()返回计算好的一个值,show_info()函数只负责显示最终的结果即可;
  • 演示程序:
cpp 复制代码
//需要存为pe12-3a.h
int set_mode(int mode);
double get_info(int mode);
void show_info(int mode, double result);
cpp 复制代码
//pe12-3a.c
#include <stdio.h>
// set_mode()函数目的是直接将mode值设为0或1(>0的都设为1)
int set_mode(int mode)
{
    if (mode == 0)
        return 0;
    else
        return 1;
}
// get_info()函数的目的是根据mode的值,输入里程和油耗并计算,返回计算值
double get_info(int mode)
{
    float distance;  
    float fuel_consume;
    int mode_code;
    double mode_0_result;
    double mode_1_result;
    mode_code = mode;

    if (mode_code == 0)
    {
        puts("Enter distance traveled in kilometers:");
        while (scanf("%d", &distance) == 1 && distance > 0)
        {
            puts("Enter fuel consumed in liters:");
            break;
        }
        while (scanf("%d", &fuel_consume) == 1 && fuel_consume > 0)
        {   
            mode_0_result = 100.0*fuel_consume/distance;
            break;
        }
        return mode_0_result;    //因为函数没法返回两个值,所以只能提前计算好结果返回
    }

    if (mode_code == 1)
    {
        puts("Enter distance traveled in miles:");
        while (scanf("%d", &distance) == 1 && distance > 0)
        {
            puts("Enter fuel consumed in gallons:");
            break;
        }
        while (scanf("%d", &fuel_consume) == 1 && fuel_consume > 0)
        {
            mode_1_result = distance/fuel_consume;
            break;
        }
        return mode_1_result;   //因为函数没法返回两个值,所以只能提前计算好结果返回
    }    
}
//show_info()函数根据mode值显示计算结果
void show_info(int mode, double result)
{
    int mode_code = mode;
    double mode_result = result;

    if (mode_code == 0)
    {
        printf("Fuel consumption is %.2f liters per 100 km.\n",mode_result);
    }
    if (mode_code == 1)
    {
        printf("Fuel consumption is %.2f miles per gallon.\n",mode_result);
    }    
}
cpp 复制代码
//需要存为pe12-3b.c
#include <stdio.h>
#include "pe12-3a.h"
int main(void)
{
    int mode;
    printf("Enter 0 for metric mode, 1 for US mode: ");
    scanf("%d", &mode);
    while (mode >= 0)
    {
        int mode_return = set_mode(mode);
        double result_return = get_info(mode_return);
        show_info(mode_return, result_return);
        printf("Enter 0 for metric mode, 1 for US mode");
        printf(" (-1 to quit): ");
        scanf("%d", &mode);
    }
    printf("Done.\n");
    return 0;
}

思路2:

  • 可以参考原书答案,通过指针的形式传递mode值,fuel_consume值与distance值;
  • 参考代码如下:
cpp 复制代码
//存为pe12-3a.h
#define METRIC 0
#define US 1
#define USE_RECENT 2

void check_mode(int *pm);               //point of mode 缩写
void get_info(int mode, double *pd, double *pf);        //point of distance 与point of fuel缩写
void show_info(int mode, double distance, double fuel);
cpp 复制代码
//存为pe12-3a.c
//compile with pe12-3b.c
#include <stdio.h>
#include "pe12-3a.h"

void check_mode(int *pm)
{
    if (*pm != METRIC && *pm != US)     //处理非0与非1的mode数值
    {
        printf("Invalid mode specified. Mode %d\n", *pm);
        printf("Previous mode will be used.\n");
        *pm = USE_RECENT;
    }
}

void get_info(int mode, double *pd, double *pt)     //通过指针形式存入距离与油耗参数
{
    if (mode == METRIC)
        printf("Enter distance traveled in kilometers: ");
    else
        printf("Enter distance traveled in miles: ");
    scanf("%lf",pd);
    if (mode == METRIC)
        printf("Enter fuel consumed in liters: ");
    else
        printf("Enter fuel consumed in gallons: ");
    scanf("%lf",pf);
}

void show_info(int mode, double distance, double fuel)  
{
    printf("Fuel consumption is ");
    if (mode == METRIC)
        printf("%.2f liters per 100 km.\n", 100 * fuel / distance);
    else
        printf(".1f miles per gallon.\n", distance / fuel);
}
cpp 复制代码
//pe12-3b.c
//complie with pe12-3a.c
#include <stdio.h>
#include "pe12-3a.h"
int main()
{
    int mode;
    int prev_mode = METRIC;
    double distance, fuel;

    printf("Enter 0 for metric mode, 1 for US mode: ");
    scanf("%d", &mode);
    while (mode >= 0)
    {
        check_mode(&mode);
        if (mode == USE_RECENT)
            mode = prev_mode;
        prev_mode = mode;       //根据第一次输入结果重置prev_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;
}
相关推荐
是隼人8 小时前
buuctf-pwn xdctf2015_pwn200题解(学习过程持续更新)
c语言·学习·安全·pwn入门·ctf入门
布莱克60511 小时前
数组详解:定义、作用、应用场景及与链表的区别(C/C++ 代码讲解)
c语言·开发语言·c++·数组
hongmai66688811 小时前
MP2348GTL-Z:这颗24V/4A同步降压芯片,把性能和体积平衡得恰到好处
c语言·开发语言·arm开发·单片机·5g
多弗朗皮卡丘11 小时前
C语言梦开始的地方19:文件操作
c语言·开发语言
万法若空12 小时前
C/C++ 类型别名定义方式对比
java·c语言·c++
一直C15 小时前
Linux系统编程|进程间通信IPC全套详解(1)(管道、信号)
linux·c语言·开发语言·网络·青少年编程·visual studio code
春风解人意15 小时前
从零开始学习嵌入式P28----线程
c语言·学习·算法
luj_176815 小时前
合法避税与投资评估实战指南
c语言·开发语言·网络·经验分享·算法
一直C16 小时前
Linux系统编程|信号进阶 + SystemV IPC(消息队列、共享内存)
linux·c语言·开发语言·算法·青少年编程·vim
新时代牛马16 小时前
SPL-TPL 链式启动:spl.c 与CONFIG_TPL 三阶段加载
c语言·开发语言