代码之家  ›  专栏  ›  技术社区  ›  Vishva Modh

C语言作业中的If-else逻辑

c
  •  0
  • Vishva Modh  · 技术社区  · 10 月前

    这个问题与if else主题有关。我试图创建一个程序,让一个人输入他们的收入,该程序显示他们需要缴纳多少税款。

    #include<stdio.h>
    
    int main ()
    {
        float tax, income;
    
        printf("Kindly note down your income here\n");
        scanf("%f", income);
    
        if (income < 5.0 && income > 2.5)
        {
            printf("You have to pay 5 tax because your income is %f\n", income);
        }
        else if (income < 10.0 && income > 5.0)
        {
            printf("You have to pay 20 tax because your income is %f\n", income);
        }
        else if (income > 10.0)
        {        
            printf("You have to pay 30 tax because your income is %f\n", income);
        }
        else if (income < 2.5)
        {
            printf("You have to pay no tax because your income is %f\n", income);
        }
    
        return 0;
    }
    

    这就是我尝试过的。我哪里错了?

    2 回复  |  直到 10 月前
        1
  •  3
  •   Chris    10 月前

    而Allan Wind has identified 作为错误的来源,我进一步建议您通过更改顺序来重构条件,以减少需要测试的内容,因为您可以假设之前测试的所有条件都是假的。

        if (income < 2.5) {
            printf("You have to pay no tax because your income is %f\n", income);
        }
        else if (income < 5.0) {
            printf("You have to pay 5 tax because your income is %f\n", income);
        }
        else if (income < 10.0) {
            printf("You have to pay 20 tax because your income is %f\n", income);
        }
        else {
            printf("You have to pay 30 tax because your income is %f\n", income);
        }
    

    尽管它与这个非常简单的例子无关,但使用浮点数来处理货币是值得怀疑的,但使用单精度浮点数(与。 double )特别可疑,因为钱 可以 涉及大的数字,这使得单精度数字迅速变得不精确,导致计算错误。很少有哪类算术错误比那些涉及的错误更让人不安 .

    由于条件句是详尽无遗的( 分支是 总是 已执行)不需要初始化 tax 当它被声明时。

    为此修改Allan Wind的建议代码:

    #include <stdio.h>
    
    int main () {
        printf("Kindly note down your income here: ");
        double income;
        int rv = scanf("%lf", &income);
        if(rv != 1) {
            printf("scanf failed\n");
            return 1;
        }
    
        double tax;
        if (income < 2.5) 
            tax = 0;
        else if (income < 5.0) 
            tax = 5;
        else if (income < 10.0) 
            tax = 20;
        else 
            tax = 30;
    
        // Or even just:
        // double tax = (income <  2.5) ?  0 :
        //              (income <  5.0) ?  5 :
        //              (income < 10.0) ? 20 : 30;
    
        if (tax)
            printf("You have to pay %.2f tax because your income is %.2f\n", tax, income);
        else
            printf("You have to pay no tax because your income is %.2f\n",  income);
    }
    
        2
  •  3
  •   Allan Wind    10 月前

    编译器应该警告您没有传递类型为的变量 float * 对应的格式字符串 %f 。这是什么 gcc -Wall 说:

    1.c: In function ‘main’:
    1.c:8:17: warning: format ‘%f’ expects argument of type ‘float *’, but argument 2 has type ‘double’ [-Wformat=]
        8 |         scanf("%f", income);
          |                ~^   ~~~~~~
          |                 |   |
          |                 |   double
          |                 float *
    `
    

    修复方法是将其更改为:

    scanf("%f", &income);
    

    始终检查的返回值 scanf() 否则,您可能正在对未初始化的变量进行操作。

    要为指定一个值 tax 变量

    当你测试时 income 您可以跳过等于(下限或上限)的值。你想使用半开区间,比如说, [2.5, 5) 你会写为 income >= 2.5 && income < 5 。此外,请考虑以合乎逻辑的方式对条件进行排序。一旦你做到了这一点,你就可以消除下界,因为如果条件按顺序运行,就像@Chris向你展示的那样:

        double tax;
        if (income < 2.5) 
            tax = 0;
        else if (income < 5.0) 
            tax = 5;
        else if (income < 10.0) 
            tax = 20;
        else 
            tax = 30;
    

    下一个(可选)重构步骤是通过在将收入的最大界限映射到税收值的数组中查找税收值来消除重复的if-else条件:

    #include <values.h>
    
    // ...
    
        float tax_rates[][2] = {
            {2.5, 0},
            {5, 20},
            {FLT_MAX, 30}
        };
        size_t n = sizeof tax_rates / sizeof *tax_rates;
        float tax = tax_rates[n - 1][1];
        for(size_t i = 0; i < n - 1; i++) {
            if(income < tax_rates[i][0]) {
                tax = tax_rates[i][1];
                break;
            }
        }
    

    这种方法的主要好处是,速率表现在是可以独立于代码进行更改的数据。您可以从文本文件中读取税率,或下载权威来源(如果您在美国,则为IRS)。

    最后,我建议你消除类似的 printf() 陈述,你可能想告诉 输出函数 你想打印多少有效数字。我用了下面的2个:

    #include <stdio.h>
    
    int main () {
        printf("Kindly note down your income here: ");
        float income;
        int rv = scanf("%f", &income);
        if(rv != 1) {
            printf("scanf failed\n");
            return 1;
        }
    
        float tax = 0;
        if(income >= 2.5 && income < 5)
            tax = 5;
        else if(income >= 5 && income < 10)
            tax = 20;
        else if(income >= 10)
            tax = 30;
    
        if(tax)
            printf("You have to pay %.2f tax because your income is %.2f\n", tax, income);
        else
            printf("You have to pay no tax because your income is %.2f\n", income);
    }