Mengapa C menggunakan tanda bintang untuk pointer? [Tutup]

21

Saya baru saja belajar tentang C.

Saya merasa aneh bahwa pencipta memilih asterisk ( *) sebagai simbol untuk pointer daripada simbol yang benar-benar terlihat seperti pointer ( ->).

Mempertimbangkan bagaimana membingungkan dereferencing dan fungsi pointer dapat, adakah alasan historis, atau bahkan praktis, untuk menggunakan tanda bintang?

Noob Saibot
sumber
10
Perhatikan bahwa ->sedang digunakan dalam bahasa C sebagai operator dereference - saat mengakses bidang dalam struct:, struct_pointer->fieldyang merupakan kependekan dari (*struct_pointer).field.
amon
@amon: Ini hanya berlaku structsuntuk dereferencing, yang terasa aneh bagi saya. Ini simbol penunjuk, bukan? Kenapa tidak ( <-) untuk dereferencing? Apakah saya benar-benar satu-satunya yang berpikir seperti ini?
Noob Saibot
1
Mengingat dua jawaban yang sangat baik dalam pertanyaan ini, termasuk satu dengan jawaban langsung dari perancang bahasa, sulit untuk benar-benar membenarkan penutupan sebagai "berbasis opini". Karena itu saya telah dinominasikan untuk membuka kembali.
Jules
Gaya IMHO Pascal lebih baik. ^digunakan dan dapat dianggap sebagai panah yang diputar dan dibaca sebagai "arahkan ke", artinya sama ->tetapi lebih pendek. ^integerberarti "pointer to integer" untuk deklarasi tipe, dan var^berarti "memori varmenunjuk ke" untuk dereferencing. Posisi simbol lebih logis daripada C saat membaca dari kiri ke kanan, yang selalu menempatkan setelah tipe dan sebelum nama variabel. Pascal juga menggunakan @untuk mengambil alamat, yang lebih baik daripada &, karena @varadalah "alamat di mana var berada"
phuclv

Jawaban:

59

Mengapa C menggunakan tanda bintang untuk pointer?

Sederhananya - karena B melakukannya.

Karena memori adalah array linier, dimungkinkan untuk menafsirkan nilai dalam sel sebagai indeks dalam array ini, dan BCPL memasok operator untuk tujuan ini. Dalam bahasa aslinya itu dieja rv, dan kemudian !, sementara B menggunakan unary *. Jadi, jika pada sel yang berisi indeks (atau alamat), atau penunjuk ke) sel lain, *pmengacu pada konten sel yang ditunjuk, baik sebagai nilai dalam ekspresi atau sebagai target penugasan.

Dari Perkembangan Bahasa C

Itu dia. Pada titik ini, pertanyaannya sama tidak menariknya dengan "mengapa python 3 digunakan .untuk memanggil metode? Mengapa tidak ->?" Yah ... karena Python 2 digunakan .untuk memanggil metode.

Jarang bahasa ada dari ketiadaan. Itu memiliki pengaruh dan didasarkan pada sesuatu yang datang sebelumnya.


Jadi, mengapa B tidak digunakan !untuk derefrencing pointer seperti BCPL pendahulunya lakukan?

Nah, BCPL agak bertele-tele. Alih-alih &&atau ||BCPL digunakan loganddan logor. Ini karena sebagian besar keyboard tidak memiliki atau kunci dan tidak sama sebenarnya adalah kata NEQV(lihat Manual Referensi BCPL ).

B tampaknya sebagian terinspirasi untuk memperketat sintaks daripada memiliki kata-kata panjang untuk semua operator logis ini yang sering dilakukan oleh programmer. Dan dengan demikian !untuk dereferensi menjadi *sehingga !dapat digunakan untuk negasi logis. Perhatikan ada perbedaan antara *operator unary dan *operator biner (multiplikasi).


Nah, bagaimana dengan pilihan lain , seperti ->?

Itu ->diambil untuk gula sintaksis sekitar derefrences lapangan struct_pointer->fieldyang(*struct_pointer).field

Opsi lain seperti <-bisa membuat parsing yang ambigu. Sebagai contoh:

 foo <- bar

Apakah itu dibaca sebagai:

(foo) <- (bar)

atau

(foo) < (-bar)

Membuat operator unary yang terdiri dari operator biner dan operator unary lain sangat mungkin mengalami masalah karena operator unary kedua mungkin merupakan awalan untuk ekspresi lain.

Lebih jauh lagi, penting untuk mencoba menjaga hal-hal yang diketik sesering mungkin. Aku benci harus menulis:

int main(int argc, char->-> argv, char->-> envp)

Ini juga menjadi sulit dibaca.

Karakter lain mungkin telah dimungkinkan (yang @tidak digunakan sampai Objective C menggunakannya ). Meskipun sekali lagi, ini pergi ke inti 'C menggunakan *karena B melakukannya'. Kenapa B tidak digunakan @? Yah, B tidak menggunakan semua karakter. Tidak ada bppprogram (bandingkan cpp ) dan karakter lain tersedia dalam B (seperti #yang kemudian digunakan oleh cpp).

Jika saya dapat menebak mengapa - ini karena di mana kuncinya. Dari manual di B :

Untuk memfasilitasi manipulasi alamat ketika tampaknya disarankan, B menyediakan dua operator alamat unary, *dan &. &adalah operator alamat begitu &xjuga alamat x, dengan anggapan ia memiliki satu. *adalah operator tidak langsung; *xberarti "menggunakan konten x sebagai alamat."

Perhatikan bahwa &shift-7 dan *shift-8. Kedekatan mereka satu sama lain mungkin merupakan petunjuk bagi programmer tentang apa yang mereka lakukan ... tapi itu hanya dugaan. Orang harus bertanya kepada Ken Thompson tentang mengapa pilihan itu dibuat.


Jadi, begitulah. C seperti itu karena B dulu. B seperti itu karena ingin berubah dari bagaimana BCPL itu.

Komunitas
sumber
2
... luar biasa! Ini jawaban yang bagus, @MichaelT! Anda menunjukkan kepada saya alasan historis dan praktis, dan bahkan hal-hal yang saya tidak mengerti tetapi bisa melihatnya. Terima kasih. +1
Noob Saibot
@NoobSaibot Pilihan karakter tidak sebanyak kesepakatan karena fakta bahwa operatornya adalah operator yang lebih baik daripada operator pascabayar. Ini membutuhkan banyak parens tambahan (meskipun -> sintaksis gula membantu) yang dapat menyebabkan bug yang konyol namun menjengkelkan bahkan untuk seorang programmer C ++ yang berpengalaman.
Trixie Wolf
1
Anda mungkin juga menyebutkan bahwa C menemukan penggunaan untuk hampir setiap karakter tanda baca Ascii. Tidak banyak suku cadang. Saya kira @akan ada kemungkinan lain.
david.pfx
1
@ david.pfx Saya telah memperluas itu - meskipun bukan C yang membuat pilihan itu ... itu B. Dan, well, saya menebak mengapa (kedekatan keyboard &dan *). B juga tidak menggunakan #jadi ada beberapa suku cadang di sekitar itu ... ada juga $.
1
@ david.pfx Tutorial B yang saya temukan ditulis oleh BW Kernighan. Sayangnya, Dennis Ritchie tidak lagi dapat ditanyai (dia meninggal pada bulan Oktober '11) sementara Kernighan tampaknya masih seorang profesor di Departemen CS di Princeton. Ken Thompson (pencipta B lainnya) bekerja di Google ... Mungkin juga ada masalah dengan beberapa keyboard (ditunjukkan oleh trigraph untuk C untuk apa yang kita anggap sebagai kunci umum) menunjukkan bahwa tidak semuanya tersedia ( Saya tidak yakin apakah '@' adalah).
55

Saya ditanya oleh seorang siswa apakah &dan *dipilih karena mereka bersebelahan di papan ketik (sesuatu yang belum pernah saya perhatikan sebelumnya). Banyak googling membawa saya ke dokumentasi B dan BCPL, dan utas ini. Namun, saya tidak dapat menemukan banyak sama sekali. Sepertinya ada banyak alasan untuk *di B, tetapi saya tidak dapat menemukan apa pun untuk &.

Jadi mengikuti saran @ MichaelT, saya bertanya pada Ken Thompson:

Dari: Ken Thompson <[email protected]>

dekat pada keyboard: no.
c disalin dari b jadi & dan * sama di sana.
b mendapat * dari bahasa sebelumnya - beberapa perakitan,
bcpl dan saya pikir pl / 1.
saya pikir saya menggunakan & karena nama (ampersand)
terdengar seperti "alamat." b dirancang untuk dijalankan dengan
model teletype 33 teletype. (5 bit kode baud-o)
sehingga penggunaan simbol dibatasi.

chmullig
sumber
19
+1 untuk menghubungi Ken Thompson dan melaporkan kembali ke sini.
stakx