Domanda

Mi rendo conto che puoi semplicemente #define alcuni numeri interi, ma perché C non aveva un tipo di dati booleano dedicato prima del C99?

È un evento così comune nella programmazione e nella logica, non capisco l'assenza di un tipo e di una notazione espliciti.

È stato utile?

Soluzione

Se si spende un po 'di tempo in biblioteca, non c'è bisogno di speculare. Ecco alcune dichiarazioni tratte da carta Dennis Ritchie sull'evoluzione della C . Il contesto è quello Dennis sta costruendo su di Ken Thompson lingua B, che è stato attuato sulla molto piccolo PDP-7, una macchina di parola indirizzata. A causa del crescente interesse, il gruppo ha ottenuto uno dei primi PDP-11s. Dennis scrive,

  

L'avvento del PDP-11 esposto diverse insufficienze del modello semantico di B. In primo luogo, i suoi meccanismi la gestione dei caratteri, ereditate con poche modifiche da BCPL, erano goffi: utilizzando procedure di libreria per diffondere le stringhe confezionati in singole cellule e poi imballare, o per accedere e sostituire singoli caratteri, cominciò a sentirsi a disagio, anche sciocco, su un byte-oriented macchina.

     

Il B e BCPL modello sovraccarico implicita nel trattare con puntatori: le regole linguistiche, definendo un puntatore come un indice in un array di parole, puntatori costretto a essere rappresentato come indici di parola. Ciascun riferimento puntatore generato una conversione scala runtime dal puntatore all'indirizzo byte atteso dall'hardware.

     

Per tutti questi motivi, è sembrato che un regime di battitura è reso necessario per far fronte a personaggi e di byte di indirizzamento, e preparare per l'hardware in virgola mobile a venire. Altre questioni, in particolare tipo di sicurezza e l'interfaccia di controllo, non sembravano così importante poi come sono diventati in seguito.

(enfasi mia).

La carta continua a descrivere le lotte di Dennis di inventare una nuova semantica puntatore, per rendere gli array funzionano e di venire a patti con questa idea struct diavolerie. Nozioni di sicurezza di tipo e booleani distinguendoli da numeri interi non sembravano importanti solo molto più tardi: -)

Altri suggerimenti

C è in realtà poco più di un linguaggio assembly di livello superiore. Sì, ha ottenuto strutture di controllo e quant'altro e ci ha dato anche tipi che assemblatore di certo non ha bisogno.

Ma il linguaggio è stato progettato decenni fa. E poiché ogni risultato booleano scende a singoli bit nella parola di stato del processore ovviamente era sufficiente per solo utilizzando un tipo di dati integrale per esso. E ha fatto il compilatore probabilmente un po 'meno complessa dal momento che è possibile omettere un certo tipo di controllo (in strutture di linguaggi di controllo successive necessità un valore booleano, in C hanno solo bisogno di un valore integrale di 0 o qualcos'altro) .

E 'stato comune (ed è tuttora in alcuni casi) per il trattamento di zero come falso e qualsiasi diverso da zero come vero. Questo ha dei vantaggi per la scorciatoia:., Ad esempio, invece di while (remaining != 0) si può semplicemente utilizzare while (remaining)

Alcuni linguaggi standardizzati sul vero essere -1. La ragione di questo è che in notazione complemento a due (che la maggior parte dei computer utilizzano per rappresentare numeri negativi), il bit-non di 0 è -1 (a 8-bit binari, 11111111 è decimale -1).

Nel corso del tempo si è capito che l'utilizzo di una costante compilatore definita eviterebbe un sacco di potenziale confusione. E 'stato un po' che ho fatto C ++, ma sono abbastanza sicuro che qualsiasi valore diverso da zero sarà ancora valutare "vero".

Una CPU non ha "tipo booleano", funzionano solo su byte e multipli di loro in modo un tipo booleano non aveva senso in quel momento in quanto non ha dato un vantaggio (perché usare un tipo quando si può solo controllare " è 0" o "non è nullo")

Ho il sospetto si è ritenuto sufficiente per avere un tipo integer, con 0 è falso e tutto quanto non 0 vero.

Il tipo si utilizza per memorizzare un valore booleano (di solito) incarna un trade-off tra spazio e tempo. Avrai in genere ottenere i risultati più veloci (almeno per una singola operazione) utilizzando un int (tipicamente quattro byte). D'altra parte, se si sta utilizzando molto molti, può rendere molto più senso utilizzare un byte o anche imballarli in modo che ogni valore che stai memorizzazione utilizza solo un singolo bit - ma quando / se si fa questo, la lettura o la scrittura di un singolo bit diventa sostanzialmente più costose (e utilizza il codice extra).

Dato che non c'era una risposta che è stato davvero "giusto", hanno lasciato la decisione di all'utente di effettuare in base ai requisiti del programma stavano scrivendo.

La vera domanda, allora, è il motivo per cui un tipo booleano è stata aggiunta nel C99. La mia ipotesi è che un paio di fattori sono coinvolti. In primo luogo, si sono resi conto che la leggibilità e la convenienza per il programmatore è ora di solito più importante che dare le migliori prestazioni in assoluto possibile. In secondo luogo, i compilatori ora fare un po 'di analisi molto più globale, in modo che sia almeno possibile intuire che qualcuno potrebbe scrivere un compilatore che cerca di scegliere una rappresentazione che è più appropriato per un particolare programma (anche se I don' so di qualsiasi che fa davvero).

Al vecchio C non "mancava" un tipo booleano: era solo che tutti i tipi integrali erano considerati adatti anche per svolgere il doppio compito, memorizzando booleani.Vedo due ragioni principali per questo:

  • I processori con indirizzamento a bit non erano affatto comuni (e non lo sono tuttora), quindi il compilatore non sarebbe realmente in grado di utilizzare un tipo "vero booleano" per risparmiare spazio: il booleano sarebbe comunque grande almeno quanto UN char comunque (se speravi di accedervi in ​​modo efficiente).

  • Tipi più stretti di int sono ampliati a int comunque nelle espressioni, quindi gli operatori booleani continuerebbero a funzionare int operandi.

... quindi sembra proprio che non ci fosse un caso abbastanza convincente secondo cui un tipo booleano dedicato avrebbe effettivamente portato vantaggi pratici.

Ricorda che il linguaggio C ha una serie di operatori che producono risultati booleani (definiti come 0 o 1) - !, &&, ||, !=, ==, <, <=, > E >= - quindi è solo un tipo booleano dedicato che non è presente.

ragioni storiche, probabilmente:

CPL, che è stato fortemente influenzato dal ALGOL, molto probabilmente aveva un tipo booleano, ma il mio google-fu non era sufficiente per trovare un punto di riferimento per questo. Ma CPL era troppo ambizioso per il suo tempo, con un conseguente versione ridotta chiamato BCPL, che ha avuto il beneficio che si potrebbe effettivamente implementarlo su hardware a disposizione.

BCPL aveva solo un unico tipo - la 'parola' - che è stato interpretato come falso in contesti booleani se 0 e come vero se ~0 (cioè il complemento di 0, che rappresenterebbe il -1 valore se interpretato come firmato complemento a due numero intero). L'interpretazione di qualsiasi altro valore era a carico di attuazione.

Dopo l'ancora senza tipo successore B, C reintrodotto un sistema di tipo, ma era ancora fortemente influenzato dalla natura senza tipo dei suoi predecessori.

L'aggiunta di un tipo separato "booleano", che non è compatibile con gli interi avrebbero reso il compilatore più complicato che semplicemente utilizzando numeri interi per lo scopo. Avere un tipo booleano separato che è compatibile con gli interi rende necessario specificare le possibili conseguenze di memorizzare un valore diverso da 0 o 1 in un oggetto booleano o eseguire calcoli numerici su un booleano oggetto la cui rappresentazione contiene né la sequenza di bit associato "0" o "1". Dato:

someBool = intFunction();
someInt = someBool;

richiedendo che someInt deve ricevere il valore 1 se intFunction restituisce alcun valore diverso da zero sarebbe generalmente rendere quanto sopra più costoso di

someChar = intFunction();
someInt = someChar;

Nel caso in cui sarebbero tenuti gli ex semantica, che potrebbero essere realizzati senza l'uso di un tipo booleano, via:

someChar = !!intFunction();
someInt = someChar;

Dato che tutto ciò che può essere fatto utilizzando tipi booleani può essere fatto anche senza di loro, e in molti casi il codice che utilizza i tipi di carattere può essere più efficiente rispetto ai tipi booleani, io suggerirei che non c'è mai stato (e ancora non è ) una reale necessità per loro.

Perché non hanno messo uno in. Scusate se questo suona snippish, ma in fondo non è stato definito come tale.

Ricordate la maggior parte delle persone #define TRUE e FALSE.

Si può dire bool è standard - ma ovviamente non era standard prima di C99 - che è stato fatto 10 anni fa;) Hanno aggiunto poi quando divenne evidente un elemento mancante

.

Perché nessuno può prevedere tutto, compreso mancante tipo di dati in un linguaggio di programmazione.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top