2009-06-30 16 views
5

C++ 'ya göreceli olarak yeniyim (yaklaşık bir yıllık deneyim, açık ve kapalı). type * name'un işaretçiyi tanımlamak için sözdizimi olarak karar verdiğini merak ediyorum. Bana öyle görünüyor ki, & sembolü, kodun değişkeninin bellek adresine başvurmak için kodun her yerinde kullanıldığından, sözdiziminin type & name olması gerekir.İşaretçiyi tanımlarken neden "type & var" yerine "type * var" kullanırız?

int a = 1; 
int * b = &a; 

ben sadece görmüyorum bu bir nedeni var eminim ve ben isterdim

int a = 1; 
int & b = &a 

olacak: Yani int işaretçiler geleneksel örneğini kullanmak C++ gazilerinin bazı girişlerini duyuyorum.

sayesinde -S

+2

"C/C++" deme. C ve C++ farklı dillerdir. –

+0

Değiştirildi, ancak işaretçiler aynı şekilde çalışmıyor mu? – spencewah

+0

C referansları yok. –

cevap

7

C++ C sözdizimi benimser. (Dennis Ritchie tarafından) "The Development of the C Language" bildirildiği gibi o tip sözdizimi kullanımını takip etmeli karar verildi çünkü C tipi beyanlarında göstericiler için * kullanır. işaretçiyi doğru olmayan operatörü [*] kullanarak, işlev çağrısı, indeksi dizisi: [a bileşik tipi] 'nin her nesne için

zaten altta yatan amacı, söz için bir yol oldu. Analog mantık, isimlerin tipik olarak göründüğü ifade sözdizimini yansıtan adlar için bir bildirim sözdizimine yol açtı. Bu nedenle, bir tamsayı, bir tamsayıya bir işaretçi, bir tamsayıya işaretçiyi gösteren bir tamsayı belirtin. Bu beyanların sözdizimi, i, * pi ve ** ppi'nin hepsinin bir ifadede kullanıldığında int türünü verdiğinin gözlemini yansıtır. Burada

daha karmaşık bir örnek verilmiştir:

int *(*foo)[4][]; 

Bu beyan bir ekspresyon *(*foo)[4][0]int tip vardır ve bundan (ve bu [] tekli * daha yüksek önceliğe sahiptir) türünü deşifre anlamına gelir: foo, işaretçiden oluşan dizinin büyüklüğünün 4'lük bir dizisine bir göstericidir.

Bu sözdizimi

C++ bildirilerde & için bir kullanımı vardır unutmayın, aynı zamanda C ile uyumluluk için C++ kabul edilmiştir.

int & b = a; 

yukarıda hat türü int başka bir değişkene bir referans değişken temel özelliklerini ifade eder. Bir referans ve işaretçi arasındaki fark kabaca yalnızca referansların başlatılmış olması ve işaret ettikleri yeri değiştiremezsiniz ve sonunda her zaman otomatik olarak iptal edilirler. "* B bir int":

int x = 5, y = 10; 
int& r = x; 

int sum = r + y; // you do not need to say '*r' automatically dereferenced. 

r = y; // WRONG, 'r' can only have one thing pointing at during its life, only at its infancy ;) 
+0

Teşekkür ederim, referanslar ve işaretçilerle ilgili bazı yanlış varsayımlar yapıyordum (çoğunlukla, aynı olmadıklarında, aynı olmadıklarını). – spencewah

1

Kişisel İkinci örnek geçerli C kodu, yalnızca C++ kodu değil. Fark, birinin bir işaretçi olması, diğerinin ise bir referans olmasıdır. Sağ tarafta

'&' daima adres araçları. Bir tanımda değişkenin bir referans olduğunu belirtir. Sağ tarafta

'*' daima değerini-at-adresi anlamına gelir. Bir tanımda, değişkenin bir işaretçi olduğunu belirtir.

Referanslar ve işaretçileri benzer, ancak aynı değildir. Bu article farklılıkları giderir.

+0

İkinci bloğun * varsayılan * yasal kod olması gerektiğini sanmıyorum - bu varsayımsal bir örnektir. –

+0

Teşekkür ederim, makale (ve referanslar ve işaretçilerin anlamsızlığı) yardımcı oldu. – spencewah

+0

İkinci örnek ne C ne de C++ için geçerli değildir. Bir değere referans bağlamak için adres operatörünü kullanmazsınız. –

1

yerine olarak int* b okuma int *b olarak okumak "b int bir göstericidir". Ardından, * karşıtı olarak & var: * b bir int. *b adresinin adresi &*b veya sadece b.

-2

Bence cevap iyi olabilir "çünkü bu şekilde K & R yaptı."

Aşağı çekilme aptalları. Neden yanlış olduğumu açıkla.

K & R, işaretçiyi bildirmek için C sözdiziminin ne olduğuna karar verenler.

Bu int & x; int * x yerine; R. görsel bir düşünür ise, veri değerine giden kara delik olarak yıldız hayal etmek yardımcı olabilir

3

K & - bu şekilde çünkü dil uydurdum adamlar tarafından tanımlandı . Bu nedenle, bir işaretçi.

ve işareti deliğin karşı sonudur, bir sökülmüş yıldız işareti veya pilot kara delikten çıkan geçiş sona alır düzensiz akışı içinde yaklaşık Wobbling bir uzay gemisi gibi düşün.

C++ tarafından, ampersanın anlamını aşırı yükleyerek, bize referans vermek için çok kafa karıştırdığını hatırlıyorum. C'yi kullanan uluslararası izleyici kitlesi ve klavye kısıtlamaları ile ilgili bilinen sorunları haklı göstererek daha fazla karakter kullanmaktan kaçınmaları için çaresizce bir girişimde, büyük bir karışıklık kaynağı eklediler.

C++ 'da yardımcı olabilecek bir şey, referansları önceden hazırlanmış işaretsiz işaretçiler olarak düşünmektir. Bir argümanı ilettiğinizde & someVariable kullanmak yerine, bazı Değişkenleri tanımladığınızda, sondaki işareti kullanmışsınızdır. Sonra tekrar, bu sizi daha fazla şaşırtabilir! Benim hayvan

Bir Ben Apple'ın Objective-C örneklerinde yayımlanan görmek için mutsuz olan düzen stili int *someIntPointer yerine int* someIntPointer

IMHO olduğunu, nefret, değişkenle yıldız işareti tutarak eski moda bir C Veri tipinin üzerinde, değişkeni nasıl tanımladığınızın mekaniğini vurgulayan yaklaşım.

someIntPointer veri türü tam olarak bir tamsayıdır ve bildirim bunu yansıtmalıdır.

kişi yeteneği aynı satırda karışık işaretçileri ve değerleri bildirme iddia ederken
int* a, b; // b is a straight int, was that our intention? 

int *a, *b; // old-style C declaring two pointers 

int* a; 
int* b; // b is another pointer to an int 

, kasıtlı bir güçlüdür: Bu gibi ince hataları önlemek için, her satırda bir değişken bildirmek şartı yol vermez özelliği, ince hata ve karışıklığa yol açtığını gördüm.

+0

+1, bildirim sözdizimiyle ilgili harika yorum. –

4

Dennis Ritchie The Development of the C Language bu cevap olduğunu düşünüyorum: Böyle bir müteşekkil türdeki her nesne için

, bir yolu, altta yatan bir nesne söz zaten vardı: endeksi dizisi, çağrı işlevde, işaretçideki dolaylı işleç kullanın. Analog muhakeme, yansıtma adlarının adlarının normal olarak göründüğü ifade sözdizimine ilişkin bildirim sözdizimine yol açmıştır. Bu nedenle,

int i, *pi, **ppi; 

bir tamsayıyı, bir tamsayıya bir işaretçi, bir tamsayı için bir işaretçi için bir işaretçi bildirin. Bu bildirimlerinin sözdizimi, gözlemini, i, * pi ve ** ppi'nin bir ifadede kullanıldığında int türünü verdiğini yansıtır. Benzer şekilde ,
int f(), *f(), (*f)(); 

bir tamsayı, bir tamsayı, bir tam sayıyı döndüren bir fonksiyonu için bir işaretçi bir işaretçi dönen bir işlev dönen bir işlev bildirmek;
int *api[10], (*pai)[10]; 

tamsayılar için işaretçiler bir dizi ve tamsayı dizisi için bir işaretçi ederim. Tüm bu durumlarda, bir değişken bildirimi, türünde bildiriminin başlığında belirtilen bir ifadede kullanımını 'a benzemektedir.

Bu yüzden bu pointer kullanımını (dereferencing) ayna beyanı izin verdiğinden bir işaretçi bildirmek için type * var kullanın.

Bu yazıda

Ritchie de int array[10] aksine "NB", "B" programlama dilinin geniş bir versiyonunda, o int s bir diziyi bildirmek için, bir int için bir işaretçi bildirmek için int pointer[] kullanılan anlatıyor .

+0

Gerçekten. Ve int yapıyor, & i; yasadışı olurdu, çünkü & int vermeyeceğim. Bu yüzden, C'yi ve dolayısıyla C++ 'da kullanmıyoruz. Ne yazık ki, C++ bu simetri ile kırdı ve int &a = i; geçerli kod yaptı, hatta "& i" int :(vermez –