2017-08-28 3 views
3

Ich übe Programmierung in c, aber ich bin auf ein Problem gestoßen, das ich nicht scheinen kann, herauszufinden. Ich habe eine printf Anweisung mit zwei Markern für zwei verschiedene int Werte. Egal was die erste int ist, es druckt 0, aber die zweite int druckt normal. Hier ist der Code:Mehrere Eingänge drucken 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; 
} 

Das Problem ist, dass die printf Aussagen in den ersten beiden Fällen den tatsächlichen Wert von int a ignorieren, aber es funktioniert in der Regel für den Wert der beiden Funktionen. Ich bin mir nicht sicher, was falsch ist, wie a einen Wert vor, in der scanf Anweisung gegeben wird, und ich verwende die richtige Markierung im Text.

+0

Sie überprüfen nie den Rückgabewert der ersten 'scanf()', also vielleicht ist es fehlgeschlagen und 'a' hat keinen Wert zugewiesen bekommen. Das ist gefährlich. – unwind

+1

@unwind Ich benutze den int-Wert in den Funktionen und sie funktionieren zwar richtig, sonst wäre die zweite Ausgabe falsch. –

+2

@Comrade_Comski IMO das Snippet sieht gut aus, also sind es eher die Details, von denen man annimmt, dass sie funktionieren, OK. Bitte machen Sie Ihren Code vollständig, damit jeder das Problem reproduzieren kann. –

Antwort

5

Da die Reihenfolge der Argumentation Auswertung nicht spezifiziert ist, diese nicht definiertes Verhalten ist.

Die einfachste Lösung wäre, eine Kopie von a in einer anderen Variablen zu speichern und diese zu drucken.

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

Aber es wäre besser, wenn die Funktion in erster Linie keine globale Variable verwendet.

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

Dann würden Sie tun:

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

Wenn a modifiziert entweder in toBinary() oder toDecimal(), es ist ein UB.

Die Reihenfolge der Argumentauswertung in einem Funktionsaufruf ist nicht spezifiziert. Einige Compiler bewerten sie L-> R (wie GCC), einige andere tun es R-> L (wie VC).

die Sie interessieren, und Sie werden es herausfinden:

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

Ich benutze GCC auf Linux, aber ich werde vorsichtig sein, nicht vage bei der Handhabung von Argumenten. –

0

Der Wert a in der Funktion toBinary() aufgrund des Vorhandenseins der Aussage zu 0 reduziert wird a /= 2; und es rekursiv ausgeführt zu werden.

Daher druckt Ihre printf-Anweisung 0 für den Wert a.

Wie @Barmar vorgeschlagen hat, ist es eine gute Vorgehensweise, lokale Variablen anstelle von globalen Variablen innerhalb einer Funktion zu verwenden.