打印多个输出输出0

时间:2017-08-28 12:32:44

标签: c printf

我在c中练习编程,但我遇到了一个我似乎无法弄清楚的问题。我有一个printf语句,其中包含两个不同int值的标记。无论第一个int是什么,它都会打印0,但第二个int会正常打印。这是代码:

#include <stdio.h>
#include <stdlib.h>

int a, temp;
int toBinary();
int toDecimal();

int main()
{
    char c;
    for(;;)
    {
        scanf("%d",&a);
        scanf(" %c",&c);
        switch(c)
        {
            case 'a' :
                printf("%d converted to binary: %d\n",a,toBinary());
                break;
            case 'b' :
                printf("%d converted to decimal: %d\n",a,toDecimal());
                break;
            case 'c' :
                printf("EXIT\n");
                return 0;
                break;
            default :
                printf("ERROR c value: %c\n",c);
                return 0;
        } 
    }
}
int toBinary()
{
    if (a == 0)
        return 0;
    else
    {
        temp = a;
        a /= 2;
        return (temp % 2 + 10 * toBinary());
    }
}
int toDecimal()
{
    int res=0, base = 1, rem;
    while (a > 0)
    {
        rem = a % 10;
        res = res + rem * base;
        a /= 10;
        base *= 2;
    }
    return res;
}

问题是前两种情况中的printf语句忽略int a的实际值,但它通常用于两个函数的值。我不确定错误是什么,因为在a声明中scanf之前已经给出了值,而我在文本中使用了正确的标记。

3 个答案:

答案 0 :(得分:5)

由于未指定参数评估的顺序,因此这是未定义的行为。

最简单的解决方法是将a的副本保存在另一个变量中,然后打印出来。

int a_copy = a;
printf("%d converted to binary: %d\n",a_copy,toBinary());

但如果函数首先不使用全局变量会更好。

int toBinary(int a)
{
    if (a == 0)
        return 0;
    else
    {
        return (a % 2 + 10 * toBinary(a / 2));
    }
}

然后你会这样做:

printf("%d converted to binary %d"\n, a, toBinary(a));

答案 1 :(得分:1)

如果在https://<yourname>.ocpu.io/a中修改了toBinary()它就是一个UB

未指定一个函数调用中的参数评估顺序。一些编译器评估它们L-> R(如GCC),其他一些编译器R-> L(如VC)。

试试这个,你就会发现它:

toDecimal()

答案 2 :(得分:0)

由于语句a的存在,函数toBinary()0的值减少到a /= 2;,并且会以递归方式执行。

因此,您的printf语句会打印0以获取a的值。

正如@Barmar建议的那样,在函数中使用局部变量而不是全局变量是一种很好的编码实践。