2010-09-07 11 views
6
int val = 5; 

printf("%d",++val++); //gives compilation error : '++' needs l-value 

int *p = &val; 
printf("%d",++*p++); //no error 

Czy ktoś mógłby wyjaśnić te 2 przypadki? Dzięki.Wyjaśnienie ++ val ++ and ++ * p ++ w C

+0

W takich przypadkach, często pomaga również dodawać komunikaty o błędach jesteś widzenia i kompilatora (wersja) masz za pomocą. – sbi

+7

Nikt nigdy nie powinien pisać takiego kodu. – duffymo

+0

Głosuj, aby zamknąć jako nie prawdziwe pytanie. Kod taki jak ten nie występuje w prawdziwym życiu. Wszystko, co jest po prostu wypadkiem składni, powinno być wskazane na często zadawane pytania, które po prostu mówią, nie bądź głupi. –

Odpowiedz

27

++val++ jest taki sam jak ++(val++). Ponieważ wynik val++ nie jest l-wartością, jest to nielegalne. I jak zauważył Stephen Canon, jeśli wynik val++ byłby lwartością, ++(val++) byłby niezdefiniowanym zachowaniem, ponieważ nie ma punktu sekwencji między s. ++.

++*p++ jest taki sam jak ++(*(p++)). Ponieważ wynik *(p++)wynosi jest równy l, jest to zgodne z prawem.

+1

Doskonała odpowiedź, choć chciałbym zauważyć, że nawet jeśli wartość "val ++" byłaby l-wartością, zachowanie nadal byłoby niezdefiniowane. '(++ val) ++' na przykład w C++ wywołałoby niezdefiniowane zachowanie. –

+0

@Stephen: Bardzo dobrze, dodam to do odpowiedzi. – sepp2k

+1

Operator po inkrementacji zawsze zwraca 'rwartość' (zarówno w języku C, jak i C++). W C++ '(++ val) ++' wywołuje niezdefiniowane zachowanie, ponieważ operator pre-increment ('++') zwraca wartość l (w C++), a wartość 'val' jest modyfikowana więcej niż jeden raz między dwoma punktami sekwencji . –

0

int j = ++val++; //gives compilation error

To dlatego nie można preinkrementuj rvalue. ++val++ jest interpretowany jako ++(val++), ponieważ operator po inkrementacji ma wyższy priorytet niż operator pre-increment. val++ zwraca operator rvalue, a operator preinrementu wymaga, aby jego operand był lvalue. :)

int k = ++*p++; //no error

++*p++ jest interpretowany jako ++(*(p++)), który jest w pełni uzasadniona.

4

Wyrażenie ++val++ jest taka sama jak (++val)++ (albo ++(val++), w każdym razie nie jest to bardzo istotne). Wynik operatora ++ nie jest zmienną, ale wartością i nie można zastosować operatora do wartości.

Wyrażenie ++*p++ jest takie samo jak ++(*(p++)). Wynik p++ jest wartością, ale wynikiem *(p++) jest lokalizacja w pamięci, do której można zastosować operator ++.

+0

'++ val ++' jest tym samym, co '++ (val ++)', który jest ** nie ** taki sam jak '(++ val) ++'. (Chociaż w C oba są syntaktycznie nieważne) –

+0

@Stephen Canon: Tak, to nie jest po prostu oczywiste, do którego ocenia. Ponieważ wyrażenie jest nieprawidłowe, nigdy nie zawracałem sobie głowy tym, który z dwóch nieważnych wariantów jest.:) – Guffa

+0

ah, ale w C++, jeden z nich jest nieprawidłowy, podczas gdy drugi jest poprawny składniowo, ale semantycznie niezdefiniowany. (C++ jest zwariowany!) –

1

również pamiętać, że jesteś zmianę adresu wskaźnika przez

int k = ++*p++; 
+0

tak, wiem to. Użyłem go dla uproszczenia. Zamiast int val, mogłem użyć int array. – understack