Ez a kérdés lehet néma, de miért 0
értékeli ezt: false
és bármely más [egész szám] érték a true
értékre a legtöbb programozási nyelv?
Karakterlánc összehasonlítás
Mivel a kérdés kicsit túl egyszerű, még egy kicsit elmagyarázom magamnak: először is minden programozó számára nyilvánvalónak tűnhet, de miért ne lenne programozási nyelv – valójában lehet, de nem olyan, amelyet használtam – ahol 0
true
értékre, az összes többi [egész] értékre false
értéket ad? Ez az egyetlen megjegyzés véletlenszerűnek tűnhet, de van néhány példám, ahol jó ötlet lehetett. Először is vegyük a húrok háromirányú összehasonlításának példáját, C “s strcmp
mint példa: minden olyan programozó, aki C-t próbálja első nyelvként, megkísérelheti a következő kódot írni:
if (strcmp(str1, str2)) { // Do something... }
Mivel strcmp
0
amely false
-re értékeli, ha a karakterláncok egyenlőek, amit a kezdő programozó megpróbált megtenni, csúnyán elbukik, és általában nem érti először. Ha ehelyett 0
értékelték volna, hogy true
, akkor ezt a függvényt a legegyszerűbb – a fenti kifejezésben – az egyenlőség összehasonlításakor lehetett volna használni, és a -1
és 1
megfelelő ellenőrzéseket csak szükség esetén végezték volna el. A visszatérési típust legtöbbször bool
-nek tekintettük (gondolatunkban erre gondolok).
Ezenkívül vezessünk be egy új típust, sign
, amely éppen -1
, 0
és 1
. Ez nagyon hasznos lehet. Képzelje el, hogy van egy űrhajó-üzemeltető a C ++ nyelven, és szeretnénk, ha a std::string
(nos, már létezik a compare
függvény, de az űrhajó-üzemeltető szórakoztatóbb). A deklaráció jelenleg a következő lenne:
sign operator<=>(const std::string& lhs, const std::string& rhs);
0
értékelték volna true
, az űrhajó-üzemeltető nem is létezne, és így deklarálhattuk volna a operator==
-t:
sign operator==(const std::string& lhs, const std::string& rhs);
Ez operator==
egyszerre háromirányú összehasonlítást kezeltek, és továbbra is felhasználhatók a következő ellenőrzés elvégzésére, miközben továbbra is ellenőrizni tudták, hogy melyik karakterlánc a lexikográfiai szempontból felülmúlja a másikat, ha szükséges:
if (str1 == str2) { // Do something... }
Régi hibakezelés
Most vannak kivételeink, ezért ez a rész csak a régi nyelvekre vonatkozik, ahol ilyen nincs létezik (például C). Ha megnézzük a C szabványos könyvtárát (és a POSIX könyvtárat is), akkor biztosan láthatjuk, hogy a maaaaany függvények sikeresen 0
-et adnak vissza, máskülönben pedig egész számot. Sajnos néhány embert láttam tegyen ilyeneket:
#define TRUE 0 // ... if (some_function() == TRUE) { // Here, TRUE would mean success... // Do something }
Ha belegondolunk, hogyan gondolkodunk programozáskor gyakran a következő érvelési mintánk van:
Do something Did it work? Yes -> That"s ok, one case to handle No -> Why? Many cases to handle
Ha belegondolunk megint értelmes lett volna az egyetlen semleges értéket, 0
, hogy yes
(és hogy “C” függvények működnek), míg az összes többi érték ott lehet, hogy megoldja a no
sok esetét. Mindazonáltal az összes általam ismert programozási nyelvben (talán néhány kísérleti ezoterikus nyelv kivételével), hogy yes
false
-re értékeli if
állapotban, wh Az összes no
eset true
-re változik. Sok helyzet van, amikor a “működik” egy esetet képvisel, míg a “nem működik” a valószínű okokat. Ha így gondolkodunk, akkor ha 0
értékeli true
, a többit pedig false
sokkal értelmesebb lett volna.
Következtetés
A következtetésem lényegében az eredeti kérdésem: miért terveztünk olyan nyelveket, ahol 0
található false
és a többi érték true
, figyelembe véve néhány fenti példámat, és talán még néhányat, amire nem gondoltam?
Utánkövetés: Nagyon jó látni, hogy sok válasz van sok ötlettel és annyi lehetséges okkal imádom, hogy milyen szenvedélyesnek tűnik emiatt.Eredetileg unalomból tettem fel ezt a kérdést, de mivel annyira szenvedélyesnek tűnik, úgy döntöttem, hogy tovább megyek, és rákérdezek a logikai választás indokaira 0 és 1 a Math.SE-n 🙂
Megjegyzések
Válasz
0
false
, mert mindkettő nulla elem a közös félosztályokban . Annak ellenére, hogy különálló adattípusok, intuitív értelemben van konvertálni közöttük, mert izomorf algebrai struktúrákhoz tartoznak.
-
0
az összeadás azonosítója és a szorzás nulla. Ez igaz egész számokra és racionális értékekre, de nem IEEE-754 lebegőpontos szám:0.0 * NaN = NaN
és0.0 * Infinity = NaN
. -
false
a logikai xor (⊻) és nulla a logikai identitása és (∧). Ha a Booleans-t {0, 1} -ként – a modulo 2 egész számok halmazaként – ábrázolhatjuk, úgy gondolhatjuk, hogy ⊻ hordozás nélküli összeadás és and szorzás. -
""
és a[]
azonosítás az összefűzéshez, de számos olyan művelet létezik, amelyeknél nullának van értelme. Az ismétlés az egyik, de az ismétlés és az összefűzés nem terjeszti, így ezek a műveletek nem alkotnak semiringet.
Az ilyen implicit átalakítások hasznosak kis programokban, de nagyban nehezebben indokolhatja a programokat. Csak egy a sokféle kompromisszumból a nyelvtervezésben.
Megjegyzések
- Szép, hogy Ön felsorolt. (BTW,
nil
mind az üres lista[]
, mind afalse
érték a Common Lisp-ben ; van-e hajlandóság a különböző adattípusokból származó identitások egyesítésére?) Még mindig meg kell magyaráznia, miért természetes, hogy a hamisat additív identitásnak, az igazat pedig multiplikatív identitásnak tekintjük, és nem fordítva. Nem lehetséges, hogy ‘ atrue
-et aAND
azonosítójaként és aOR
? - +1 hasonló identitásokra való hivatkozásért. Végül egy olyan válasz, amely nem ‘ csak leforr a ” egyezményig, foglalkozzon vele “.
- +1 egy konkrét és nagyon régi matematika részleteinek megadásáért, amelyben ezt követték és régóta értelmes volt
- Ez a válasz nem ‘ t van értelme. A
true
a félidők (logikai és / vagy) identitása és nulla. Nincs ok arra, hogy alkalmazzuk a konvenciót, hogy úgy gondoljuk, hogy afalse
közelebb van a 0-hoz, mint atrue
. - @TonioElGringo: Az igaz és hamis különbség az XOR és az XNOR közötti különbség. Izomorf gyűrűket alkothatunk az AND / XOR használatával, ahol igaz a multiplikatív azonosság és hamis az additív, vagy OR és XNOR esetén, ahol hamis a multiplikatív azonosság és az igaz az additív, de az XNOR-ot általában nem tekintik közösnek alapvető művelet az XOR módja.
Válasz
Mivel a matematika működik.
FALSE OR TRUE is TRUE, because 0 | 1 is 1. ... insert many other examples here.
Hagyományosan a C programok olyan feltételekkel rendelkeznek, mint
if (someFunctionReturningANumber())
helyett
if (someFunctionReturningANumber() != 0)
mert a nulla egyenértékű hamis fogalma jól érthető.
Megjegyzések
- A nyelveket azért tervezték, mert a matematikának van értelme. Ez jött előbb.
- @Morwenn, a 19. századig nyúlik vissza és George Boole. Az emberek a False-t 0-ként és True-t! 0-ként jelentik hosszabb ideig, mint ahány számítógép volt.
- Nem tudom, ‘ miért nem látom a matematikát ‘ akkor nem működik másképp, ha csupán az összes definíciót megváltoztatja úgy, hogy az AND + és OR legyen *.
- Pontosan: a matematika mindkét irányban működik, és a válasz úgy tűnik, hogy ez a kérdés tisztán konvencionális.
- @Robert ‘ d nagyszerű lenne, ha meg tudná mondani a ” matematikai alapok ” a bejegyzésedben.
Válasz
Mint mások mondták, a matematika volt az első. Ezért 0 a false
, az 1 pedig true
.
Melyik matematikáról beszélünk? Boole-algebrák , amelyek az 1800-as évek közepétől származnak, jóval a digitális számítógépek megjelenése előtt.
Azt is mondhatja, hogy a konvenció propozíciós logikából jött ki, amely még a logikai algebráknál is régebbi. Ez sok olyan logikai eredmény formalizálása, amelyet a programozók ismernek és szeretnek (false || x
egyenlő x
, true && x
egyenlő x
és így tovább).
Alapvetően két elemű halmazon beszélünk az aritmetikáról. Gondoljon a bináris számolásra. A logikai algebrák eredete ennek a koncepciónak és elméleti megalapozásának. Az olyan nyelvek konvenciói, mint a C, csak egy egyszerű alkalmazás.
Megjegyzések
- , az biztos. De ha a ” szabványos ” módon tartjuk, az jól illeszkedik az általános aritmetikához (0 + 1 = 1, nem 0 + 1 = 0).
- Igen, de feltehetően az ÉS-t írná a + és az OR gombbal, ha megfordítaná a definíciókat.
- A matematika nem ‘ nem az első. Math felismerte, hogy a 0 és az 1 olyan mezőt alkot, amelyben az ÉS olyan, mint a szorzás, az OR pedig az összeadás.
- @ Kaz: De a {0, 1} az OR és az AND nem alkot mezőt.
- Kicsit zavar, hogy több válasz és megjegyzés azt mondja, hogy
true = 1
. Ez ‘ nem egészen pontos, merttrue != 0
ami nem teljesen ugyanaz. Az egyik ok (és nem az egyetlen), amiért el kell kerülni az összehasonlításokat, példáulif(something == true) { ... }
.
Válasz
Úgy gondoltam, hogy ennek köze van az elektronika “öröklődéséhez”, valamint a logikai algebrához, ahol
-
0
=off
,negative
,no
,false
-
1
=on
,positive
,yes
,true
strcmp 0 értéket ad vissza, ha a karakterláncok egyenlőek, a megvalósítással van összefüggésben, mivel valójában azt jelenti, hogy kiszámolja a két karakterlánc közötti távolságot. Az, hogy a 0-t is véletlenül hamisnak tekintik, csak egybeesés.
0 visszatérése a sikernek van értelme mert a 0 ebben az esetben nincs hiba jelentése, és bármely más szám hibakódnak számít. Bármely más szám használata sikernek kevésbé lenne értelme, mivel csak egyetlen sikerkódja van, míg több hibakódja is lehet. Ön a “Működött?” mint ha az if kifejezés kifejezés és a 0 = igen kimondása sokkal értelmesebb lenne, de a kifejezés helyesebb: “Valami baj történt?” és akkor látod, hogy a 0 = nem sok értelme van. A false/true
-re gondolni itt nincs igazán értelme, mivel valójában no error code/error code
.
Megjegyzések
- Haha, te vagy az első, aki kifejezetten kimondja a visszatérési hiba kérdését. Már tudtam, hogy értelmezem a magam módján, és ezt meg is kérdezhetném másképp, de te ‘ te vagy az első, aki kifejezetten kifejezi (a sok válasz és megjegyzés közül).Valójában nem mondanám ‘ azt, hogy egyik vagy másik útnak nincs értelme, de több mindkettőnek különböző módon van értelme 🙂
- Valójában én ‘ d mondjuk
0
asuccess/no error
számára az egyetlen, aminek van értelme, ha más egész számok hibakódokat képviselnek . Ez az0
véletlenül afalse
-et is képviseli, más esetekben pedig nem igazán fontos, mert ‘ itt egyáltalán nem igazakról vagy hamisakról beszélünk;) - nekem ugyanaz volt az elképzelésem, ezért támogattam
-
strcmp()
a távolság kiszámítása nagyon jó. Hastrdiff()
-nek hívták volna, akkor aif (!strdiff())
nagyon logikus lenne. - ” elektronika […] ahol 0 = […] hamis, 1 = […] igaz ” – ez még az elektronikában is csak egy konvenció , és nem csak ‘ t. Ezt pozitív logikának hívjuk, de használhatunk negatív logikát is, ahol a pozitív feszültség hamisat, a negatív pedig igazat jelöl. Ezután az áramkör, amelyet ‘ használ az ÉS számára, VAGY, vagy VAGY ÉS lesz, és így tovább. A De Morgan ‘ törvény miatt mindez ekvivalens lesz. Előfordul, hogy ‘ megtalálja az elektronikus áramkör egy részét, amely a kényelem kedvéért negatív logikában valósul meg, és ekkor az adott részen lévő jelek nevét felette egy sáv jelöli.
Válasz
Amint azt a ebben a cikkben , a false
és a true
értékeket nem szabad összekeverni a 0 és 1 egész számokkal, de azonosíthatók a Galois mező elemeivel (véges mező) két elemből (lásd itt ).
A mező két művelettel rendelkező halmaz, amely bizonyos axiómákat kielégít.
A 0 és 1 szimbólumokat hagyományosan egy mező additív és multiplikatív identitásának jelölésére használják, mivel a valós számok is egy mező (de nem véges), amelynek azonossága a 0 és 1 szám.
Az additív azonosság a mező 0. eleme, amely az összes x esetében:
x + 0 = 0 + x = x
és a multiplikatív identitás a mező 1. eleme, oly módon, hogy az összes x esetében:
x * 1 = 1 * x = x
Két elem véges mezőjében csak ez a két elem szerepel, mégpedig additív identitás 0 (vagy false
) és az 1 multiplikatív identitás (vagy true
). Ennek a mezőnek a két művelete a logikai XOR (+) és a logikai ÉS (*).
Megjegyzés. Ha megfordítja a műveleteket (XOR a szorzás és az AND az összeadás), akkor a szorzás nem disztributív az összeadás felett, és nincs többé mezője. Ilyen esetben nincs oka a két elem 0 és 1 (tetszőleges sorrendben) hívására. Vegye figyelembe azt is, hogy nem választhatja az OR műveletet az XOR helyett: függetlenül attól, hogy az OR / AND-t hogyan értelmezi összeadásként / szorzásként, az eredményül kapott szerkezet nem mező (nem minden inverz elem létezik, ahogy azt a mező axiómái megkövetelik).
A C függvényekkel kapcsolatban:
- Sok függvény egy egész számot ad vissza, amely hibakód. A 0 azt jelenti, hogy NINCS HIBA.
- Intuitív módon a
strcmp
függvény kiszámítja a két karakterlánc közötti különbséget. A 0 azt jelenti, hogy nincs különbség két karakterlánc között, vagyis hogy két karakterlánc egyenlő.
A fenti intuitív magyarázatok segíthetnek emlékezni a visszatérő értékek értelmezésére, de még egyszerűbb csak ellenőrizze a könyvtár dokumentációját.
Megjegyzések
- +1 annak bizonyítására, hogy ha önkényesen cserélgeti ezeket, a matematika már nem működik.
- Megfordítva: Ha két elemű műveletet és * és + mezőt adunk meg, akkor a True-t 0-val, a False-t 1-vel azonosítjuk. A OR-t a * -val, az XOR-t a + -al azonosítjuk.
- Meg fogja találni, hogy mindkettő ezen azonosítások ugyanazon a mezőn keresztül történnek, és mindkettő összhangban van a logikai szabályokkal. A megjegyzés sajnos helytelen 🙂
- Ha azt feltételezi, hogy True = 0, és az XOR +, akkor az True-nak kell lennie az XOR identitásának. De nem azért, mert True XOR True = Hamis. Hacsak nem definiálja újra az XOR műveletet a True-on, így a True XOR True = True. Aztán természetesen az építkezésed működik, mert csak átnevezted a dolgokat (bármilyen matematikai struktúrában mindig sikeresen létrehozhatsz névmutatást és izomorf struktúrát kapsz). Másrészt, ha hagyja, hogy az Igaz, a Hamis és az XOR a szokásos jelentéssel bírjon, akkor az Igaz XOR Igaz = Hamis és Igaz nem lehet az additív identitás, vagyis az Igaz nem lehet 0.
- @Giorgio: Az utolsó megjegyzésemben megjavítottam a megjegyzésem kommentje alapján…
Válasz
Fontolja meg, hogy alternatív rendszerek is elfogadható tervezési döntések lehetnek.
Héjak: A 0 kilépési állapot igaz, a nulla értéke hamis
A 0-t kezelő héjak példája a kilépés állapotát igazként már említettük.
$ ( exit 0 ) && echo "0 is true" || echo "0 is false" 0 is true $ ( exit 1 ) && echo "1 is true" || echo "1 is false" 1 is false
Ennek oka van a sikernek egy módja van, de a kudarc sokféleképpen, így a 0 használata speciális értékként, amely “nincs hiba”, pragmatikus.
Ruby: 0 pontosan olyan, mint bármely más szám
A “normál” programozási nyelvek között van néhány olyan kiugró érték, mint például a Ruby, amelyek a 0-t valós értékként kezelik.
$ irb irb(main):001:0> 0 ? "0 is true" : "0 is false" => "0 is true"
A indoklás szerint csak false
és nil
hamisak lehetnek. Sok Ruby-újonc számára ez nagyon jó. Egyes esetekben azonban jó, hogy a 0-t ugyanúgy kezeljük, mint bármely más számot.
irb(main):002:0> (pos = "axe" =~ /x/) ? "Found x at position #{pos}" : "x not found" => "Found x at position 1" irb(main):003:0> (pos = "xyz" =~ /x/) ? "Found x at position #{pos}" : "x not found" => "Found x at position 0" irb(main):004:0> (pos = "abc" =~ /x/) ? "Found x at position #{pos}" : "x not found" => "x not found"
, egy ilyen rendszer csak olyan nyelven működik, amely képes megkülönböztetni a logikai értékeket külön típusként a számoktól. A számítás korábbi napjaiban az összeállítási nyelvvel vagy a nyers gépnyelven dolgozó programozóknak nem volt ilyen luxusuk. Valószínűleg természetes, hogy a 0-at “üres” állapotként kezeljük, és kissé 1-re állítjuk zászlóként, amikor a kód észleli, hogy valami történt. Tágabb értelemben az a megállapodás alakult ki, hogy a nullát hamisnak, a nem nulla értékeket pedig igaznak tekintették. Ennek azonban nem kell így lennie.
Java: A számokat egyáltalán nem lehet logikai értékként kezelni
Java-ban a true
és a false
az egyetlen logikai érték. A számok nem logikai értékek, és nem is dobhatók logikai értékekbe ( Java nyelv specifikáció, Sec 4.2.2 ):
Az integrált típusok és a
boolean
típus között nincs casting .
Ez a szabály csak teljesen elkerüli a kérdést – az összes logikai kifejezést kifejezetten be kell írni a kódba.
Megjegyzések
- A Rebol és a Red mind a 0 értékű INTEGER! értékeket igaznak tekinti, és külön NINCS! típussal rendelkezik (csak egy értékkel, NINCS) feltételes hamisként kezelve a LOGIC! false mellett. I ‘ jelentős csalódottságot tapasztaltam a 0-t hamisnak kezelő JavaScript-kód megírásában; egy növekmény ehetően ügyetlen döntés egy dinamikusan tipizált nyelv mellett. Ha olyan dolgot szeretne tesztelni, amely null vagy 0 lehet, akkor fel kell írnia a
if (thing === 0)
szöveget, az egyszerűen nem jó. - @HostileFork én nem ‘ nem tudom. Úgy látom, hogy van értelme, hogy a
0
true
(mint minden más egész szám) dinamikus nyelven. Néha előfordult, hogy elkaptam egy0
-t, amikor megpróbáltam elkapni aNone
-t Pythonban, és ezt néha elég nehéz észrevenni. - A rubin nem kirívó. Ruby ezt elveszi Lisp-től (Ruby-t titokban még ” MatzLisp ” -nek is hívják. A Lisp az informatika egyik fő nyelve. A nulla is csak egy igazi érték a POSIX shellben, mert ‘ egy szövegrészt:
if [ 0 ] ; then echo this executes ; fi
. A hamis adatok értéke egy üres karakterlánc, a tesztelhető hamisítás pedig egy parancs sikertelen felmondási állapota, amelyet non -zér jelent.
Válasz
Mielőtt az általános esetet tárgyalnánk, megbeszélhetjük az ellenpéldákat.
Karakterlánc-összehasonlítások
Ugyanez vonatkozik sokféle összehasonlításra is. Az ilyen összehasonlítások távolságot számolnak két objektum között. Ha az objektumok egyenlőek, akkor a távolság minimális. Tehát, ha az “összehasonlítás sikeres”, akkor az értéke 0. De valójában a strcmp
visszatérési értéke nem logikai érték, ez távolság, és hogy mi csapdába ejti a programozókat, akik nem tudják, hogy if (strcmp(...)) do_when_equal() else do_when_not_equal()
.
A C ++ – ban újratervezhetnénk a strcmp
elemet egy Distance
objektum, amely felülírja a (z) operator bool()
objektumot, ha igaz értéket ad vissza, amikor 0 (de akkor más problémák haladnának meg). Vagy a C közönségében csak van egy streq
függvény, amely 1-et ad vissza, ha a karakterlánc egyenlő, és 0-t különben.
API hívások / program kilépési kód
Itt érdekel valami, amiért valami nem sikerült, mert ez hibára készteti a döntéseket. Amikor a dolgok sikerrel járnak, nem akar semmit különösebben megtudni – a szándéka megvalósul. A visszatérő értéknek tehát át kell adnia ezeket az információkat.Ez nem logikai érték, hanem hibakód. A speciális hibaérték 0 azt jelenti, hogy “nincs hiba”. A tartomány többi része olyan helyileg értelmezhető hibákat képvisel, amelyekkel kezelnie kell (beleértve az 1-et is, ami gyakran “meghatározatlan hibát” jelent).
Általános eset
Ebből adódik a kérdés: miért vannak logikai értékek True
és False
általánosan ábrázolva 1-rel, illetve 0-val?
Nos, a szubjektív “így jobb érzés” érv mellett itt van néhány ok (szubjektív is), amire gondolok:
-
elektromos áramkör analógia. Az áram 1 másodpercig BE és 0 másodpercig KI. Szeretem, ha (1, Igen, Igaz, Be) van együtt, és (0, Nem, Hamis, Ki), nem pedig egy másik keverék
-
a memória inicializálása. Amikor
memset(0)
egy csomó változó (legyen az ints, float, bool), azt akarom, hogy értéke megegyezzen a legkonzervatívabb feltételezésekkel. Például. az összegem eredetileg 0, az állítmány hamis stb.
Lehet, hogy mindezek az okok az oktatásomhoz kötődnek – ha megtanítottak volna 0-t társítani az kezdetén fordítva mennék.
Megjegyzések
- Valójában létezik legalább egy programozási nyelv, amely a 0-t igazként kezeli. Az unix shell.
- +1 a valódi probléma kezeléséhez: Morwenn ‘ kérdésének többsége nem ‘ t kb.
bool
. - @ dan04 Az. A teljes bejegyzés arról szól, hogy milyen okokból választják ki a szereplőgárdát
int
ésbool
között számos programozási nyelven. Az összehasonlítás és a hibagesztusok csak példák azokra a helyekre, ahol értelmes lenne más módon leadni, mint amit jelenleg ‘ csinál.
Válasz
Magas szintű szempontból három egészen különböző adattípusról beszélsz:
-
Boolean. A Boolean algebra matematikai konvenciója a 0 értéket használja a
false
és atrue
, ezért van értelme követni ezt a konvenciót. Úgy gondolom, hogy ez a módszer intuitívabban is értelmesebb. -
Az összehasonlítás eredménye. Ez három érték:
<
,=
és>
(vegye figyelembe, hogy egyik semtrue
). Számukra ésszerű -1, 0 és 1 értékeket használni (vagy általánosabban negatív, nulla és pozitív értékeket).Ha ellenőrizni szeretné az egyenlőséget a Második funkcióval rendelkezik, amely általános összehasonlítást végez, úgy gondolom, hogy ezt kifejezetten meg kell tennie olyasmi használatával, mint
strcmp(str1, str2) == 0
. Zavarba ejtőnek találom az!
használatát ebben a helyzetben, mert egy nem logikai értéket úgy kezel, mintha logikai érték lenne.Ne feledje továbbá, hogy az összehasonlítás és Az egyenlőség ne legyen ugyanaz. Például, ha az embereket születési dátum szerint rendeli meg, a
Compare(me, myTwin)
értéknek vissza kell térnie0
, deEquals(me, myTwin)
vissza kell adnia afalse
értéket. -
A függvény sikere vagy kudarca , esetleg a siker vagy kudarc részleteivel is. Ha a Windows-ról beszél, akkor ezt a típust
HRESULT
és a nem nulla érték nem feltétlenül jelenti a kudarcot. Valójában egy negatív érték kudarcot és nem negatív sikert jelez. A siker értéke nagyon gyakranS_OK = 0
, de lehet példáulS_FALSE = 1
vagy más értékek is.
A zavart a tény okozza hogy logikusan hármat a meglehetősen különböző adattípusok valójában egyetlen adattípusként (egész számként) vannak ábrázolva C-ben és néhány más nyelven, és hogy egész számot használhat egy feltételben. De nem gondolom, hogy lenne értelme újból definiálni a logikai értéket, hogy egyes nem logikai típusúakat egyszerűbbé tegyünk bizonyos körülmények között.
Fontoljon meg egy másik típust is, amelyet gyakran használnak a C állapotban: mutató . Ott természetes, hogy egy NULL
-mutatót (amelyet 0
néven képviselnek) false
. Tehát a javaslatod követése a mutatókkal való munkát is megnehezítené. (Bár személy szerint inkább a mutatók kifejezett összehasonlítását szeretném összehasonlítani a NULL
vel, ahelyett, hogy logikai értékként kezelném őket.)
Válasz
A nulla hamis lehet, mert a legtöbb CPU-nak ZERO jelzője van, amely az elágazáshoz használható. Ment egy összehasonlítási műveletet.
Lássuk, miért.
Néhány psuedocode, mivel a közönség valószínűleg nem olvassa az összeállítást
c- forrás egyszerű hurokhívások 10-szer mozognak
for (int foo =10; foo>0; foo-- ) /* down count loop is shorter */ { wibble(); }
valamilyen színlelt összeállítás ehhez
0x1000 ld a 0x0a "foo=10 0x1002 call 0x1234 "call wibble() 0x1005 dec a "foo-- 0x1006 jrnz -0x06 "jump back to 0x1000 if not zero 0x1008
c- másik egyszerű forrás a ciklus 10 alkalommal hívogat >
0x1000 ld a 0x00 "foo=0 0x1002 call 0x1234 "call wibble() 0x1005 dec a "foo-- 0x1006 cmp 0x0a "compare foo to 10 ( like a subtract but we throw the result away) 0x1008 jrns -0x08 "jump back to 0x1000 if compare was negative 0x100a
további c források
int foo=10; if ( foo ) wibble()
és az assembly
0x1000 ld a 0x10 0x1002 jz 0x3 0x1004 call 0x1234 0x1007
megtudja, milyen rövid ez?
további c forrás
int foo=10; if ( foo==0 ) wibble()
és az összeállítás (feltételezhet egy marginálisan intelligens fordítóprogramot, amely = = 0 helyettesítheti összehasonlítás nélkül )
0x1000 ld a 0x10 0x1002 jz 0x3 0x1004 call 0x1234 0x1007
Most kipróbálhatja a true = 1 konvenciót
még néhány c forrás #define TRUE 1 int foo = TRUE; if (foo == IGAZ) wibble ()
és az assembly
0x1000 ld a 0x1 0x1002 cmp a 0x01 0x1004 jz 0x3 0x1006 call 0x1234 0x1009
megnézheti, hogy a nonzero true eset milyen rövid?
Tényleg a korai CPU-k kis zászlókészletekkel voltak összekötve az akkumulátorral.
Annak ellenőrzésére, hogy az a> b vagy a = b általában összehasonlítási utasítást igényel-e.
- Hacsak B nem vagy ZERO – ebben az esetben a ZERO jelzőt egyszerű logikai NOR-ként állítják be, vagy az összes bit az Akkumulátorban.
- Vagy NEGATÍV, amelyben csak a “jel bitet” kell használni, azaz az akkumulátor legjelentősebb bitjét. ha két komplementaritmust használ. (Leginkább mi csináljuk)
Ezt megismételhetjük. Néhány régebbi CPU-n nem kellett összehasonlító utasítást használni a nullával egyenlő akkumulátor vagy a nullánál kisebb akkumulátor esetében.
Most látja, miért lehet a nulla hamis?
Felhívjuk figyelmét, hogy ez psuedo-kód, és egyetlen valós utasításkészlet sem néz ki így. Ha ismeri az összeállítást, akkor tudja, hogy itt nagyon leegyszerűsítem a dolgokat. Ha tudsz valamit a fordító tervezéséről, akkor nem kellett elolvasnod ezt a választ. Bárki, aki tud bármit a hurok kibontásáról vagy az elágazás előrejelzéséről, a haladó osztály a 203-as teremben van.
Megjegyzések
- Az Ön állítása itt nincs jól megfogalmazva, mert egy dologra
if (foo)
ésif (foo != 0)
-nek ugyanazt a kódot kell generálnia, másodszor pedig ‘ megmutatja, hogy a ‘ által használt összeállítási nyelv valójában kifejezett logikai operandusok és tesztek számukra. Példáuljz
jelentése:jump if zero
. Más szóvalif (a == 0) goto target;
. És a mennyiséget még közvetlenül nem is teszteljük; a feltételt konvertáljuk egy logikai zászlóvá, amelyet egy speciális gépi szó tárol. Ez ‘ valójában inkábbcpu.flags.zero = (a == 0); if (cpu.flags.zero) goto target;
- Nem Kaz, a régebbi CPU ‘ s nem így működött. T a jz / jnz összehasonlítási utasítás elvégzése nélkül is végrehajtható. Ami valóban az egész hozzászólásom lényege volt.
- Nem írtam ‘ semmit egy összehasonlítási utasításról.
- Tudna idézzen egy processzort, amely
jz
utasítással rendelkezik, de nincsjnz
? (vagy a feltételes utasítások bármely más aszimmetrikus halmaza)
Válasz
Nagyon sok válasz utal arra, hogy az 1 és az igaz közötti megfelelést valamilyen matematikai tulajdonság szükségessé teszi. Nem találok ilyen tulajdonságokat, és azt javasolhatom, hogy pusztán történelmi konvenció.
Ha két elemű mezőt adunk meg, két műveletünk van: összeadás és szorzás. Kétféle módon térképezhetjük fel a Boolean műveleteket ezen a mezőn :
Hagyományosan a True-t 1-vel, a False-t 0-val azonosítjuk. Az AND-t * -val, az XOR-t a + -al azonosítjuk. Így az OR telítő adalék.
Ugyanakkor ugyanolyan könnyen azonosítsuk a True-t 0-val, a False-t 1-vel. Ezután a VAGY-t * -val, az XNOR-t a + -al azonosítjuk. Így az AND telítődési kiegészítés. követte a wikipédia linkjét, megállapíthatta, hogy a logikai algebra fogalma lezárult a két elem Galois-mezőjéhez ( hu.wikipedia.org/wiki / GF% 282% 29 ). A 0 és 1 szimbólumokat hagyományosan az additív és a multiplikatív identitás jelölésére használják, mert a valós számok is olyan mezők, amelyek azonosítói a 0 és 1 számok.
Válasz
Furcsa módon a nulla nem mindig hamis.
Különösen a Unix és a Posix konvenció az, hogy a EXIT_SUCCESS
-et 0-ként definiáljuk (és EXIT_FAILURE
mint 1). Valójában ez még egy szokásos C konvenció !
Tehát a Posix héjak és a kilépés esetén (2) syscalls, 0 jelentése “sikeres”, amely intuitív módon inkább igaz, mint hamis.
Különösen az “s if
héj akarja a process return EXIT_SUCCESS
(vagyis 0), hogy az “akkor” ágát kövesse!
A sémában (de nem a Common Lisp-ben vagy a MELT ) 0 és nulla (azaz a ()
a rendszerben) igaz, mivel az egyetlen hamis érték #f
Egyetértek, nikkelek!
Válasz
C a hardverhez közeli alacsony szintű programozáshoz használatos, egy olyan területen, ahol néha át kell váltani a bitenkénti és a logikai műveletek között ugyanazon az adaton. Ha egy numerikus kifejezést konvertálni kell logikai értékre, csak a teszt elvégzése érdekében, akkor zavaros lenne. a kódot.
Ilyeneket írhat:
if (modemctrl & MCTRL_CD) { /* carrier detect is on */ }
helyett
if ((modemctrl & MCTRL_CD) != 0) { /* carrier detect is on */ }
Egy elkülönített példában nem is olyan rossz, de ennek elvégzése kellemetlen lesz.
Hasonlóképpen, társalogjon a műveletekkel. Egy logikai művelet eredményéhez hasznos, mint egy összehasonlítás, csak 0 vagy 1 előállítása: Tegyük fel, hogy néhány szó harmadik bitjét annak alapján szeretnénk beállítani, hogy modemctrl
rendelkezik a hordozó érzékelő bitjével:
flags |= ((modemctrl & MCTRL_CD) != 0) << 2;
Itt meg kell adnunk a != 0
, a kétirányú &
kifejezés eredményének csökkentésére 0
vagy 1
, de mivel az eredmény csak egy egész szám, megkíméljük attól, hogy néhány bosszantó szereplőt kelljen hozzáadnunk a logikai érték egész számgá történő további konvertálásához.
Annak ellenére, hogy a modern C id = “3b09aa4254”>
típusú, még mindig megőrzi az ilyen kód érvényességét, mind azért, mert “jó dolog, mind az ellenkező esetben kompatibilis, hatalmas visszalépés miatt.
Egy másik példa, ahol C csúszós: két logikai feltétel tesztelése négyirányú kapcsolóként:
switch (foo << 1 | bar) { /* foo and bar booleans are 0 or 1 */ case 0: /* !foo && !bar */ break; case 1: /* !foo && bar */ break; case 2: /* foo && !bar */ break; case 3: /* foo && bar */ break; }
Ezt harc nélkül nem vehette el a C programozótól!
Végül a C néha szolgál amolyan magas szintű összeszerelő nyelvként. Az összeállítási nyelvekben szintén nincsenek logikai típusaink. A logikai érték csak egy bit vagy nulla vagy nulla érték egy memóriahelyen vagy regiszterben. Az egész nullát, a logikai értéket és a null címet ugyanúgy tesztelik az összeállítási nyelv utasításkészleteiben (és talán még lebegőpontos nullát is). A C és az összeállítási nyelv közötti hasonlóság hasznos, például amikor a C-t célnyelvként használják egy másik nyelv összeállításához (méghozzá olyanhoz, amely erősen beírta a logikai értékeket!)
Válasz
A logikai vagy igazságértéknek csak 2 értéke van. Igaz és hamis.
Ezeket nem egész számként, hanem bitként (0 és 1) kell ábrázolni. ).
Bármely más egész szám 0 vagy 1 melletti mondása nem hamis, zavaros állítás. Az igazságtáblák igazságértékekkel foglalkoznak, nem egész számokkal.
A prospektív igazságértékből -1 vagy 2 megszakítaná az összes igazságtáblát és minden hozzájuk kapcsolódó logikai logikát.
- 0 ÉS -1 ==?!
- 0 VAGY 2 ==?!
A legtöbb nyelv általában boolean
típus, amely számtípusra (például egész számra) vetve hamis értéket mutat, és 0 egész értékként kell leadni.
Megjegyzések
- 0 ÉS -1 == bármilyen logikai értékre vetíti őket. ‘ ez az, amiről a kérdésem szól, miért vetik őket
TRUE
vagyFALSE
.Soha nem mondtam – talán tettem is, de nem szándékoltam – az egész számok igazak vagy hamisak voltak, azt kérdeztem, miért értékelnek akármelyiket, ha logikai értékre vetik őket.
Válasz
Végül arról beszél, hogy az alapnyelvet meg kell bontani, mert egyes API-k gagyiak. A gagyi API-k nem új keletűek, és a nyelv törésével nem lehet őket kijavítani. Matematikai tény, hogy 0 hamis és 1 igaz, és minden nyelv, amely ezt nem tartja tiszteletben, alapvetően megszakad. A háromirányú összehasonlítás hiányos, és nincs vállalkozása, amelynek eredménye implicit módon átalakul bool
vé, mivel három lehetséges eredményt ad vissza. A régi C API-k egyszerűen szörnyű hibakezeléssel rendelkeznek, és azért is vannak akadályozva, mert a C-nek nincsenek meg a szükséges nyelvi tulajdonságai ahhoz, hogy ne legyenek szörnyű felületei.
Ne feledje, hogy nem azoknál a nyelveknél mondom, amelyeknek nincs implicit egész-> logikai átalakítás.
Megjegyzések
- ” Matematikai tény, hogy a 0 hamis és az 1 igaz ” Erm.
- Tudna-e hivatkozni ” matematikai tényére, hogy a 0 hamis és 1 igaz “? Válaszod veszedelmesen hangzik, mint egy röhögés.
- ‘ nem matematikai tény, de ‘ század óta matematikai konvenció.
- A Boole algebrát egy véges mező képviseli, amelyben 0 és 1 az additonra és a szorzásra hasonlító műveletek azonosságelemei. Ezek a műveletek rendre OR vagy AND. Valójában a logikai algebra hasonlóan van írva, mint a normál algebra, ahol a szembeállítás az AND-t, a
+
szimbólum az OR-t jelöli. Tehát például aabc + a'b'c
jelentése:(a and b and c) or (a and (not b) and (not c))
.
strcmp()
nem jó példa az igaz vagy hamis, mivel 3 különböző értéket ad vissza. És meg fog lepődni, ha elkezdi használni a héjat, ahol a 0 igazat, bármi más hamisat jelent.if true ; then ... ; fi
állítást, ahol atrue
egy parancs, amely nulla értéket ad vissza, és ez azt mondja, hogyif
a...
futtatásához.bool
típusú, de az összehasonlítások / ha a feltételek stb. Bármilyen visszatérési értékkel bírhatnak.