Pisemne wersje operatorów logicznych


95

To jest jedyne miejsce, jakie kiedykolwiek widziałem and, ora notna liście rzeczywistych operatorów w C ++. Kiedy napisałem program testowy w NetBeans, zauważyłem czerwone podkreślenie, jakby był błąd składniowy i pomyślałem, że witryna jest błędna, ale to NetBeans jest błędny, ponieważ skompilował się i działał zgodnie z oczekiwaniami.

Widzę, !że są faworyzowani, notale czytelność and&& orwydaje się większa niż w przypadku ich braci gramatycznych. Dlaczego te wersje operatorów logicznych istnieją i dlaczego pozornie nikt ich nie używa? Czy to naprawdę poprawne C ++, czy jakaś kompatybilność z C, która została dołączona do języka?


4
\ me Przepisuje cały swój kod
Limited Atonement

2
w duchu „czystego kodu” osobiście zalecam pozbycie się nawyku pisania, ||a &&może nawet !czasami. Słowa są zawsze lepsze niż „szum linii”, nie wspominając o możliwym pomyleniu z operatorami manipulacji bitami.
Ichthyo

2
@Ichthyo To nie zawsze jest poprawne. O wiele szybciej jest odczytać wiele symboli i poznać ich znaczenie, niż czytać wiele słów.
vallentin

to, co jest jaśniejsze dla ludzkiego czytelnika, zależy od „Gestalt”. Czasami symbol może być wyraźniejszy niż jakiś niejasny termin, ale w tym przypadku tak nie jest. A proste słowa języka angielskiego są znacznie bardziej uniwersalne niż niektóre dziwne symbole specjalne nieco dziwnego języka programowania ...
Ichthyo

3
Ironia andpolega na tym, że powiedzenie, że jest bardziej czytelne, a potem napisanie „ and&& or” :)
Ivan Vergiliev

Odpowiedzi:


113

Pochodzą z C w nagłówku <iso646.h>. W tamtym czasie istniały klawiatury, które nie mogły wpisać wymaganych symboli &&(na przykład), więc nagłówek zawierał te #define, które pomogłyby im w tym, poprzez (w naszym przykładzie) zdefiniowanie, andże jest &&. Oczywiście w miarę upływu czasu stawało się to mniej wykorzystywane.

W C ++ stały się tak zwanymi alternatywnymi tokenami . Zdajesz nie muszą obejmować niczego do używania tych znaków w kompilatora zgodnego (jako takie, C ++ - ified wersję nagłówka C, <ciso646>jest puste). Alternatywne tokeny są takie same jak zwykłe tokeny, z wyjątkiem pisowni. Więc podczas parsowania andjest dokładnie to samo &&, co po prostu inny sposób zapisywania tego samego.

Jeśli chodzi o ich użycie: ponieważ są rzadko używane, używanie ich jest często bardziej zaskakujące i zagmatwane niż pomocne. Jestem pewien, że gdyby to było normalne, byłoby dużo łatwiejsze do odczytania, ale ludzie są do tego przyzwyczajeni &&i ||wszystko inne po prostu rozprasza.

EDYCJA: Odkąd to opublikowałem, zauważyłem jednak bardzo niewielki wzrost ich użycia. Nadal ich unikam.


Czy zatem interpretacja tych alternatywnych tokenów jest tylko funkcją kompilatora, czy jest zawarta w specyfikacji C ++?
uszkodzonyhalt

2
@Kavon: Jest to określone w sekcji 2.5 standardu; jest to funkcja językowa.
GManNickG

15
Osobiście uważam, że są znacznie lepsze ... ale poza tym jestem stronniczy w Pythonie. Nie wiem, dlaczego niektórzy myślą, że jeśli nie jest zniekształcony, to nie jest kod ...
Matthieu M.

Więc nie są one prawidłowe w C bez dołączenia tego pliku nagłówkowego? Dziwię się, że nie wszyscy z nich korzystają; sprawiają, że Python jest o wiele bardziej czytelny.
endolit

1
Przynajmniej Visual Studio 2015 CTP 6 nie podobał mi się mój orlub notbez dołączenia nagłówka.
usr1234567

19

Istnieją one dla użyteczności (obsługa znaków w smakach klawiatury / wyświetlacza) i ogólnej czytelności, ale jest inny powód, który jest obecnie bardziej wyraźny. Prawie żadna z odpowiedzi tutaj , tutaj , ani nawet główna odpowiedź tutajWyjaśnij główny powód, dla którego wielu z nas woli wersje słowne od wersji symboli (i główny powód, dla którego używają ich inne języki): błędy. Różnice między wersjami słów są bardzo widoczne. Różnice między wersjami symboli są znacznie mniejsze, do tego stopnia, że ​​kuszą błędy w stosunkowo dużo większym stopniu: „x | y” w zasadzie nie jest „x || y”, ale gdy jest osadzony w większym wyrażeniu, wielu z nas przegapić różnicę. Jest to podobne do typowego przypadkowego mieszania operatora przypisania i równości. Z tego powodu odsunąłem się od wersji symboli (nie było to łatwe) na rzecz wersji słownych. Wolałbym, żeby ktoś z nich wziął się podwójnie z powodu naszej miłości do starych rzeczy, niż kusić robaki.


4
Niestety w programie Visual Studio (od VS2013) należy ustawić określoną opcję kompilatora ( /Za), aby obsługiwać alternatywne słowa kluczowe (patrz stackoverflow.com/a/555524/368896 ). Prawdopodobnie ma to również inne skutki. Dlatego w programie Visual Studio skorzystanie z tej porady niekoniecznie jest bezpieczne.
Dan Nissenbaum

FWIW / - ponieważ umieściłem spacje wokół operatorów, x | yjest wystarczająco wizualnie odrębny (czcionkami o stałej szerokości) od x || y, ale uważam, że !np. if (!f(xyz) && ...Łatwiej jest przeoczyć niż if (not f(xyz) && ....
Tony Delroy,

@Tony D, kiedy umieszczasz spacje wokół operatorów, jest to twoja prywatna konwencja i nie jest oczywista dla czytelnika. Lecz za pomocą słów języka naturalnego podoba and, ora notw logicznej wypowiedzi, rzeczywiście poprawia czytelność plus to podkreśla rozróżnienie bitowych manipulacji. Dlatego IMHO powinniśmy rozważyć zmianę naszych ukochanych starych nawyków na lepsze ...
Ichthyo

@DanNissenbaum Tę opcję znalazłem pod nazwą C / C ++> Język> Wyłącz rozszerzenia językowe , więc stosunkowo bezpiecznie można spodziewać się efektów ubocznych;)
Wolf

6
Czy wiesz, ile błędów w Pythonie zostało wprowadzonych z powodu słów andi oruprzedzeń, które ludzie myślą o tym, jak powinni działać? Np. if (a == b or c)Zamiast if (a == b || a == c)- coś takiego pojawia się prawie codziennie w StackOverflow. Abstrakcyjne symbole, które są odłączone od języka angielskiego, zmniejszają te błędy.
Mark Ransom

10

W C ++ są prawdziwymi słowami kluczowymi. W C są to makra zdefiniowane w <iso646.h>. Zobacz http://web.archive.org/web/20120123073126/http://www.dinkumware.com/manuals/?manual=compleat&page=iso646.html .


6
Z technicznego punktu widzenia są to alternatywne tokeny, a nie słowa kluczowe. :)
GManNickG

2
@GMan: +1 Niezłe połączenie, strona Dinkumware nazywa je słowami kluczowymi, więc przypuszczam, że nie przejmowali się zbytnio tym rozróżnieniem.
Chris Jester-Young


Czy więc MSVC obsługuje je po wyjęciu z pudełka w C ++, ale nie w C?
pierwszy

1
@rwst Nie mogę komentować w szczególności MSVC, ale jeśli wiernie implementuje standardy C ++ i C, to rzeczywiście tak będzie. Zobacz też: stackoverflow.com/questions/2376448/…
Chris Jester-Young

2

andi &&funkcjonalnie są takie same w C ++. andI oroperatorzy są naprawdę ważne C ++ i częścią standardu językowego.

Wypracowanie na innych odpowiedzi o przykład betonu, nie ma innego powodu, oprócz tylko „czytelności” wolą andponad &&. Wyraźne pisanie „i”, gdy logiczne AND jest tym, co masz na myśli, eliminuje możliwość subtelnych błędów.

Rozważ to:

int x = 3;
int y = 4;

// Explicitly use "and"
if (x and y) {
    cout << "and: x and y are both non-zero values" << endl;
}

// Using "&&"
if (x && y) {
    cout << "&&: x and y are both non-zero values" << endl;
}

// Oops! I meant to type "&&"!
if (x & y) {
    cout << "&: x and y are both non-zero values" << endl;
}
else {
    cout << "How did I get here?" << endl;
}

Wszystkie trzy instrukcje if zostaną skompilowane, ale ostatnia oznacza coś zupełnie innego i niezamierzonego!

Jeśli zawsze używasz, andgdy masz na myśli logiczne AND, nigdy nie możesz przypadkowo wpisać pojedynczego znaku „&” i sprawić, że kod zostanie pomyślnie skompilowany i uruchomiony z tajemniczymi wynikami.

Kolejne dobre ćwiczenie: spróbuj przez przypadek pominąć znak „i” i zobacz, co się stanie. ;)


1
To nie jest tak naprawdę odpowiedź na pytanie. Po prostu stwierdzasz, co uważasz za bardziej czytelne. PO zapytał, jak działają wersje pisemne, a nie które są lepsze. A ktoś inny już powiedział o tym, co ty próbujesz zrobić.
Nicol Bolas

Nie żeby tak naprawdę zawierało więcej użytecznych informacji, ale do odpowiedzi dodam " andi &&są funkcjonalnie identyczne" ... A jeśli przeczytasz moją odpowiedź, zobaczysz, że nie mówię o czytelności;)
tjwrona1992
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.