【问题标题】:Why does my returned structure change negative values to positive in c?为什么我返回的结构在 c 中将负值变为正值?
【发布时间】:2014-12-24 17:56:13
【问题描述】:

这会创建一个分数并相应地分配负号。但是,当我想打印出整数、分子和分母时,负号不会传递到 fractionPrint 函数中。因此,仅打印出正值。

struct fraction fractionCreate(int numerator, int denominator)
{
    struct fraction result;
    if (denominator == 0)
    {
        result.numerator = 0;
        result.denominator = 0;
    }
    else
    {
        if (numerator*denominator <0)
        {

            int tempNumerator = fabs(numerator);
            int tempDenominator = fabs(denominator);
            int temp = 0;
            while(tempDenominator != 0)
            {
                temp = tempDenominator;
                tempDenominator = tempNumerator%tempDenominator;
                tempNumerator = temp;
            }
            int GCD = tempNumerator;

            numerator = fabs(numerator);
            denominator = fabs(denominator);
            //Num is larger than denom
            if(numerator>=denominator)
            {
                //whole number
                if(numerator%denominator == 0)
                {
                    result.wholeNumber = (numerator/denominator)*-1;
                    result.numerator = 1;
                    result.denominator = 1;
                }
                //mixed number
                else
                {
                    result.wholeNumber = ((numerator - (numerator%denominator)) /denominator)*-1;
                    numerator = (numerator%denominator);
                    if (numerator%GCD ==0 && denominator%GCD ==0)
                    {
                        result.numerator = numerator/GCD;
                        result.denominator= denominator/GCD;
                    }
                    else
                    {
                        result.numerator = numerator;
                        result.denominator = denominator;
                    }
                }
            }

            //simple fraction
            else
            {
                if (numerator%GCD ==0 && denominator%GCD ==0)
                {
                    result.numerator = (numerator/GCD)*-1;
                    result.denominator= denominator/GCD;
                }
                else
                {
                    result.numerator = numerator*-1;
                    result.denominator = denominator;
                }
            }
        }

        if (numerator*denominator > 0)
        {
            int tempNumerator = fabs(numerator);
            int tempDenominator = fabs(denominator);
            int temp = 0;
            while(tempDenominator != 0)
            {
                temp = tempDenominator;
                tempDenominator = tempNumerator%tempDenominator;
                tempNumerator = temp;
            }
            int GCD = tempNumerator;
            numerator = fabs(numerator);
            denominator = fabs(denominator);

            //Num is larger than denom
            if(numerator>=denominator)
            {
                //whole number
                if(numerator%denominator == 0)
                {
                    result.wholeNumber = numerator/denominator;
                    result.numerator = 1;
                    result.denominator = 1;
                }
                //mixed number
                else
                {
                    result.wholeNumber = (numerator - (numerator%denominator)) /denominator;
                    numerator = (numerator%denominator);
                    if (numerator%GCD ==0 && denominator%GCD ==0)
                    {
                        result.numerator = numerator/GCD;
                        result.denominator= denominator/GCD;
                    }
                    else
                    {
                        result.numerator = numerator;
                        result.denominator = denominator;
                    }
                }
            }

            //simple fraction
            else
            {
                if (numerator%GCD ==0 && denominator%GCD ==0)
                {
                    result.numerator = numerator/GCD;
                    result.denominator= denominator/GCD;
                }
                else
                {
                    result.numerator = numerator;
                    result.denominator = denominator;
                }
            }
        }
    }
    return result;
}

void fractionPrint(struct fraction f)
{
    if (f.numerator == 0 && f.denominator == 0)
    {
        printf("Divide by zero!\n");
    }
    else
    {
        // There IS a whole number
        if (f.wholeNumber !=0)
        {
            int tempNumerator;
            if (f.numerator <0)
            {
                tempNumerator = f.numerator *-1;
            }
            //ONLY whole number
            if (tempNumerator == 1 && f.denominator ==1 )
            {
                printf("%d\n", f.wholeNumber);
            }
            //Mixed number
            else
            {
                printf("%d %d/%d\n", f.wholeNumber, f.numerator, f.denominator);
            }
        }
        //fraction only
        else
        {
            printf("%d/%d\n", f.numerator, f.denominator);
        }
    }

}

int main (void)
{
    struct fraction a, b, c, d, r, bad;

    a = fractionCreate (-5, -6);
    fractionPrint(a);
    b = fractionCreate (-10, 2);
    fractionPrint(b);
    c = fractionCreate (56, -160);
    fractionPrint(c);
    d = fractionCreate (-35, 150);
    fractionPrint(d);
    bad = fractionCreate (8, 0);
    fractionPrint(bad);


    return 0;
}

【问题讨论】:

  • 添加struct fraction的定义
  • 编译时包含所有警告和调试信息 (gcc -Wall -Wextra -g)。然后使用调试器gdb;它的watch 命令可能很有用)。
  • 在 fractionPrint 中除以零检查应该只测试分母,如果它为零,那么分子是什么都没有关系。此外,当 f.numerator >=0 时,在注释 //ONLY whole number 之后的条件测试中可能未初始化 tempNumerator。
  • 你知道如何在调试模式下运行程序并跟踪它吗?你这样做了吗?如果这样做,应该很容易找到问题。此外,您的程序有太多的冗余代码。类似的代码应该聚集在一起(也许是函数)。比如GCD部分应该是一个函数,这样两个地方都可以调用同一个函数。请在询问之前尝试清理/简化您的程序。
  • 您可以使用几个在线编辑器/编译器来测试短程序并在线共享,例如,这是您的程序和我尝试编译的程序(这就是我发现潜在的未初始化的 tempNumerator - 编译器警告我)。 coliru.stacked-crooked.com/a/0347a1902eba89b6

标签: c function struct negative-number


【解决方案1】:

丢失的标志来自:

result.wholeNumber = (numerator/denominator)*-1;

这是在numerator * denominator &lt; 0 所在的块内,因此该行始终将wholeNumber 设置为正数。取出-1

另外,你在其他一些地方有垃圾,因为你没有在应该初始化的时候将wholeNumber 初始化为0。由于使用fabs 和四舍五入,当您尝试存储较大的值时会出现一个潜在的问题;使用整数否定而不是fabs

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-12-09
    • 2018-01-29
    • 2020-04-01
    • 1970-01-01
    • 2019-04-28
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多