2017-08-28 94 views
3

我正在用c编程,但遇到了一个我似乎无法解决的问题。我有一个printf声明与两个标记为两个不同的int值。不管第一个int是什么,它都会打印0,但第二个打印通常是int。下面的代码:打印多个输入输出0

#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的实际价值,但它通常适用于两个函数的值。我不确定有什么不对,因为ascanf声明之前给出了一个值,并且我在文本中使用了正确的标记。

+0

你从不检查第一个'scanf()'的返回值,所以它可能失败并且'a'没有得到赋值。这很危险。 – unwind

+1

@unwind我在函数中使用了int的值,它们可以正常工作,否则第二个输出就会出错。 –

+2

@Comrade_Comski IMO的片段看起来不错,所以它是相当你承担工作的细节确定。请使您的代码完整,以便每个人都可以重现此问题。 –

回答

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

如果atoBinary()toDecimal(),中被修改,则它是UB

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

试试这个,你会发现它:

printf("%d %d %d\n", a, toBinary(), a); 
printf("%d %d %d\n", a, toDecimal(), a); 
+0

我在linux上使用GCC,但在处理参数时我会小心谨慎,不要模糊。 –

0

a在功能toBinary()值被降低到0由于声明a /= 2;的存在,它是越来越递归执行。

因此,您的printf语句打印0的值为a

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