Why does C use the asterisk for pointers?
Semplicemente - perché B ha fatto.
Because memory is a linear array, it is possible to interpret the value in a cell as an index in this array, and BCPL supplies an operator for this purpose. In the original language it was spelled rv
, and later !
, while B uses the unary *
. Thus, if p
is a cell containing the index of (or address of), or pointer to) another cell, *p
refers to the contents of the pointed-to cell, either as a value in an expression or as the target of an assignment.
Da Sviluppo della lingua C
Ecco. A questo punto, la domanda non è interessante come "perché python 3 usa .
per chiamare un metodo? Perché non ->
?" Bene ... perché Python 2 usa .
per chiamare un metodo.
Raramente esiste un linguaggio dal nulla. Ha influenze e si basa su qualcosa che è venuto prima.
Quindi, perché B non ha usato !
per derefrire un puntatore come ha fatto il suo predecessore BCPL?
Bene, BCPL era un po 'prolisso. Invece di &&
o ||
BCPL ha utilizzato logand
e logor
. Questo perché la maggior parte delle tastiere non aveva ∧
o ∨
chiavi e non era uguale alla parola NEQV
(vedi Il Manuale di riferimento BCPL ).
B sembra essere stato parzialmente ispirato a stringere la sintassi piuttosto che avere parole lunghe per tutti questi operatori logici che i programmatori facevano abbastanza frequentemente. E quindi !
per dereference è diventato *
in modo che !
possa essere utilizzato per la negazione logica. Nota c'è una differenza tra l'operatore unario *
e l'operatore binario *
(moltiplicazione).
Well, what about other options, like ->
?
Il ->
è stato preso per lo zucchero sintattico attorno al campo derefrences struct_pointer->field
che è (*struct_pointer).field
Altre opzioni come <-
potrebbero creare analisi ambigue. Ad esempio:
foo <- bar
È da leggere come:
(foo) <- (bar)
o
(foo) < (-bar)
Creare un operatore unario composto da un operatore binario e un altro operatore unario è probabile che abbia problemi poiché il secondo operatore unario potrebbe essere un prefisso per un'altra espressione.
Inoltre, è ancora importante provare a mantenere le cose digitate frequentemente al minimo. Vorrei odiare per scrivere:
int main(int argc, char->-> argv, char->-> envp)
Anche questo diventa difficile da leggere.
Potrebbero essere stati possibili altri caratteri (il @
non è stato utilizzato fino a quando Obiettivo C lo ha appropriato ). Anche se di nuovo, questo va al nucleo di 'C usa *
perché B ha fatto'. Perché B non ha utilizzato @
? Bene, B non ha usato tutti i personaggi. Non c'era nessun programma bpp
(confronta cpp ) e altri caratteri erano disponibili in B (come #
che era successivamente utilizzato da cpp).
Se posso azzardare un'ipotesi sul perché - è a causa di dove sono le chiavi. Da un manuale su B :
To facilitate manipulation of addresses when it seems advisable, B provides two unary address operators, *
and &
. &
is the address operator so &x
is the address of x
, assuming it has one. *
is the indirection operator; *x
means "use the content of x as an address."
Tieni presente che &
è shift-7 e *
è shift-8. La loro vicinanza tra loro potrebbe essere stato un suggerimento per il programmatore su ciò che fanno ... ma è solo un'ipotesi. Uno sarebbe chiedere a Ken Thompson sul perché questa scelta è stata fatta.
Quindi, ce l'hai. C è così perché B era. B è così perché voleva cambiare il modo in cui BCPL era.