2013-06-10 17 views
5
int c = someIntegerValue; 

// Some code... 

int i; 
for (i = 0; i < 5, i < c; i++) { 
... 
} 

Mój kompilator mówi error: expression has no effect, który brzmi poprawnie. Które z tych 2 porównań będzie tutaj użyte? Domyślam się, że i < c jest ignorowany, ale chciałem trochę potwierdzenie od innych, jak nie jestem w stanie uruchomić jeszcze ten kod ...Co robi ten przecinek w części * test * pętli for?

+0

Nie ekspertem C, ale wydaje się, że stara się zrobić równowartość 'I <5 && i

+0

Kompilator ma rację. "i <5" jest tutaj oceniane, ale wartość jest wyrzucana bez użycia i nie ma żadnych skutków ubocznych, więc programista wyraźnie coś źle zrozumiał. –

+0

Dlaczego głosowanie w dół i głosy zamykają się? Operator przecinka nie jest najbardziej intuicyjną rzeczą na świecie. To mnie potknęło i koduję C przez prawie 2 dekady. –

Odpowiedz

14

Oświadczenie

i < 5, i < c 

Używa comma operator, który ocenia wszystkie wyrażenia od lewej do prawej, ale tylko daje wartość na prawo. Oznacza to, że wyrażenie i < 5 jest oceniane i odrzucane, podczas gdy wyrażenie i < c jest oceniane i faktycznie wykorzystywane przez pętlę.

Zakładam, że autor oznaczało napisać coś takiego:

i < 5 && i < c 

które faktycznie uznaje oba wyrażenia.

To powiedziawszy, nie jestem pewien, dlaczego jest to kompilator błąd a nie kompilator ostrzeżenie. To jest legalny kod, choć prawie na pewno jest to błąd. Być może ustawiłeś kompilator do zgłaszania błędów ostrzeżeń?

Mam nadzieję, że to pomoże!

+4

Nie nazwałbym tego "o wiele lepszym sposobem na zrobienie tego". Wersja z '&&' jest semantycznie różna od wersji z operatorem przecinka. Jest bardzo prawdopodobne, że wersja '&&' jest tym, co autor * miał na myśli *, ale nie można być pewnym. –

+2

'i <5 && i

+0

@ KeithThompson - Tak, masz rację. Naprawiony! – templatetypedef

3

Jest i < 5 że jest ignorowany.

Kompletny wyrażenie jest:

i < 5, i < c

czyli dwa oddzielne wyrażenia połączone przez comma-operator.

Przecinarka działa, oceniając pierwsze wyrażenie (i < 5), następnie drugie wyrażenie (i < c), a pełne wyrażenie przyjmuje wartość drugiej części.

Pierwsza część wyrażenia ma znaczenie tylko w przypadku wystąpienia efektów ubocznych.

Jest powszechnie, a właściwie stosowane w ten sposób:
przykład

for(i = 0, j = 10; i < 10; ++i, --j) 
/* i goes from 0-10, while j goes from 10-0 at the same time */ 

Ale w sposób przedstawiony w kodzie, to nie ma żadnego sensownego celu, a tylko dezorientuje innych ludzi.

1

Tutaj , operator przecinka odgrywa ważną rolę. Znaczy, przechwytuje od lewej do prawej i zwraca ostatnie wyrażenie. Tak więc oszacowano wartość i<5, wartość i<c została oszacowana, ale zwraca wynik i<c jako ostatnie wyrażenie.

i < 5, i < c jest całkowicie bezsensowne. Nie ma różnicy z i < c.

W zależności od autora logika jest błędem.

7

To jest operator przecinka . Ocenia jej lewy i prawy operand (zawsze w tej kolejności) i daje wynik prawego argumentu. Sensowne jest użycie go, jeśli lewy operand jest oceniany pod kątem skutków ubocznych; ponieważ i < 5 nie ma skutków ubocznych, Twój kompilator ostrzega o tym.

To jest i < 5, a nie i < c, które jest ignorowane. Kod jest równoznaczne z:

for (i = 0; i < c; i++) { 
    ... 
} 

Trudno odgadnąć, co było przeznaczone być. Być może autor miał na myśli:

for (i = 0; i < 5 && i < c; i++) { 
    ... 
} 
3

Wynik operatora przecinek jest wartość prawego argumentu.

Tutaj lewy operand (i < 5) ma efekt uboczny tak

i < 5, i < c 

jest rzeczywiście równoważne do

i < c 
2

Jest to wynikiem zastosowania operatora przecinkami. Wyrażane jest lewe wyrażenie, a następnie wynik jest odrzucany. Następnie oceniane jest właściwe wyrażenie. Wynik operatora przecinka jest wynikiem prawidłowego wyrażenia.

Ponieważ lewe wyrażenie (i < 5) nie jest operacją, pojawia się ostrzeżenie, które widzisz. Pytanie brzmi: "co autor zamierzał?" Bez dalszych kontekście nie możemy naprawdę powiedzieć, ale jest to prawdopodobnie jeden z nich:

i < 5 
    i < c 
    i < 5 && i < c