Po przeczytaniu ukrytych funkcji i zakamarkach C ++ / STL na comp.lang.c++.moderated
, byłem całkowicie zaskoczony, że następujący fragment skompilowany i pracował zarówno w Visual Studio 2008 i G ++ 4.4.
Oto kod:
#include <stdio.h>
int main()
{
int x = 10;
while (x --> 0) // x goes to 0
{
printf("%d ", x);
}
}
Wynik:
9 8 7 6 5 4 3 2 1 0
Zakładam, że to C, ponieważ działa również w GCC. Gdzie jest to zdefiniowane w standardzie i skąd ono pochodzi?
c++
c
operators
code-formatting
standards-compliance
GManNickG
źródło
źródło
++
albo--
wcześniej ...#define upto ++<
,#define downto -->
. Jeśli czujesz się źle, możesz zrobić#define for while(
i#define do ) {
(i#define done ;}
) napisaćfor x downto 0 do printf("%d\n", x) done
Och, ludzkość ...Odpowiedzi:
-->
nie jest operatorem. W rzeczywistości są to dwa oddzielne operatory--
i>
.Kod warunku zmniejsza się
x
, zwracającx
oryginalną (nie zmniejszoną) wartość, a następnie porównuje oryginalną wartość za0
pomocą>
operatora.Aby lepiej zrozumieć, oświadczenie można napisać w następujący sposób:
źródło
while (x-- > 0)
byłoby bardziej trafne. Sprawia również, że bardziej oczywiste jest to, co się dzieje (przynajmniej w edytorze czcionek o stałej czcionce), co oznacza, że nawiasy w tej odpowiedzi nie byłyby konieczne.Lub coś zupełnie innego ...
x
slajdy do0
.Nie tak matematyczne, ale ... każdy obraz maluje tysiąc słów ...
źródło
why waste words when a picture does a better job
, używane w tym kontekście jako żart. (w rzeczywistości są 2 słowa kluczowewhile
iprintf
)To bardzo skomplikowany operator, więc nawet ISO / IEC JTC1 (Wspólny Komitet Techniczny 1) umieścił swój opis w dwóch różnych częściach standardu C ++.
Żartuje bok, są to dwie różne operacji:
--
a>
opisane odpowiednio w §5.2.6 / 2 i §5.9 z C ++ 03 standardu.źródło
Jest to równoważne z
x--
(po zmniejszeniu) jest równoważne,x = x-1
więc kod przekształca się w:źródło
0 >-- x
W tym przypadkux
jest zmniejszany przed logiką. W postfiksie logika jest wykonywana przed zmniejszeniem, a zatem obie próbki są równoważne. Możesz je napisaćConsole
i przetestować.while(x=x-1,x+1 > 0)
jest równoważne.x
może zerować nawet szybciej w przeciwnym kierunku:8 6 4 2
Możesz kontrolować prędkość za pomocą strzałki!
90 80 70 60 50 40 30 20 10
;)
źródło
Jego
Tylko przestrzeń sprawia, że rzeczy wyglądają zabawnie,
--
dekrety i>
porównania.źródło
Zastosowanie
-->
ma znaczenie historyczne. Zmniejszanie było (i nadal jest w niektórych przypadkach) szybsze niż zwiększanie w architekturze x86. Korzystanie-->
sugeruje, żex
tak będzie0
, i przemawia do osób z wykształceniem matematycznym.źródło
to jest tak parsowane.
źródło
Zupełnie maniakiem, ale użyję tego:
źródło
do ... while
to lista instrukcji. W C jest to blok, więc musi byćdo { ... } while
.do statement while ( expression ) ;
. Powiedziawszy to, mam nadzieję, że zrozumiałem, że miałem na myśli ten przykład jako żart.W jednej książce, którą przeczytałem (nie pamiętam poprawnie, którą książkę) napisałem: Kompilatory próbują parsować wyrażenia do największego tokena przy użyciu reguły lewej i prawej.
W takim przypadku wyrażenie:
Analizuje największe tokeny:
Ta sama reguła dotyczy tego wyrażenia:
Po analizie:
Mam nadzieję, że to pomoże zrozumieć skomplikowane wyrażenie ^^
źródło
a-----b
i pomyśli(a--)-- - b
, co nie kompiluje, ponieważa--
nie zwraca wartości.x
a--
dwa oddzielne żetony.-->
jest operatorem (co sugeruje pytanie, które zostało zadane), odpowiedź ta w ogóle nie jest pomocna - pomyślisz, że token 2 jest-->
nie tylko--
. Jeśli wiesz, że-->
to nie jest operator, prawdopodobnie nie masz problemu ze zrozumieniem kodu w pytaniu, więc jeśli nie masz zupełnie innego pytania, nie jestem pewien, jak to może być przydatne.a
przeciążono operatora po dekrementacji, który zwraca wartość. coliru.stacked-crooked.com/a/e1effc351ae79e9fTo jest dokładnie to samo co
dla liczb nieujemnych
źródło
for(--x++;--x;++x--)
?unsigned
jest--x++
ma niezdefiniowane zachowanie zgodnie z §1.9.15unsigned
, użyłby%u
W każdym razie mamy teraz operatora „idzie do”.
"-->"
łatwo jest zapamiętać go jako kierunek, a „gdy x idzie do zera” jest proste w znaczeniu.Ponadto jest nieco bardziej wydajny niż
"for (x = 10; x > 0; x --)"
na niektórych platformach.źródło
for (size_t x=10; x-->0; )
treścią pętli jest wykonywana za pomocą 9,8, .., 0, podczas gdy druga wersja ma 10,9, .., 1. W przeciwnym razie wyjście z pętli do zera przy użyciu zmiennej bez znaku jest dość trudne.++>
aby wykonać pracę przyrostową.int
, więc może równie dobrze zjadać twojego psa, jak zerować,x
jeśli zaczyna się negatywnie.0
. (Dla porównania, idiom pomijania testów zerowych, takich jak pisaniewhile (n--)
zamiast dla niepodpisanychn
, nic ci nie kupuje, a dla mnie znacznie utrudnia czytelność.) Ma również przyjemną właściwość, że podajesz jeden więcej niż indeks początkowy, który zwykle jest tym, co chcesz (np. dla pętli nad tablicą określasz jej rozmiar). Lubię też-->
bez miejsca, ponieważ ułatwia to rozpoznanie tego idiomu.Ten kod najpierw porównuje x i 0, a następnie zmniejsza x. (Powiedział również w pierwszej odpowiedzi: dekrementujesz x, a następnie porównujesz x i 0 z
>
operatorem). Zobacz wynik tego kodu:Teraz najpierw porównujemy, a następnie zmniejszamy, widząc 0 w danych wyjściowych.
Jeśli chcemy najpierw zmniejszyć, a następnie porównać, użyj tego kodu:
Ten wynik to:
źródło
Mój kompilator wydrukuje 9876543210 po uruchomieniu tego kodu.
Zgodnie z oczekiwaniami. W
while( x-- > 0 )
rzeczywistości oznaczawhile( x > 0)
.x--
Postu zmniejszax
.to inny sposób pisania tego samego.
Fajnie, że oryginał wygląda jak „podczas gdy x idzie do 0”.
źródło
while( x-- > 0 ) actually means while( x > 0)
- Nie jestem pewien, co tam próbowałeś powiedzieć, ale sposób, w jaki to powiedziałeś, oznacza, że--
nie ma żadnego znaczenia, co oczywiście jest bardzo błędne.x
będzie-1
po opuszczeniu pętli, podczas gdy w tej odpowiedzix
będzie0
.Brakuje miejsca między
--
i>
.x
jest po zmniejszeniu, to znaczy zmniejszeniu po sprawdzeniu warunkux>0 ?
.źródło
#define foo()
porównaniu#define foo ()
.--
jest operatorem dekrementacji i>
jest operatorem większym niż .Oba operatory są stosowane jako jeden podobny
-->
.źródło
To połączenie dwóch operatorów. Pierwszy
--
służy do zmniejszania wartości i>
do sprawdzania, czy wartość jest większa niż operand po prawej stronie.Dane wyjściowe będą:
źródło
W rzeczywistości
x
jest po dekrementacji iz tym warunkiem jest sprawdzany. Nie-->
jest(x--) > 0
Uwaga: wartość parametru
x
zmienia się po sprawdzeniu warunku, ponieważ zmniejsza się on po dekrementacji. Mogą wystąpić również podobne przypadki, na przykład:źródło
x
zaczął się od 1, alewhile ( (x--) > 0 )
by to zrobił. {edit} Eric Lippert opisałC i C ++ przestrzegają zasady „maksymalnego chrupania”. Taki sam sposób, w jaki a --- b jest tłumaczony
(a--) - b
, w twoim przypadkux-->0
oznacza(x--)>0
.Zasada mówi w zasadzie, że od lewej do prawej, wyrażenia są tworzone przez wzięcie maksymalnej liczby znaków, które utworzą prawidłowe wyrażenie.
źródło
Skąd ta komplikacja?
Prosta odpowiedź na pierwotne pytanie brzmi:
Robi to samo. Nie mówię, że powinieneś to zrobić w ten sposób, ale robi to samo i odpowiedziałby na pytanie w jednym poście.
Jest
x--
to po prostu skrót od powyższego, i>
jest po prostu normą większą niżoperator
. Bez wielkiej tajemnicy!Zbyt wielu ludzi komplikuje proste rzeczy;)
źródło
The OP's way: 9 8 7 6 5 4 3 2 1 0
orazThe Garry_G way: 10 9 8 7 6 5 4 3 2 1
x=x-1
wcześniej,printf
wtedy możesz powiedzieć „robi to samo”.W konwencjonalny sposób zdefiniowalibyśmy warunek w
while
nawiasie pętli()
i warunek kończący w nawiasach{}
, ale-->
definiujemy oba jednocześnie.Na przykład:
To zmniejsza
a
i uruchamia pętlę, gdya
jest większa niż0
.Konwencjonalnie wyglądałoby to tak:
Oba sposoby robimy to samo i osiągamy te same cele.
źródło
test-write-execute
jak w pytaniu, dziękuję za zwrócenie uwagi!(x --> 0)
znaczy(x-- > 0)
(x -->)
output -: 9 8 7 6 5 4 3 2 1 0
(-- x > 0)
To znaczy(--x > 0)
output -: 9 8 7 6 5 4 3 2 1
output -: 9 8 7 6 5 4 3 2 1
output -: 9 8 7 6 5 4 3 2 1 0
output -: 9 8 7 6 5 4 3 2 1 0
output -: 9 8 7 6 5 4 3 2 1 0
podobnie możesz wypróbować wiele metod, aby pomyślnie wykonać to polecenie
źródło