Mam pytanie, w jaki sposób kompilator działa na następującym kodzie:
#include<stdio.h>
int main(void)
{
int b=12, c=11;
int d = (b == c++) ? (c+1) : (c-1);
printf("d = %i\n", d);
}
Nie jestem pewien, dlaczego wynik jest d = 11.
Mam pytanie, w jaki sposób kompilator działa na następującym kodzie:
#include<stdio.h>
int main(void)
{
int b=12, c=11;
int d = (b == c++) ? (c+1) : (c-1);
printf("d = %i\n", d);
}
Nie jestem pewien, dlaczego wynik jest d = 11.
Odpowiedzi:
W int d = (b == c++) ? (c+1) : (c-1);:
c++jest bieżąca wartość c11. Oddzielnie czwiększa się do 12.b == 11jest fałszywe, ponieważ bma 12 lat.(b == c++)jest fałszywe, (c-1)jest używane. Do ctego punktu należy również wykonać przyrost o 12.cma 12 lat, c-1ma 11 lat.d jest inicjowany do tej wartości, 11.Zgodnie ze standardem C (operator warunkowy 6.5.15)
4 Pierwszy argument jest oceniany; między oceną a oceną drugiego lub trzeciego operandu występuje punkt sekwencyjny (w zależności od tego, który jest oceniany). Drugi operand jest oceniany tylko wtedy, gdy pierwszy porównuje nierówny z 0; trzeci argument jest oceniany tylko wtedy, gdy pierwszy porównuje równy 0; wynikiem jest wartość drugiego lub trzeciego operandu (zależnie od tego, który jest oceniany), przekonwertowany na typ opisany poniżej. 110)
Tak więc w inicjującym wyrażeniu tej deklaracji
int d = (b == c++) ? (c+1) : (c-1);
zmienna bjest porównywana z wartością zmiennej, cponieważ operator po inkrementacji zwraca wartość swojego argumentu przed jego inkrementacją.
Ponieważ wartości nie są sobie równe ( bjest ustawione na 12, podczas gdy cjest ustawione na 11), wówczas podwyrażenie (c-1)jest oceniane.
Zgodnie z cytatem istnieje punkt sekwencyjny po ocenie stanu operatora. Oznacza to, że po ocenie warunku cma wartość 12po zastosowaniu operatora po-przyrostowego do zmiennej c. W rezultacie zmienna d jest inicjalizowana przez wartość 1( 12 - 1).
?:. Ponieważ zwykle w C łączenie ++z innymi operacjami na tym samym operandzie jest niezdefiniowanym zachowaniem. Ten kod działa tylko przewidywalnie, ponieważ ?:ma różne specjalne reguły dotyczące płatków śniegu.
Ponieważ warunek jest fałszywy, dlatego falsetak się stanie :, c-1ale ponieważ zwiększyłeś cwarunek o c++, dlatego cjest teraz 12. Wynik zatem 12 - 1, który wynosi 11.
EDYCJA: To, co OP źle zrozumiał, to przyrost postu.
Tak więc to, co się naprawdę wydarzyło, wygląda następująco:
#include<stdio.h>
int main(void)
{
int b=12, c=11;
int d;
if (b == c) { // 12 == 11 ? -> false
c = c + 1;
d = c + 1;
} else { // this executes since condition is false
c = c + 1; // post increment -> c++ -> c = 12 now
d = c - 1; // 12 - 1 = 11 -> d = 11
}
printf("d = %i\n", d);
}
c++pod uwagę warunek. Warunek jest fałszywy, ale do obliczenia używana jest wartość oryginalna parametru , a nie wersja przyrostowa. cc - 1
c++i++c
c++jest operatorem post- increment. Wartość c++wynosi 11, z efektem ubocznym tworzenia c == 12. ++cmiałby wartość 12.
Patrz operator trójskładnikowy.
Składnia
stan: schorzenie ? wartość_jeśli_prawda: wartość_jeśli_fałsz
Więc napisałeś
int d = (b == c++) ? (c+1) : (c-1);
W tej sytuacji wynikiem będzie 11, ponieważ po sprawdzeniu wartość „c” wzrasta (c + 1 = 12), a dopiero potem ustawia wartość „d” na c (12) -1, która wynosi 11.
Jeśli używałeś na przykład:
int d = (b == ++c) ? (c+1) : (c-1);
Wartość „c” byłaby zwiększona przed sprawdzeniem instrukcji, więc byłaby to prawda, a wartość „d” wynosiłaby c (12) +1, czyli 13.