C neden işaretçiler için yıldız işaretini kullanır? [kapalı]


21

Sadece şimdi C'yi öğreniyorum.

Yaratıcıların, imleci ( ) işaretçisi gibi görünen* bir sembol yerine işaretçilerin sembolü olarak yıldız işaretini ( ) seçtiklerini garip buluyorum .->

Reddetme ve işlev göstergelerinin kafa karıştırıcı olabileceğini göz önünde bulundurarak, yıldız kullanmak için tarihsel, hatta pratik bir neden var mı?


10
Not ->dereference operatörü olarak C dilinde kullanılıyor - bir yapı alanları erişirken: struct_pointer->field, kısaltmasıdır (*struct_pointer).field.
amon

@amon: Yalnızca structsbana tuhaf gelen referanslar için geçerlidir . Bu bir işaretçi sembolü, değil mi? Neden <-reddetme için ( ) değil ? Gerçekten bu şekilde düşünen tek kişi ben miyim?
Noob Saibot

1
Bu sorudaki iki mükemmel cevap göz önüne alındığında, biri doğrudan dil tasarımcısı tarafından verilen bir cevap da dahil olmak üzere, yaklaşımı gerçekten “görüşe dayalı” olarak haklı göstermek zordur. Bu yüzden yeniden açılmak için aday gösterdim.
Jules

IMHO Pascal tarzı daha iyi. ^kullanılır ve döndürülmüş bir ok olarak düşünülebilir ve "işaret" olarak okunabilir, aynı ->ancak daha kısa anlamına gelir . ^integertür bildirimi için "tamsayıya işaretçi" var^anlamına gelir ve başvuru varkaldırma için " hafızaya işaret eder" anlamına gelir . Soldan sağa okurken, her zaman türden ve değişken adından önce gelen sembol konumu C'den daha mantıklıdır. Pascal aynı zamanda @adres almak için de kullanır &, çünkü @var"
varın

Yanıtlar:


59

C neden işaretçiler için yıldız işaretini kullanır?

Basitçe - çünkü B yaptı.

Bellek doğrusal bir dizi olduğundan, hücredeki değeri bu dizideki bir dizin olarak yorumlamak mümkündür ve BCPL bu amaçla bir işleç sağlar. Asıl dilde yazılmıştı rvve daha sonra !, B unary'yi kullanıyordu *. Bu nedenle, pbaşka bir hücrenin indeksini (veya adresini) veya işaretçiyi) içeren bir hücre ise, *pbir ifadedeki bir değer veya bir ödevin hedefi olarak işaret edilen hücrenin içeriğine karşılık gelir.

Gönderen C Dili Geliştirme

Bu kadar. Bu noktada, soru, "python 3 neden .bir yöntem çağırmak için kullanıyor ? Neden olmasın ->?" Şey ... çünkü Python 2 .bir yöntemi çağırmak için kullanıyor .

Nadiren bir dil hiçbir şeyden yoktur. Etkisi var ve daha önce gelen bir şeye dayanıyor.


Öyleyse, B neden !kendinden önceki BCPL gibi bir işaretçiyi serbest bırakmak için kullanılmadı ?

Eh, BCPL biraz endişeliydi. Yerine &&veya ||kullanılan BCPL logandve logor. Bunun nedeni çoğu klavyenin bulunmaması ya da tuşları olmaması ve eşit olmaması aslında kelimedi NEQV(bkz. The BCPL Referans Kılavuzu ).

B, programcıların oldukça sık yaptığı tüm bu mantıksal operatörler için uzun kelimeler kullanmak yerine, sözdizimini sıkılaştırmak için kısmen ilham almış gibi görünüyor. Ve böylece !dereference için oldu *böylece !mantıksal olumsuzlama için kullanılabilir. Unary *operatörü ile binary *operatörü (çarpma) arasında bir fark olduğuna dikkat edin .


Peki ya diğer seçenekler ->?

->Alan derefrences etrafında sözdizimsel şeker için alındı struct_pointer->fieldolduğu(*struct_pointer).field

Diğer seçenekler gibi <-belirsiz ayrıntılar oluşturabilir. Örneğin:

 foo <- bar

Okunması gereken mi:

(foo) <- (bar)

veya

(foo) < (-bar)

İkili bir operatörden ve başka bir tekli operatörden oluşan bir tekli operatör yapmak, ikinci tekli operatör başka bir ifadenin ön eki olabileceğinden sorun yaşama olasılığı oldukça yüksektir.

Ayrıca, sık sık yazılan şeyleri minimumda tutmaya çalışmak yine önemlidir. Ben ediyorum nefret yazma zorunda:

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

Bu da okumak zorlaşıyor.

Diğer karakterler mümkün olabilirdi ( Amaç C ona uygun@ olana kadar kullanılmadı ). Yine de, bu, 'C kullanır' çünkü C kullanır . B neden kullanmadı ? B, tüm karakterleri kullanmadı. Program yok ( cpp karşılaştır ) ve B'de ( sonradan cpp tarafından kullanıldığı gibi) diğer karakterler mevcuttu .*@bpp#

Eğer neden olarak bir tahminde bulunabiliyorsam - bunun nedeni tuşların nerede olduğudur. B'deki bir el kitabından :

Uygun göründüğü zaman adreslerin manipülasyonunu kolaylaştırmak için, B iki tane tek adresli adres operatörü *ve &. &adres operatörü , varsayalım &xki adresi de xöyledir. *dolaylı operatördür; *x"x'in içeriğini adres olarak kullan" anlamına gelir.

Bu &shift-7 ve *shift-8 olduğunu unutmayın. Birbirlerine yakınlıkları, programcının ne yaptıklarına dair bir ipucu olabilirdi ... ama bu sadece bir tahmin. Bir ederim Ken Thompson sormak zorunda olduğu seçim neden yapıldığıyla ilgili.


Yani, işte orada. C bu şekilde çünkü B idi. B bu şekilde çünkü BCPL'nin şeklinden değiştirmek istedi.


2
... müthiş! Bu harika bir cevap @MichaelT! Bana hem tarihi hem de pratik sebepler, hatta tam olarak anlamadığım ama araştırabileceğim şeyler gösterdiniz. Teşekkür ederim. +1
Noob Saibot

@ NooobSaibot Karakter seçimi, operatörün postpend operatörü yerine bir prepend olduğu gerçeği kadar önemli değildir. Bu, deneyimli bir C ++ programcısı için bile saçma sapan böceklere neden olabilecek birçok ekstra paren (-> sözdizimsel şeker yardımcı olsa da) gerektirir.
Trixie Wolf,

1
Ayrıca C'nin hemen hemen her Ascii noktalama karakteri için bir kullanım bulduğunu söyleyebilirsiniz. Çok fazla yedek yoktu. Sanırım @başka bir olasılık olurdu.
david.pfx

1
@ david.pfx Bu konuda genişledim - bu seçimi yapan C olmasa da ... B idi. Ve, neden olduğunu tahmin ettim (klavye yakınlığı &ve *). B de kullanmadı, #bu yüzden etrafta birkaç tane daha yedek vardı ... sonra da $.

1
@ david.pfx Bulduğum öğretici , BW Kernighan tarafından yazılmıştır. Ne yazık ki, Dennis Ritchie'ye artık soru sorulmuyor (11 Ekim'de vefat etti), Kernighan hala Princeton'daki CS Bölümünde profesör. Ken Thompson (B'nin yaratıcısı) Google'da çalışıyor ... Bazı klavyelerde de sorun yaşanmış (hepsinin erişilebilir olmadığını düşündüren C’nin harfleri) '@' Olup olmadığından emin değilim).

55

Klavyede yan yana olduklarından (daha önce hiç farketmediğim bir şey) olduğu için öğrenciden bana istendi &ve *seçildiler. Çok googling beni B ve BCPL belgelerine ve bu konuya yönlendirdi. Ancak, pek bir şey bulamadım. *B'de bir sürü neden varmış gibi görünüyordu , ama hiçbir şey bulamadım &.

Böylece @ MichaelT'in önerisini takiben Ken Thompson'a sordum:

Kimden: Ken Thompson <ken@google.com>

klavyede yakın: no.
c b'den kopyalanır, böylece & ve * aynıdır.
b * önceki dillerden * geldi - bazı
derlemeler , bcpl ve bence pl / 1.
Sanırım kullandım ve adı (ve işareti)
"adres" gibi geliyor. b,
bir teletype model 33 teletype ile çalışacak şekilde tasarlanmıştır . (5 bit baud-o kodu)
böylece sembollerin kullanımı kısıtlandı.


19
+ Thompson ile bağlantıya geçmek ve rapor etmek için +1.
stakx
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.