2017-08-28 7 views
3

私はC言語でプログラミングをしていますが、私は理解できないような問題に遭遇しました。私はprintfステートメントを2つの異なったint値の2つのマーカーで持っています。最初のintが何であっても0を出力しますが、2番目のintが正常に印刷されます。ここでは、コードです:複数の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; 
} 

問題は、最初の2つの場合にprintf文がint aの実際の値を無視するということですが、それは2つの関数の値のために正常に動作します。私は何が間違っているのか分かりません。aにはscanfという文の前に値が与えられており、テキストに適切なマーカーを使用しています。

+0

最初の 'scanf()'の戻り値をチェックすることはないので、おそらく失敗し、 'a'は値が割り当てられていません。それは危険です。 – unwind

+1

@unwind関数でintの値を使用していますが、正しく動作します。そうしないと、2番目の出力が間違っていました。 –

+2

@Comrade_Comski IMOスニペットがうまく見えます。だから、それはあなたがOKと思う詳細です。誰もが問題を再現できるように、コードを完成させてください。 –

答えて

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

aた場合は、それがUBだtoBinary()またはtoDecimal()のいずれかに変更されます。

1つの関数呼び出しでの引数評価の順序は不定です。いくつかのコンパイラは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

の機能toBinary()aの値が原因の文a /= 2;の存在に0に減少しますし、それが再帰的に実行きています。

したがって、printfステートメントは、aの値に0を出力します。

@Barmarは、関数内でグローバル変数ではなくローカル変数を使用することをお勧めします。

関連する問題