5

Jak wytłumaczyć wyjście poniższym kodzie:C - Objaśnienie wyników printf ("% d% d n", k = 1, k = 3);

include <stdio.h> 

int main(void) { 
    int k; 
    printf("%d %d\n",k=1,k=3); 
    return 0; 
} 

Ideone Link

Moje myślenie było to, że 1 zostanie przypisana do zmiennej, a następnie k1 zostanie wydrukowany. Podobnie 3 zostanie przypisany do k, a wyjście będzie 3.

oczekiwany wynik

1 3 

Rzeczywista wyjściowa

1 1 

ja ekstrapolację z

int a; 
if (a = 3) { 
    ... 
} 

jest równa

if (3) { 
    ... 
} 

Proszę dać mi znać, gdzie się mylę?

+0

@CinCout Niestety, zauważyłem ją później. –

Odpowiedz

7

Problem polega na tym, że kolejność oceny argumentów funkcji nie jest zdefiniowana i nie ma żadnego punktu sekwencji między wartościowaniem lub argumentami. Tak, to stwierdzenie

printf("%d %d\n",k=1,k=3) 

wywołuje undefined behavior, jak starasz się zmodyfikować tej samej zmiennej więcej niż raz bez punktu sekwencji pomiędzy.

Po uruchomieniu programu wywołującego UB i (jeśli) istnieje wyjście, tak i tak nie można go uzasadnić, wyjście może być dowolne.

+1

To jest w porządku, jedno zadanie, wydrukuje wartość 'k', tj., 3. –

+0

Myślę, że ta odpowiedź jest błędna http://stackoverflow.com/a/9514591/5473170. Możesz to sprawdzić. –

+0

@SurajJain Nie jest najlepszy, ale ogólnie wygląda dobrze. Dlaczego uważasz, że jest niepoprawny? –

-4

Spodziewam się, że powodem, dla którego widzisz 1 1 jest to, że dwie instrukcje przypisania mają miejsce, kontrola jest przekazywana do printf.

printf("%d %d\n",k=1,k=3); 

Więc w odpowiedzi na dół głosów, tak, to jest to niezdefiniowane zachowanie, a więc nie należy liczyć na to zachowanie ustawicznego. Jednakże, jeśli chodzi o określenie, dlaczego dane wyjściowe wyniosły 1 1, a nie 1 3, moglibyśmy wywnioskować, że przypisanie 3 mogło zostać zdeptane przez kolejne przypisanie 1.

Po wywołaniu polecenia printf stos wywołań zawiera dwa wpisy z ostateczną wartością k, która jest 1.

Możesz to przetestować, zastępując je funkcją, która drukuje coś po uruchomieniu.

Przykładowy kod:

#include <stdio.h> 

int test(int n) { 
    printf("Test(%d)\n", n); 
    return n; 
} 

int main(void) { 
    int k; 
    printf("%d %d\n",k=test(1), k=test(3)); 
    return 0; 
} 

wyjściowa:

Test(3) 
Test(1) 
1 1 
+0

To jest kiepskie wytłumaczenie z prawdopodobnie dużo bardziej wymyślnego powodu. –

+1

@ q. Potem Słaba jest łagodnym słowem, to jest złe. –

+0

Jestem naprawdę ciekawa, jak moje wyjaśnienie jest błędne. Czy argument jest taki, że wielokrotnym przydziałem jest UB? – Scovetta