Bir C programlama acemi için işaretçiler açıklamak için son bir zevk oldu ve aşağıdaki zorluk tökezledi. İşaretçileri nasıl kullanacağınızı zaten biliyorsanız bir sorun gibi görünmeyebilir, ancak aşağıdaki örneğe açık bir şekilde bakmaya çalışın:
int foo = 1;
int *bar = &foo;
printf("%p\n", (void *)&foo);
printf("%i\n", *bar);
Mutlak yeni başlayanlar için çıktı şaşırtıcı olabilir. 2. satırda * bar 'ı foo olarak ilan etmişti, ama 4. satırda * bar aslında & foo yerine foo!
Diyelim ki, karışıklık * sembolünün belirsizliğinden kaynaklanıyor: 2. satırda bir işaretçi bildirmek için kullanılır. 4. satırda, işaretçinin işaret ettiği değeri alan tekli bir operatör olarak kullanılır. İki farklı şey, değil mi?
Ancak, bu "açıklama" yeni başlayanlara hiç yardımcı olmaz. İnce bir tutarsızlığa işaret ederek yeni bir konsept ortaya koyuyor. Bu öğretmenin doğru yolu olamaz.
Peki, Kernighan ve Ritchie bunu nasıl açıkladı?
Tekli operatör * dolaylı veya kayıttan çıkarma operatörüdür; bir işaretçiye uygulandığında, işaretçinin işaret ettiği nesneye erişir. [...]
İp işaretçisi bildirimi,
int *ip
bir anımsatıcı olarak tasarlanmıştır; ifadenin*ip
bir int olduğunu söylüyor . Bir değişkene ilişkin bildirimin sözdizimi, değişkenin görünebileceği ifadelerin sözdizimini taklit eder .
int *ip
" *ip
dönecektir " gibi okunmalıdır int
? Peki, bildirgeden sonraki ödev neden bu kalıba uymuyor? Bir acemi değişkeni başlatmak isterse ne olur? int *ip = 1
(okuma: bir *ip
döner int
ve int
is 1
) beklendiği gibi çalışmaz. Kavramsal model tutarlı görünmüyor. Burada bir şey mi eksik?
Edit: Buradaki cevapları özetlemeye çalıştı .
*
İşaretçiler sözdizimini açıklamak zorunda kaldığımda, her zaman bir bildirgede "bir işaretçi bildir" anlamına gelen bir belirteç olduğu, ifadelerde dereference operatörü olduğu ve bu ikisinin aynı simgeye sahip olan farklı şeyleri temsil ettiği konusunda ısrar ettim. (çarpma operatörü ile aynı - aynı sembol, farklı anlam). Kafa karıştırıcı, ama gerçek durumdan farklı bir şey daha da kötü olacak.
int* bar
de yıldızın tanımlayıcının bir parçası değil, aslında türün bir parçası olduğunu daha açık hale getirir. Tabii ki bu sizi sezgisel olmayan şeylerle farklı problemlere sokar int* a, b
.
*
bağlama bağlı olarak iki farklı anlamı olabilir. Aynı harfin, içinde olduğu gibi birçok dili konuşmayı öğrenmeyi zorlaştıran kelimeye bağlı olarak farklı telaffuz edilebilmesi gibi. Her bir kavramın / işlemin kendi sembolü olsaydı, çok daha büyük klavyelere ihtiyacımız olurdu, bu yüzden semboller bunu yapmak mantıklı olduğunda geri dönüştürülür.
int* p
) türünün bir parçası olarak vurgulayın ve öğrencinizi işaretçiler söz konusu olduğunda aynı satırda birden çok bildirim kullanmaya karşı uyarın. Öğrenci işaretçi kavramını tamamen anladığında, öğrenciye int *p
sözdiziminin eşdeğer olduğunu açıklayın ve ardından sorunu birden fazla bildirimle açıklayın.