Qual è stato il motivo della creazione di variabili booleane?

4

Ho scoperto che alcuni linguaggi come C non supportano le variabili booleane e i programmatori usano invece interi con valori di 0 e 1. C'è qualche ragione specifica per cui alcune lingue si sono allontanate da questa diversa da una migliore leggibilità?

    
posta Royce 04.08.2015 - 12:14
fonte

5 risposte

4

I tipi booleani integrati consentono di esprimere in modo più sintetico vero o falso (la maggior parte delle dichiarazioni tipicamente condizionate). Il bool passa direttamente alla possibilità di scrivere un condizionale semanticamente chiaro, testando e creando risultati booleani nel codice. Sarebbe più naturale e più chiaro essere in grado di utilizzare un tipo booleano autentico.

Originariamente C utilizzava valori interi (ora c'è un tipo _Bool ) con il condizione che false fosse 0 (o NULL nei test pointer) e true non fosse falso (non necessariamente solo 1). Che generalmente è tutto "bene", ma non puoi quindi testare / memorizzare espressamente / direttamente una condizione vera (solo per un non falso).

    
risposta data 04.08.2015 - 12:16
fonte
3

Sono tipi semanticamente diversi, usati per scopi diversi, quindi è molto utile che il controllo di tipo sia in grado di distinguerli. Prendi questo bug infame, ad esempio:

if (x = 1)
  ...

Nella maggior parte delle lingue, il type checker prenderà questo, perché si aspetta un booleano, ma ha un int (o unità / void nelle lingue in cui i compiti non restituiscono il loro valore). C è una delle poche lingue che consente questo particolare bug.

    
risposta data 04.08.2015 - 16:41
fonte
2

Si è dimostrato molto utile per standardizzarli.

Penseresti che 0 sia "falso" e 1 sia "vero" sia facile. Tuttavia, è anche comune vedere -1 per "true", perché nella notazione complemento a 2, è tutto 1. Viene anche utilizzata la versione più generalizzata: 0 per false e non zero per true. Tuttavia, ciò porta a situazioni interessanti in cui è possibile unire entrambi i valori bit e due valori diversi da zero e ottenere un valore falso, quindi si è verificata una costernazione.

Alla fine, la confusione dell'uso di diverse convenzioni booleane da una libreria all'altra era sufficiente. Ora abbiamo il bool per gestirlo.

(E anche in quel caso, non funziona sempre se ottieni codice da diversi compilatori e prova a collegarli!)

    
risposta data 04.08.2015 - 19:00
fonte
1

Solo per leggibilità, anche se questo non significa niente. Non ci sono tipi interi per i valori a tre stati, anche se sono molto comuni nella programmazione (ad esempio, gli operatori di confronto restituiscono uno dei 3 stati)

    
risposta data 04.08.2015 - 12:24
fonte
0

I motivi principali sono:

1. I casi d'uso per i booleani sono estremamente comuni.

Assumerò la nota convenzione che 0 significa falso e 1 significa vero ne è una prova sufficiente.

2. Vogliamo sicurezza dei tipi.

Un intero può fare tutto ciò che un booleano può fare, e molto altro ancora, quindi non è che ci mancassero delle funzionalità.

Ma se usassimo interi per rappresentare i booleani, i nostri "booleani" sarebbero in grado di fare cose che i booleani non dovrebbero essere in grado di fare (come addizione e sottrazione), e sarebbero in grado di interagire con "interi reali" in modi che non hanno alcun senso (in senso stretto, true non dovrebbe essere uguale a 1).

Di solito usiamo il termine "sicurezza del tipo" per riferirci a problemi come questo. Usare gli interi per rappresentare i booleani non è una soluzione "sicura per il tipo".

La sicurezza del tipo è generalmente considerata una buona cosa molto , specialmente in linguaggi tipizzati staticamente, in cui il compilatore controlla efficacemente il tuo programma per errori di tipo su ogni compilation. Dato che true == 42 non è un confronto valido o significativo, sarebbe bello se il compilatore semplicemente non lo permettesse e ci costringesse a risolvere quel pezzo di codice. Il "miglioramento della leggibilità" che menzioni nella tua domanda è un altro vantaggio tipico.

3. Un tipo definito dall'utente (cioè una classe o una struct) non può rappresentare correttamente un booleano, quindi dovrebbe essere un tipo primitivo o predefinito

Per molti di noi questa è la parte davvero interessante e non ovvia. Nel caso del C ++, questo problema è spiegato in modo approfondito dal Guru della settimana # 26 di Herb Sutter . Citerò il suo riassunto qui:

A typedef ... bool wouldn't allow overloading on bool.

A #define bool wouldn't allow overloading either and would wreak the usual havoc of #defines.

An enum bool would allow overloading but couldn't be automatically converted from a conditional expression (as in "b = (i == j);").

A class bool would allow overloading but wouldn't let a bool object be tested in conditions (as in "if( b )") unless it provided an automatic conversion to something like int or void*, which would wreak the usual havoc of automatic conversions.

Yes, we really did need a builtin bool! And, finally, there's one more thing (related to overloading) that we couldn't have done otherwise, either, except perhaps with [a class]: specify that conditional expressions have type bool.

Quindi il C ++ non può fare booleani non primitivi. A rischio di semplificare eccessivamente le differenze tra le lingue, se non si può fare qualcosa in C ++, ci sono buone possibilità che non si possa farlo in nessuno degli altri linguaggi OOP tradizionali. Credo che l'implementazione di C # potrebbe essere esattamente simile a quella di C ++, ma non più vicina, e Java sarebbe significativamente peggio poiché non offre intenzionalmente sovraccarico dell'operatore o conversioni implicite.

    
risposta data 08.08.2015 - 13:39
fonte

Leggi altre domande sui tag