2011-01-24 11 views
5

Czytałem w wielu miejscach, ale naprawdę nie mogę zrozumieć określonego zachowania w warunkowych.Operator przecinania warunkowego

Rozumiem, że w przydziałach ocenia pierwszy operand, odrzuca wynik, a następnie ocenia drugi operand.

Ale co do tego kodu, co powinien zrobić?

CPartFile* partfile = (CPartFile*)lParam; 
ASSERT(partfile != NULL); 
bool bDeleted = false; 
if (partfile,bDeleted) 
    partfile->PerformFileCompleteEnd(wParam); 

Partfile w IF był niepotrzebnym argumentem, czy ma jakieś znaczenie?

+0

Może to pomoże: http://stackoverflow.com/questions/54142/c-comma-operator –

+0

Jedną z możliwości jest że koder miał na myśli 'if (partfile && bDeleted)', niektóre inne języki programowania mają 'IF a, b' oznaczać" jeśli aib " –

Odpowiedz

9

W tym przypadku jest to niepotrzebne wyrażenie, które można usunąć bez zmiany znaczenia kodu.

+3

Operator przecinka jest nadpisywalny. Może użycie go może zmienić stan wypowiedzi lewej ręki. – Benoit

+0

@Benoit Nie może być przeciążony dla dwóch typów pierwotnych (w tym przypadku wskaźnik i bool); co najmniej jeden operand musi mieć klasę typu –

4

Operator przecinka wykonuje wyrażenie pierwszego elementu, odrzuca wyniki, a następnie ocenia wynik jako ostatnie wyrażenie.

partfile,bDeleted więc byłoby evaulate cokolwiek partfile byłoby wyrzucić tego rezultatu, a następnie ocenić i powrócić bDeleted

Jest to przydatne, gdy trzeba ocenić coś, co ma skutki uboczne (na przykład wywołanie metody). W tym przypadku jest to jednak bezużyteczne.

Aby uzyskać więcej informacji, zobacz Wikipedia: Comma operator

+0

Operator przecinka nie ocenia elementów n-1. Każdy operator w C/C++ jest albo jednoargumentowy, albo binarny. Jeśli umieścisz kilku operatorów przecinania w jednym wierszu, oceni on pierwszy element, odrzuci go, oceni drugi element i użyje drugiego elementu jako argumentu dla następnego operatora przecinka na linii. Oczywiście wynik będzie taki sam, jak gdyby oceniał n-1 przedmiotów, ale aby zrozumieć, dlaczego, musisz wiedzieć, co dzieje się pomiędzy, aby dostać się do ostatniego przedmiotu. – Lundin

+0

Dobra sprawa, myślałem, że a, b, c było jednym terminem (czy to właściwe sformułowanie?), Ale to nie jest prawda, ponieważ istnieją tam dwa operatory przecinania. naprawiony post – helloworld922

1

partfile jest oceniany, a następnie bDeleted jest oceniane i wykorzystywane jako test. Ponieważ ocena pliku partfile nie ma żadnych skutków ubocznych, usunięcie go z warunkowego nie ma żadnego efektu.

+0

Masz go od tyłu, partfile zostaje oceniony i zignorowany, a bDeleted zostaje oceniony i zwrócony. – helloworld922

+0

@ helloworld922: prawda, naprawi. – ThomasMcLeod

2
bool bDeleted = false; 
if (partfile,bDeleted) 
    partfile->PerformFileCompleteEnd(wParam); 

Tutaj oświadczenie if ocenia partfile, bDeleted, ale bdelete jest zawsze fałszywe, więc wyrażenie nie uruchomić. Kluczowe pytanie brzmi "o co w tym wszystkim chodzi?". Prawdopodobną odpowiedzią jest to, że ktoś tymczasowo chciał uniemożliwić działanie instrukcji partfile->PerformFileCompleteEnd(wParam);, być może dlatego, że powodował pewien problem lub chciał poprawnie zapewnić późniejsze zgłaszanie błędów w kodzie, jeśli ten krok nie został wykonany. Aby pamiętali, jak kod był kiedyś, zostawili starą logikę "if (partfile)", ale dodali zakodowaną na stałe zmienną bDeleted, aby udowodnić, że logika partfile->Perform... została "usunięta" z programu.

Lepszym sposobem, aby tymczasowo wyłączyć takiego kodu jest prawdopodobnie ...

#if 0 
    if (partfile) 
     partfile->PerformFileCompleteEnd(wParam); 
#endif 

... chociaż czasami staram się dokumentować rozumowanie też ...

#ifndef DONT_BYPASS_FILE_COMPLETE_PROCESSING_DURING_DEBUGGING 
    if (partfile) 
     partfile->PerformFileCompleteEnd(wParam); 
#endif 

... lub ...

if (partFile, !"FIXME remove this after debugging") 
    partfile->PerformFileCompleteEnd(wParam); 

najlepszy wybór zależy od zestawu narzędzi i istniejących nawyków (np Niektóre edytory podświetlić „FIXME” lub „TODO” w odwróconym filmie wideo, więc trudno go pomijać lub wyszarzać #if 0 bloków; możesz mieć określone ciągi, o których ostrzega twoje sterowanie kontrolą źródła; preprocesor definiuje tylko w debugowaniu, a kompilacje wersji mogą uniemożliwić przypadkową dystrybucję itp.).

1

Operator przecinka jest dość mało znaną funkcją C/C++. Nie należy go mylić z przecinkiem w listach inicjujących (tj: int x, int y;) ani z przecinkiem parametru funkcji wywołania funkcji (np .: func (x, y)).

Operator przecinka ma jeden cel: zapewnić programistom gwarantowaną kolejność oceny wyrażenia. Dla prawie każdego operatora w C/C++, kolejność oceny wyrażeń jest niezdefiniowana. Jeśli napiszę:

wynik = x + y;

gdzie x i y są podwyrażeniami, wtedy x lub y mogą być ocenione jako pierwsze. Nie wiem, który, to zależy od kompilatora. Jeśli jednak napiszesz:

wynik = x, y;

kolejność oceny jest gwarantowana przez standard: lewy pierwszy.

Oczywiście, zastosowania tego w rzeczywistych zastosowaniach światowych są dość ograniczone ...

Powiązane problemy