2014-07-23 18 views
27

Podczas zabawy z operatorem ++, starałem się napisać następujące:Co zwraca operator ++ (lub -)?

++i++; 

Spodziewałem to skompilować na początku, ale mam błąd kompilatora:

The operand of an increment or decrement operator must be a variable, property or indexer.

Następnie próbowałem pisać ++(i++), aby pomóc kompilatorowi zrozumieć, co miałem na myśli, ale także (co nie powinno dziwić) nie zadziałało.

Więc zastanawiam się, co zwróci operator ++? Z błędem kompilatora jestem coraz Spodziewałem ++i aby nie zwracać int reprezentujący wartość i zwiększany, ale to też nie jest przypadek, ponieważ mogę zrobić i = (++i) + 1 z powodzeniem ...

Ktoś ma jakiś pomysł, dlaczego ++ Operator nie może być powiązany?

Również, (++i).GetType() zwraca System.Int32.

+0

Należy spojrzeć na C++ Operator przeciążenie może będzie to wyczyścić rzeczy http://stackoverflow.com/questions/4421706/operator-overloading –

+0

prostu ciekawi, czy (++ i) ++ kompilować? Nie mam przed sobą VS, więc nie mogę tego sprawdzić. – RLH

+0

Nie, nie ma. Ponieważ '++ i' zwraca wartość' i' inkrementowaną, a nie samą zmienną. (Z tego co właśnie się nauczyłem: P) – Bun

Odpowiedz

45

C# ++ operator zwraca wartośćwcześniej (na i++) lub po (na ++i) zwiększany.

Błąd, który widzisz, ponieważ ten operator może być używany TYLKO na zmiennej, właściwości lub indeksie . Argument powód jest ponieważ intencją operatora jest zwiększenie zmiennej, która jest przywoływana. Nie można go używać w wyrażeniu lub innym typie. Co zrobi (9++)?

Oczekujesz, że (i++)++ będzie odpowiednikiem i++; i++. Ale i++ zwraca wartość o wartości i wewnętrznie wzrasta o i. Ponieważ nie można zastosować operatora ++ do wartości , łańcuchowanie nie jest możliwe.

Różnica w C++ jest to, że ++ prefiks operator bierze odniesienie jako wejście i zwraca odniesienie do pierwotnej wartości, dzięki czemu można łańcuch operator, ponieważ jest to tylko przy użyciu wskaźnika zamiast wartości. Operator postfix zwraca wartość, a zatem nie może być powiązany.

+0

Ta część dotycząca porównania C#/C++ jest bardzo interesująca (nie, że reszta odpowiedzi nie jest), i prawdopodobnie źródłem mojego nieporozumienia. Dziękuję bardzo. – Bun

+0

@Bun Cieszę się, że pomogło. –

+3

Obejmuje również [o wiele obszerniejszą odpowiedź Eric Lipperta] (http://stackoverflow.com/a/3346729/60761) –

17

Wynik operatora ++ lub -- jest wartość zmiennego, własności lub indeksującego i nie zmienna, własności lub sam podziałowe.

Nie można podwójnie zwiększyć zmiennej, takiej jak (i++)++, z tego samego powodu, dla którego nie można samodzielnie zwiększyć wartości, np. 100++.

+0

Wow, nie mogę uwierzyć, że o tym nie myślałem. Dziękuję bardzo za jasne wyjaśnienie. – Bun

4

Jeśli mogę pożyczyć terminologię z C lub C++, operator ++ tutaj zwraca "wartość r". Wartość r nie jest mapowana na typ języka, jest syntaktyczną sztuczką pozwalającą odróżnić to, co można przypisać (modyfikowalne), a co nie.

Coś, co można znaleźć po lewej stronie operacji przypisania, nazywa się l-value (lewa wartość), a rzeczy, które można znaleźć po prawej stronie przypisania to "r-wartości" (prawidłowe wartości). Operator ++ musi działać na wartości l, ponieważ musi ją przypisać. Jednak zwracane wyrażenie musi być wartością r, ponieważ nie ma sensu robić i++ = 4 w języku C#, tak jak nie ma sensu robić foo.Bar() = 4 lub 1 = 5.

C# nie ma wartości bezwzględnych ani r-wartości jako takich, ale ogranicza to, co można znaleźć po lewej stronie przypisania do zmiennych, właściwości i operacji indeksujących. Jest to, nie przypadkowo, także to, co możesz użyć operatora ++.

+1

Dobra odpowiedź. Zauważam, że masz rację twierdząc, że C# nie używa nieco mylącej terminologii "rvalue"/"lvalue". Zamiast tego C# klasyfikuje wszystkie wyrażenia w jedną z następujących: * wartość, zmienna, przestrzeń nazw, typ, grupa metod, zero literalne, funkcja anonimowa, właściwość, indeksator, zdarzenie i wywołanie metody zwracającej puste miejsce *. (Inicjatory tablicowe, chociaż wyglądają jak wyrażenia, nie są technicznie wyrażeniami). –

1

Zdałem sobie sprawę, że nie można użyć ++ przed lub po wyrażeniu.

Podczas korzystania:

++(i++); 

robisz coś takiego:

++(<expression>) 

kompilator rozwiązać ekspresji, a potem będzie podwyższyć wynik ekspresji i brzmi szalony. Operan ++ działa poprzez inkrementowanie bezpośredniej zmiennej bez wyniku wyrażenia.

W jaki sposób ocenia się wyrażenia programistyczne? Gramatyka języka (BNF) http://people.cis.ksu.edu/~schmidt/301s11/Lectures/bnfT.html

Oto kolejny przykład prawidłowego użytkowania tego argumentu ++

int i = 0, j = 0; 
int sum = i++ + j++; 
//result sum = 0, i = 1, j = 1 

Ten operand ++ jest brudny, ponieważ zrobić 3 rzeczy naraz (czytaj, przyrost, cesja). Osobiście nie używam dużych wyrażeń, takich jak powyższy przykład: i++ + j++. Ale nadal używam go w pętli for lub pętli while.

Nawet krótkie wyrażenie, takie jak i = j++;, jest bałaganem. Zachowaj swój kod prosty i łatwy do zrozumienia. To samo wyrażenie można napisać tak:

i = j; 
j++; //or j+=1;