2015-02-09 33 views
5

Przez jakiś czas używałem SO jako punktu odniesienia, ale nigdy wcześniej nie zadawałem pytania. Jestem obecnie w college'u w klasie C++ i czytam także Bjarne Stroutstrup dla Bjarne Stroutstrup tylko dla mojej własnej korzyści, gdy zobaczyłem odpowiedź na pytanie, które naprawdę ją poleciło.Jakieś pomieszanie z działaniem przecinków w C/C++

W tej chwili obejmujemy operatorów w mojej klasie i po prostu nie mogę się zorientować, jak działa operator przecinków w oświadczeniu. Jednym z przykładów jest przykładowe pytanie dotyczące części online tej klasy, która ciągle się mylę, nawet jeśli piszę program C i używam GDB, aby uzyskać wynik. Pytanie brzmi:

Przyjmując x == 16 przed następującym wyrażeniem, jaka jest wartość następującego wyrażenia (niekoniecznie wartość x)?

x ++, ++ x, x = x +

Nie jestem zainteresowany w prawidłowej odpowiedzi tyle, jak uzyskać prawidłową odpowiedź. Przeczytałem kilka odpowiedzi na podobne pytania, takie jak ta here, ale wydaje mi się, że brakuje mi tego, jak to ma zastosowanie, gdy w rzeczywistości nie ma operatora przypisania. Jest to tak samo jak powiedzenie

int y = (x++, ++x, x+=x); 

lub

int y = x++, ++x, x+=x; 

czy nie? Czy ktoś mógłby wyjaśnić, w jaki sposób działa operator przecinka, w szczególności w odniesieniu do oświadczenia bez zlecenia?

+4

@SouravGhosh Nie, operator przecinka wprowadza punkt sekwencji między operandami. Wyrażenia są sekwencjonowane od lewej do prawej. – juanchopanza

+0

@KeithThompson Dziękuję panu za poprawienie mnie. –

+0

@juanchopanza Panie, jakoś przeoczyłem rozdział 6.5.17. Przepraszam za to. Poprawiono mnie. –

Odpowiedz

8

Operator przecinka jest łatwy - tak łatwo jest trudny. Ma najniższy priorytet wszystkich operatorów; jego priorytet jest nawet niższy niż operatorów przydziału. Zauważ, że argumenty funkcji nie są oddzielone przez operatora przecinka.

Operator przecinka ocenia lewy operand, generuje punkt sekwencji i odrzuca wynik, a następnie analizuje prawy operand.

W kontekście:

x++, ++x, x += x; 

odpowiada:

x++; 
++x; 
x += x; 

wyjątkiem, że całkowita wartość jest wynikiem x += x;.

Biorąc pod uwagę, że x zaczyna się od 16 lat, to jest zwiększana do 17, potem 18, potem dwukrotnie do 36. Całkowita wartość wynosi zatem 36.

Należy pamiętać, że ze względu na punkty sekwencji, to nie działa wolny od zasady dotyczące niepodawania tej samej zmiennej więcej niż jeden raz między punktami sekwencji.

Jedynym powodem używania operatora przecinka jest to, że istnieją konteksty, w których nie można używać oddzielnych instrukcji, ale można korzystać z operatorów przecinków. Na przykład:

for (i = 0, j = n; i < j; ++i, --j) 

Zamiast przecinków nie można używać średników.


w pytaniu, są dwie próbki:

int y = (x++, ++x, x+=x); 

int y = x++, ++x, x+=x; 

Pierwszym jest uzasadnione (chociaż niepotrzebnie skręcone) i inicjuje y do 36 (i ustawia x do 36).

Drugi nie jest zgodny z prawem i nie będzie się kompilować; przecinki nie są operatorami przecinkowymi i powinny oddzielać odrębnych deklaratorów, ale ++x i x += x nie są deklaratorami. Jeśli jednak został zmieniony na:

y = x++, ++x, x+=x; 

to byłoby uzasadnione. Pierwszy termin oznacza:

y = x++ 

przyporządkowujący 16 do y i zwiększa x do 17 przyrostów drugi człon x do 18; trzeci człon zmiany x do 36.

+1

[Klas Lindbäck] (http://stackoverflow.com/users/646887/klas-lindb% c3% a4ck) - dziękuję za edycję; Byłem w trakcie dodawania materiału po regule, kiedy dokonałeś zmiany. Mam nadzieję, że moje wyjaśnienie jest co najmniej równie dobre jak twoje. Już na samym początku odpowiedzi zauważyłem, że operator przecinka ma nawet niższy priorytet niż przypisanie. –

4

Operator przecinek ocenia pierwszy argument operacji, usuwa się, po czym ocenia do drugiej, z punktu sekwencji między oceny.

W twoim przypadku to oznacza, że ​​masz tę sekwencję wyrażeń oceniana

x++ // evaluates to 16, increments x to 17 
++x // increments x to 18, evaluates to 18 
x+=x // increments x by x, i.e. by 18, evaluates to 36. 

oraz pełne wyrażenie do trzeciego sub-wypowiedzi. Pierwsze wyrażenie zwraca wartość 16, ale zwiększa liczbę x do 17. Drugi zwiększa liczbę x do 18 i ocenia tę liczbę. Trzeci zwiększa x o jego wartość 18 i ocenia na x, czyli oceniając na 36.