i'v następnym kod:jest Pierwszeństwo operatora ignorowane 'czy' warunki
void main()
{
int k, x, y, z;
printf("\nExperiment 1:");
x = 0, y = 0, z = 0;
k = x++ || y++ && z++;
printf("\nx = %d, y = %d, z = %d and k = %d\n", x, y, z, k);
printf("\nExperiment 2:");
x = 1, y = 0, z = 0;
k = x++ || y++ && z++;
printf("\nx = %d, y = %d, z = %d and k = %d\n", x, y, z, k);
}
Wydajność:
Eksperyment 1: x = 1, y = 1, Z = 0 i k = 0
Eksperyment 2: x = 2, y = 0, z = 0 i k = 1
Co mam rozumieć to: dla ekspresji aby mogło być prawdziwe, albo lewa lub prawa strona "||" musi być niezerowe. Zaczyna się od lewej. Jeśli pozostanie niezerowe, nie ocenia dalej. Jeśli jest zero, zaczyna się po prawej stronie. Po prawej mamy "& &". Tak więc, ponownie zaczynamy od lewej strony & &, a jeśli jest zero, wyrażenie nie może być prawdziwe i nie jest kontynuowane. Inaczej ocenia prawą stronę „& &”
Moim założeniem było operator & & ma wyższy priorytet. Tak więc oba argumenty należało ocenić, a następnie zastosować do niego & &, a następnie ocenić oba argumenty ||.
Czy optymalizuje się sam kompilator? Użyłem funkcji Visual Studio TC compilar z wyłączoną Optymalizacją.
Nie są to "jeśli warunki", przy okazji. Są po prostu wyrażeń, używając operatorów boolowskich i operatorów po inkrementacji. – unwind
Tylko dlatego, że && ma zaostrzone pierwszeństwo, nie oznacza 'k = x ++ || (y ++ && z ++) 'wykona polecenie && przed ||. Nazywa się to zwarciem i jest bardzo dobrze znane. Wspomniałeś o tym nawet sam. Wyobraź sobie: 'k = x ++ || f (& y, & z) 'gdzie f() zwraca' (* y) ++ && (* z) ++ '. Jest to funkcjonalnie równoważne z twoim kodem. – Matthias
@Matthias: rzeczywiście; '++' ma jeszcze wyższy priorytet niż '&&'; nie oczekujemy, że post-inkrementacja stanie się przed wszystkim innym tylko ze względu na pierwszeństwo ... – geoffspear