it-swarm.asia

İşaretçiler için güzel bir açıklama nedir?

Kendi çalışmalarınızda (kendi başınıza veya bir sınıf için) nihayet, gerçekten işaretçileri anladığınız zaman bir "ah ha" anınız oldu mu? Yeni başlayan programcılar için özellikle etkili görünen bir açıklamanız var mı?

Örneğin, yeni başlayanlar C'de işaretçilerle ilk karşılaştıklarında, sadece &s ve *s derlenene kadar (kendim bir kez yaptığım gibi). Belki de işaretçileri sizin ya da öğrenciniz için “tık” haline getiren bir resim ya da gerçekten iyi motive olmuş bir örnektir. Bu neydi ve işe yaramıyor gibi görünmeden önce ne denediniz? Herhangi bir konu önkoşulu var mıydı (ör. Yapılar veya diziler)?

Başka bir deyişle, &s ve *, bunları ne zaman güvenle kullanabilirsiniz? Sözdizimini ve terminolojiyi veya kullanım örneklerini öğrenmek yeterli değildir, bir noktada fikrin içselleştirilmesi gerekir.


Güncelleme: Şimdiye kadarki cevapları çok seviyorum; lütfen gelmeye devam et. Burada çok büyük perspektifler var, ama birçoğunun kendimiz için iyi açıklamalar/sloganlar olduğunu düşünüyorum after kavramı içselleştirdik. Size şafak vakti geldiğinde ayrıntılı bağlamları ve koşulları arıyorum.

Örneğin:

C'de sadece işaretçileri sözdizimsel olarak anladım. İki arkadaşımın başka bir arkadaşa işaretçileri açıkladığını duydum, bu da neden bir işaretçi ile struct geçtiğini sordu. İlk arkadaş, nasıl referans alınması ve değiştirilmesi gerektiğinden bahsetti, ancak bana vurduğu diğer arkadaştan kısa bir yorum yapıldı: "Aynı zamanda daha verimli." 16 bayt yerine 4 bayt geçmek, ihtiyacım olan son kavramsal değişiklikti.

72
Macneil

Izgara Olarak Bellek Diyagramı

Genellikle yaptığım şey, adresleri oluşturabildiğim, farklı bellek boşluklarını vurgulayabildiğim ve hücre değerlerine yazabildiğim (ya da dahası, ikili sunumları) ve bellekteki işaretçileri değerlerine bağlayabilmem için belleği bir "ızgara" olarak temsil etmektir. işaret etmek. (Ve yine de bunun bir basitleştirme olduğunu belirtin).

Genellikle öğrencilerimin çoğu için bir "ohhhh" anıdır.

Sembol Dönüşümü

Daha sonra nasıl kullanılacağını ve & * 'yı unutmayı bırakmalarına gelince, bu çok basit: matematik veya fizik hesaplamaları ile aynı şekilde sunun. Km cinsinden bir mesafeyi saat cinsinden bölerseniz, km/s cinsinden bir hız elde edersiniz. İçinde ne olmalı dışarıda. Basit.

kurtarmaya yazdır

Bunlarla açıkladığınızı görsel olarak temsil eden birkaç temel örnek yapmak onları anladıklarını düşündükleri şeyde rahatlatacak veya "ah, bunu anlamıyorum" deme fırsatı verecektir.

Kapsamlı Olun

Basit türler için işaretçileri kapsar ve adresleme ile veri türünün boyutu arasındaki farkı, sonra yapıları, sonra dizileri ve birden çok düzeyi anladıklarından emin olun.

Ardından işaretçi aritmetiğini başlatın.


Zeyilname: Özyineleme

Genellikle özyinelemeyi görsel bir sunum kullanarak benzer şekilde açıklarım. Tek bir karakter yazan önceden hazırlanmış bir işlevi kullanarak alfabeyi yazdırmasını sağlayın ve ardından yalnızca iki satırı değiştirerek ters sırada yazdırmasını isteyin.

Genellikle "ne ...?" ve sayısal değerleri yazdırmak ve adımları girintilemek için printf'nize başka bir parametre eklediğinizde rahat bir nefes alır.


Alternatifleri: Play-Doh Modeli ve Su Bardağı

Aslında bir üniversitede bazı öğrencilere play-doh macunu kullanarak işaretçileri ve bellek erişimlerini açıklayan bir video gösterdim. Programlamayı kavramakla ilgilenen çok genç öğrenciler (ama genellikle onları çok erken işaretçiler kullanarak bir dile yönlendirmeyeceğim) dışında, bu tekniği kendim hiç kullanmadım, ancak inanılmaz derecede akıllı ve iyi yapıldı. Temel olarak, bellek alanlarını temsil eden diğer daha büyük play-doh toplarına bağlayabileceğiniz ve bunları (bağlantılı veri yapısında olduğu gibi) bağlamak veya birleştirmek için (bitişik olarak olduğu gibi) birleştirebileceğiniz küçük play-doh topları kullanmak bellek alanı). İşaretlenen bellek alanları için farklı renkler kullanmak ve işaretçiler de yardımcı olur. Ama yine de Grid olarak Bellek olayının daha iyi çalıştığını düşünüyorum, çünkü göstergenin "harita/ızgarada" olduğu gibi gerçekten "adresleme" meselesi olduğunu açıkça gösterebilirsiniz. Oysa Play-doh modu onları hala bir şeylerin gerçekten hafızada birbirine "dokunduğunu" düşünerek karıştırıyor.

Su Bardağı şey doğrudan bir meslektaş tarafından da kullanıldı, ancak onunla gelip gelmediğini bilmiyorum. Bu ilginç bir yaklaşımdı, ancak birçok öğrencinin açıklamadan şaşkın kaldığını gördüm. DevSolo'nun Kahve Fincanı tekniği . Ancak öğrencilerin kapları, veri yapılarını, işaretçileri ve dizileri karıştırmasını sağladığınız için aslında yanıltıcı bir durum olduğunu düşünüyorum. Sanırım başlangıçta dizileri açıklamak ilginç bir yaklaşım olabilir, ama buna çok uzun sürmezdim.

25
haylem

Bir zamanlar söylediğimden daha bilge biri:

Rahibe Wu Jincang, Altıncı Patriach Huineng'e "Uzun yıllardır Mahaparinirvana sutrasını inceledim, ancak tam olarak anlamadığım birçok alan var. Lütfen beni aydınlatın."

Patrik, "Okuma yazma bilmiyorum. Lütfen bana karakterleri okuyun ve belki de anlamını açıklayabileceğim."

Rahibe, "Karakterleri bile tanıyamazsın. O zaman anlamını nasıl anlayabilirsin?" Dedi.

"Gerçeğin kelimelerle ilgisi yoktur. Gerçeğin gökyüzündeki parlak aya benzetilebilir. Kelimeler, bu durumda, bir parmağa benzetilebilir. Parmak ayın konumuna işaret edebilir. Ancak, parmak Aya bakmak için parmağın ötesine bakmak gerekiyor, değil mi? "

80
Frank Shearar

Diyagramların çok yardımcı olduğunu gördüm. Misal:

pointer diagram


Bu tür bir diyagram, işaretçilerin kendi değişkenleri olduğunu görmeme yardımcı oldu, ancak başka bir nesnenin, yani dizi veya dizenin konumu olan bir değer içeriyordu. Ayrıca, kalemle yapıldığında, programımı kağıt üzerinde veya bir kara tahta/beyaz tahtada izlemek için kullanabilirim.

46
Michael K

İşaretçileri ilk kez "öğrendiğimde" ona doğru bir şekilde ittim. Üniversitem, müfredatı Java'nın etrafında ortalamak için kaydolmadan çok önce karar vermişti, bu yüzden Veri Yapıları profesörüm C hakkında bir ders verdiğinde ve bir şeylere giriyormuş gibi hissettiğim işaretçilerle bir XOR Listesi uygulamasını istedi. yol kafamın üstünde.

Tanımı anladım:

İşaretçi, bir değişkenin adresini içeren bir değişkendir

Ama hala kavramın büyük bir bölümünü anlamadım. Geriye dönüp baktığımda, üç şeye odaklandığını düşünüyorum:

  1. Tam olarak is bir bellek yeri nedir? (O zaman bir Bilgisayar Organizasyonu dersi almadım)

  2. Garip sözdizimi (Yani um ... neden tam olarak "int * ip" gibi tanımlanmış ama sonradan "ip" olarak adlandırıyorum?)

  3. Sadece değişkeni kullanmak yerine bir değişkenin adresini saklamak tam olarak ne kadar faydalıdır?

K&R kitabını satın alıp işaretçiler için gerçekten kavradığım her problemi tamamlayana kadar değildi. Bilgisayar Organizasyonu sınıfını uzun süredir tamamlamamın yanı sıra (C öğrenmeden önce gerekli olduğunu düşünüyorum), bir kısmı da işaretçilerin işlevler, diziler, yapılar için kullanılabileceğini fark ettim ... yararlı şeyler yapmak ve sadece sıradan değişkenlerin adresleri için depolama olarak değil.

Ama benim “aha” anım, K&R'nin basit bir işaretçi tanımlamanın garip sözdizimini açıklamasının yoluydu. Kitap boyunca notlar aldım (anladığım kadar ilerlemek için kitabın işaret ettiği noktaları kendi sözlerime yeniden yazdığım) ve bununla ilgili olan şu:

İşaretçi, bir değişkene adres içeren bir değişkendir. Bir işaretçi tanımlanır ve '*' operatörü ile işaret ettiği bellek konumunda depolanan değeri verir; ifade anımsatıcıdır.

Ex.: 
   int a;      /* Variable 'a' is an integer */

   int *ip;   /* Variable ip is a pointer and dereferencing it gives an integer.
                 In other words, the expression *ip is an int, so ip is a pointer
                 to an int */

Kafamda kökleşmiş bir şey olana kadar işaretçilerin daha gelişmiş kavramlarını tam olarak kavrayamadığımı hep hissettim. Bu atamadan sonra (bu arada çok iyi yapmadım;)) neden "* ip" i tanımladığımdan hemen sonra "* ip" bulunmadığı için beni sürekli rahatsız etmişti. Bunun üstesinden gelmek, işlev işaretçileri gibi işaretçileri içeren daha gelişmiş kavramlar ve bunun gibi daha karmaşık tanımlar için gereklidir:

char (*(x())[])()

Sonuç olarak, işaretçiler kavramının şunları gerektirdiğini düşünüyorum:

  1. Bilgisayarda belleğin nasıl düzenlendiğine (ve belleğin ne olduğuna) ilişkin temel bir anlayış.

  2. İşaretçilerin ne kadar güçlü olabileceği hakkında bilgi (gerçek dünya kullanımı, sadece öğrenme uğruna öğrendikleri başka bir soyut kavram değil).

  3. Halk dilinde "bir işaretçinin tanımı" olarak bilinen hiyerogliflerin deşifresinin yapılması

Sonuç olarak, işaretçiler hakkında bilgi edinirken en az 3 "aha" anı olması gerektiğini düşünüyorum. Hâlâ bir öğrenciyim, bu yüzden hala (nispeten) kavramı öğrenen birisinin bakış açısını takdir edeceğinizi düşündüm.

32
Kevin

İşaretçi, masaüstünüzdeki uygulama kısayollarına benzer. Kısayolu silin ve hedef hala var. Kısayolu başlatın, hedef başlar.

Her zaman masaüstümde bir txt dosyası ve dosyaya iki kısayol oluşturarak bunun çalışmasını açıklarım. Kısayolları kopyalayıp sildikten sonra, insanların 'referanslar'ın arkasındaki fikri anladıklarını görebilirsiniz.

Grup, kısayolların arkasındaki temel öğeyi anladıktan sonra, istediğiniz şekilde işaretçileri açıklamaya başlayabilirsiniz. Muhtemelen kolayca anlayacaklar.

19
Barfieldmv

8-10 yıl önce bir kolejde bir "C" dersi verdim. Bu her zaman keşfedilecek eğlenceli bir konuydu. En iyi işe yarayan şey budur ve bu bir iş arkadaşını birkaç kez tartıştıktan sonra bir kahve fincanı ve elinizi kullanmaktı.

Bir kahve fincanı benzetmesini (veya diziler için bunların sırasını) bir değişken olarak kullandım (bir şey tutabilir). Daha sonra bir şey tutabilen ya da işaret parmağımı bir kahve kupasını "gösterecek" şekilde uzatarak elimi kullandım.

Yakın bir el boştu, kafamı işaret eden bir parmak (sahte bir silah gibi) sarkan bir işaretçiydi.

Sonra birkaç gösteri ve hata ayıklayıcı gezileri ile, çoğu ile tıkladı.

14
DevSolo

"İşaretçileri nasıl kavradınız" sorusunu duyduğumda gerçekten endişeleniyorum. Her zaman kavramın inanılmaz derecede basit olduğunu ve programcılara büyük güç sağlayan dillerin mantıklı bir evrimi olduğunu düşündüm.

Beni endişelendiren şey işaretçiler kavramını anlamakta hiç zorlanmadığım. Burada tekrar "nihayet ne zaman anladın" diye düşündüğünüzde, düşünmeye başlarsınız:

Aslında anladım mı? Belki hiç yapmadım?

Belki de kavramın zor görünmesinin nedeni, henüz onlarla karşılaşmamış herkese işaretçilerin çok zor olduğunu ve burada öğrenebileceğiniz yüz yol olduğunu söylemeye devam etmemizdir.

Sadece bu fikri dışarı atmak, elbette kişisel olarak iyi bir diyagramı seviyorum ve Steve Gibson her zaman her şeyi açıklamak için harika bir iş çıkarır !

10
Marcus Whybrow

C'deki işaretçilerle hiçbir zaman çok fazla sorun yaşamadım, ancak bunun nedeni öncelikle montajcıyı öğrenmek zorunda olduğumdur. Aslında artık adresleri kendim yönetmemek bir rahatlama oldu. Bu yüzden belki de (bunun öğrettiğiniz bir şey olduğunu varsayarak) cevabı öğrencilere çalışmak için taklit edilmiş bir Meclis dili vermektir. Onlar will "Merhaba dünya" dan daha sofistike bir şey yazma sürecinde anlıyorlar.

7
Larry Coleman

İşaretçi, değeri başka bir değişkenin bellek adresi olan bir değişkendir.

7
kirk.burleson

İşaretçileri gerçekten nasıl öğrendim? Basit bir derleyici birinci sınıf yazarak üniversite yıl.

İşaretçileri layman terimleriyle nasıl açıklayabilirim? Dizin kartlarında saklanan bir kütüphane kataloğunun (tarihli?) Benzetmesini seviyorum. Her kart ("işaretçi") bir kitabın ("veri") bulunduğu yerle ilgili bilgiler içerir, ancak aslında kitabın kendisini içermez. Kartı değiştirirseniz ("işaretçi aritmetiği") tek yaptığı, işaret ettiği kitabı değiştirmek ve kitabın kendisi üzerinde hiçbir etkisi yoktur - sadece adresi bozmamaya dikkat edin, yoksa var olmayan bir kitaba işaret edebilirsiniz. hatta yanlış kütüphaneyi bile. Ancak, karttaki "adresi" takip edip kitaplığın uygun kısmına giderseniz ("işaretçiyi serbest bırak"), kitabın kendisini görebilir/değiştirebilirsiniz.

6

Sorunun gözden geçirilmiş gereksinimini desteklemek için düzenlendi

"Post-pointer" anlayış yolum (doğru hatırlıyorsam) böyle gitti. Ben hala bir BBC Micro ile mucking beri montaj programlama bazı basit bir deneyim oldu bu yüzden bir grup kutu olarak bellek kavramı vardı (bunun için aşağıya bakınız). Bu, dizilerin kullanımı ile güçlendirildi. Ancak, C dünyasına giriyordum ve iplerle uğraşmak zorunda kaldım ve bu işaretçiler anlamına geliyordu. BASIC'te bu önemsizdi, montajcıda onlarla çalışmak zorunda kalmadım ve şimdi klasik C'de tüm işaretçiler ve şeyler. Ah, ama şu şekilde (boş sonlandırılmış) dizelerle dizilere geri dönebilirim:

char s[] = "Hello, world!";
printf("%s",s);

Her şey yolunda ve iyi, bu sadece bir dizi karakter (benim küçük dünyamda karakter başına 8 bit) sonunda nerede olduğunu göstermek için sıfır karakterle. Printf sadece bu diziyi alır ve üzerine basar. Ama bu dizeyi bir işleve geçirmek istersem ne olur?

void print_str(char* p) {
  printf("%s",p);
}

Kılavuz ne diyor, ama hepsi ne * ile ilgili? Hmm, char * "bir char işaretçisi" anlamına gelir. Tamam ... beni kaybetti. Sonra karakter * s'yi p [0] 'a eşdeğer hale getirdi. Tamam, bunu kullanabilirim, ama hala işaretçilerin ne olduğunu dalmadım. Yani, bunlardan biriyle bazı verileri nasıl ayarlayabilirim? Tekrar el kitabına ...

char* p = "Hello World!";

Yukarıdakileri yazarken kendime "karaktere bir işaretçi bildirin ve bu karakter dizisine eşit olarak ayarlayın" diyorum. Her nasılsa bu işaretçi bir dizi ihtiyacını ortadan kaldırır. Sanırım derleyici bir değişiklik için benim için bir şeyler yapıyor. Peki bu işaretçiyle diziyi nasıl değiştirebilirim? Dizi sürümünü kullanabileceğimi biliyorum

 s[2] = 'L'; 

ama "pointer speak" den eşdeğer nedir? Yine bu el kitabında ...

*(p+2) = 'L';

Sanırım * basitçe "bellek adresinin içeriği" ve (p+2) dır-dir s[2]. Yani p işaretçisi ... sadece ... bir ... adres ... bong!

Aydınlanma sesi var. Aniden işaretçiler dalladım (uzun zaman önceydi, biz eski zamanlayıcılar daha sonraya kadar "grok" olmadı). Sadece dolaylıydı.


Orijinal:

Tamam, benim 2c değer:

Hafızanın bir grup kutu olduğunu hayal edin. Her kutunun yanında bir numara vardır (adres). Her kutuda bir sayı (içerik) bulunur. Bu kutularla 2 şekilde çalışabilirsiniz: Değişkenler (N kutusunun içeriğini istiyorum), işaretçiler (N (kutusundaki) kutusunun içeriğini istiyorum ). İşaretçiler basitçe dolaylıdır.

Ve bilmeniz gereken her şeyi kapsayan büyük cevap için - bunu okuyun .

5
Gary Rowe

İşaretçilerin öğreneceği birisinin normal değişkenlerin ne olduğunu ve C'de nasıl çalıştığını bildiğini varsayacağım. Şimdi, bazı nitelikleri olan işaretçileri tanımlamaya çalışalım.

  • Aynı zamanda değişkenlerdir, fakat farklı niteliktedirler. Değişken alanında iki katman olduğunu varsayın. Farklı tipteki normal değişkenler üst tabakada ve alt tabakadaki işaretçilerdedir. Bu rakam gibi

    alt text

  • 'İşaretçi' adından da anlaşılacağı gibi, işaretçiler bir şeye POINT olabilir. Parmağımızın bir nesneye işaret edebileceği gibi. İşaret ettikleri şeyler neler? Bunlar normal değişkenlerdir. Kısacası, "İşaretçiler normal değişkenleri gösterir".

  • Normal değişkenler gibi, işaretçiler de int, char veya float gibi aynı sayıda tiptedir. Ve belirli bir türdeki bir işaretçi yalnızca aynı tür değişkenleri gösterebilir.
  • İşaretçi bir değişkeni ve daha sonra aynı işaretçi başka bir değişkeni gösterebilir. Sadece tür aynı olmalıdır. Bu nedenle, bir işaretçinin bazı değişkenlerle ilişkisi kalıcı değildir ve değiştirilebilir.
  • Peki, bir işaretçi nasıl ilan edilir? Neredeyse normal değişkenler gibi. Addan önce yıldız işareti (*). Sevmek-

    int *pointer;
    
  • Peki, bir işaretçi bir değişkenle nasıl ilişkilendirilir? Kullanmak & operatörü bu ifadeye benzer değişkenden önce-

    pointer = &variable;
    
  • Bir değişkene işaret ederek işaretçi nasıl kullanılır? Bu, adın önünde yıldız işareti (*). Sonra şimdi işaret ettiği değişkenin yerine kullanılabilir.

    *pointer = var1 + var2;
    

    onun yerine

    variable = var1 + var2;
    
  • Şimdi, bazı kodlarla işaretçilerle oynayın. Şimdi sadece işaretçilerin bu özelliklerine alışın. Bu noktaya kadar, işaretçilerin ne yaptığından bahsediyoruz. Bir kez bunu yaptıktan sonra, işaretçilerin bazı değişkenlere nasıl işaret ettiğini ve normal aritmetik işlemler uygulanırsa nasıl tepki verdiklerini incelemeye başlayın. Sonra işaretçiler ve diziler ve işaretçilerden işaretçiler arasındaki ilişkiyi araştırın.

İşaretçiler hakkında önereceğim tek şey bu.

5
Gulshan

Küçük tahta bloklar al.

bir ucuna metal kancalar, diğer ucuna metal gözler ekleyin.

artık oynayabileceğiniz şeyler için bağlantılı bir liste yapabilirsiniz.

Bu fiziksel pervane ile açıklamayı deneyin. Sık sık birinci sınıf öğrencilerine işaretçiler öğretirken bunu olmasını isterdim.

Küçük metal kanca işaretçi, şeyin işaret ettiği tahta bloğudur.

Ben bloklarla oynadıktan sonra almak için kimse DEFY.

4
Tim Williscroft

Tüm tüyleri çıkardığımda ve işaretçiyi büyülü bir varlıktan (11 yıl önce uzun zaman önce) başka bir değişken olarak ele almaya başladığımda hayatımı kolaylaştırdım .. sadece 3 şeyi biliyorum:

  1. İşaretçi, başka bir değişkenin (veya yalnızca herhangi bir adresin) adresini saklayan bir değişkendir.
  2. *, işaretçi değişkeninde saklanan bellek konumundaki değeri almak için kullanılır.
  3. & operatörü bir bellek konumunun adresini verir.

Gerisi sözdizimsel şeker ve sağduyu. Sadece asmak için işaretçiler kullanarak bazı basit C programları (bağlantılı bir liste kitaplığı uygulamak gibi) yazın.

4
Sridhar Iyer

Gerçekten yığılmış açıklama oldu:

Arazi parçaları üzerine inşa edilmiş farklı evleri olan bir şehir ızgarasını düşünün. Elinde bir parça kağıt var. Yazdığınız kağıt üzerinde:


David'in evi,

112 Yani sokak.


Kağıt parçası (pointer değişkeni) David'in evine puan adresini içerir. Bir arkadaşınıza David'in havalı evine bakmasını söylemek istediğinizde, kağıt pice'i eve referans olarak kullanmak, postadaki gerçek iki katlı binayı göndermekten çok daha kolaydır.

Gerçek işaretçilerde olduğu gibi, kağıt parçanızdaki adresi takip ettiğinizde biraz sorun yaşayabilirsiniz. David taşınmış olabilir ve oraya vardığınızda yerde büyük bir delik bulursunuz. Bu durumda, David taşındığında veya en azından yenisiyle değiştirdiğinde kağıt üzerindeki adresi silmek daha iyi olurdu. Ayrıca adrese gidip arkadaşınızın David'in oturma odası olduğunu düşündüğünüzü girdiğinizi de görebilirsiniz, ancak bu sefer tam bir yabancı yüzme havuzuna girersiniz. Başka biri, adresinizdeki alanı tamamen farklı bir şey için kullandı.

2
Per Wiklander
  1. İşaretçi, bir dizinin bir diziye genelleştirilmesi olarak düşünülebilir.
    • Büyük bir dizinin daha küçük, çakışmayan, değişken boyutlu dizilere bölünebileceğini düşünün. Şimdi, bu daha küçük diziler genellikle dizi olarak düşündüğümüz şeydir. Daha büyük olanı bilgisayarın tüm bellek alanıdır. Daha küçük dizileri kesme işlemine bellek ayırma denir.
  2. Bazı işaretçilerle birbirine bağlanan yapılar kümesi yönlendirilmiş grafik . Olarak düşünülebilir.
    • Her tepe noktası, bir değer tutabilecek bir değişkendir.
    • Bazı değişkenler işaretçilerdir ve her işaretçi başka bir şeye tam olarak giden bir Kenar içerebilir.
    • İşaretçi olmayan değişkenlerin giden kenarı olmayacaktır. İstenilen sayıda Edge alabilirler.
2
rwong

Eğer işaretçileri açıklamak istiyorsanız, önce hafızayı açıklamanız gerekir. Bunu genellikle satır ve sütun içeren grafik kağıdı/kare kağıt kullanarak yaparım. "Öğrenci" hafızayı anlarsa, bir adresin ne olduğunu anlayabilir. Eğer adresin varsa işaretçiler var.

Bu soyutlama ile oynayabilirsiniz. Örneğin. bir karenin adresini (numarasını) başka bir kareye yazın. Şimdi işaretçi karesinden hedef kareye bir ok çizin. Şimdi işaretçiyi üzerine yazın (örn. Artırın) ve oku ayarlayın. Başka bir kareye bir adres yazın ve öğrencinin oku çizmesine izin verin ...

Sonraki adım: Belirli karelere (işaretçi gibi) bir ad verin. Şimdi kayıt silme işlemini açıklayabilirsiniz. Bu kadar.

2
EricSchaefer

İşaretçilerim-aha-anımın etrafındaki koşulları tam olarak hatırlayamıyorum, ancak c-tarzı bir dizi hakkındaki anlayışımdaki belleği geriye dönük olarak yeniden ekledim. (yani arr[3]*(arr+3) ile aynıdır)

Bazı nedenlerden dolayı, işaretçi durumuna geldiğimde işaretçileri diziler olarak görmek son derece yararlı buluyorum.

2
Zaz

Temelde @Gary Rowe doğru modeli tanıttı. Bellek, adresleri (sayıları) olan bir kutu kümesi olarak. Her kutu bir değer (sayı) depolar.

İşaretçi fikri, bir kutudaki değeri başka bir kutunun adresi olarak yorumlamaktır. Bu değer başvur için belirli bir kutuya kullanılır, bu nedenle başvur olarak adlandırılır. Böylece dereferencing atıfta bulunulan kutuyu açma işlemidir.

v bir değişken (kutu) ise, ifade

  • vv değeri anlamına gelir, yani bana kutuda ne olduğunu ver
  • *v, v değerinin dereference'ı ifade eder, yani bana v değerinin atıfta bulunduğu kutuda ne olduğunu ver
  • &v referans v anlamına gelir, yani bana kutudaki adresi ver

Ben tamamen farklı bir şey işaretçiler tanıtmak amacı sunucu olmadığını düşünüyorum. Çocukken kavramak benim için zor bir kavramdı. Her zaman hiç anlamadığım, çok fazla özel karakter gerektiren karanlık bir sihir gibi görünüyordu. İlk anladığımda, işaretçi aritmetiği olmayan bir dilde çift dolaylı kullanarak küçük bir oyun yazdığım zamandı. Bu beni aydınlattı.

İşaretçiler bir yorum meselesidir. Bence bunu açıklamak işleri kolaylaştırıyor. İşaretçi aritmetikleri, 10 değişkenlik bir belleğe sahip basit bir örnek gösterildiğinde son derece basit ve sezgisel işlemlerdir.

2
back2dos

Belki de sadece benim, ama benzetmelerle iyi çalışıyorum. Diyelim ki bir arkadaşınız (işlev/sınıf) "Foo", başka birisine (farklı işlev/sınıf), "Bar" a sahip olmak isteyen bir sebepten dolayı sizinle iletişime geçin. "Foo" sizi "Bar" ı görmeye götürebilir, ama bu uygun değil, bütün bu varlıkları (örnekleri) hareket ettiriyor. Ancak, "Foo" telefon numaranızı (işaretçi) "Bar" gönderebilir. Bu şekilde, nerede olursanız olun, "Foo" sizi bulmak zorunda kalmadan sizinle nasıl iletişim kuracağını bilir.

Ve diyelim ki "Bar" sizinle tanışmak isteyen bir "Tan" tanıştı. Ancak telefon numaranızı koruyorsunuz ve herkesin sahip olmasını istemiyorsunuz, "Baz" daha sonra çağrıyı size iletebilen (başka bir işaretçi) "Bar" ı (işaretçi olarak telefon) arayabilir. Ve böylece ve benzeri "Baz" ın arkadaş ve arkadaşlarının zinciri.

2
Hugo

Montaj dili ve/veya bilgisayar mimarisini incelediyseniz işaretçiler yol daha anlamlı olur. Bir C sınıfı öğretirsem, bellek modelini ve işlemcinin gerçekte yürüttüğü talimatları açıklamak için birkaç hafta mimariyle başlayacağımı düşünüyorum.

2
Barry Brown

Benim "aha!" an bu öğreticide geldi:

C'deki İşaretçiler ve Diziler Üzerine Bir Eğitim

Kesin olmak gerekirse, bu bölümde geldi: Bölüm 3: İşaretçiler ve Dizeler

Daha kesin olmak gerekirse, bu cümle ile geldi:

Puts () öğesine iletilen parametre bir işaretçidir, bir işaretçinin değeridir (C'deki tüm parametreler değere göre geçtiği için) ve işaretçinin değeri işaret ettiği adres veya basitçe bir adresdir .

Bunu okuduğumda, bulutlar ayrıldı ve melekler trompet hayranlarını havaya uçurdu.

Gördüğünüz gibi, bundan önce okuduğum her C öğreticisi veya kitabı, C'nin değere veya referansa göre hain bir yalandan geçebileceğini iddia etmişti. Gerçek şu ki, C her zaman değere göre geçer, ancak bazen iletilen değer bir adres olur. Yöntem içinde, bu adresin bir kopyası, tıpkı aktarılan bir int'in kopyası gibi yapılır. Bir kopyası değil işaretçinin işaret ettiği değer. Böylece yöntemin içindeki işaretçiyi kullanarak orijinal değere erişebilir ve değeri değiştirebilirsiniz.

Asla bir C programcısı olmadım, ancak bir .NET programcısı oldum ve nesneler ve nesne başvuruları aynı şekilde çalışıyor; nesneye yapılan başvuru değere göre iletilir (ve böylece kopyalanır), ancak nesnenin kendisi kopyalanmaz. Bunu anlamayan birçok programcı üzerinde çalıştım çünkü daha önce işaretçiler öğrenmediler.

2
Kyralessa

İşaretçi, yararlı bir şeyin nerede olduğunu söyleyen yapışkan bir nottur. Bir şeyin yerini içerir ve size o şeyin ne kadar büyük olduğunu söyler (yine de C cinsinden). Yani çift işaretçi, "Buzdolabında altı paket var" yazan yapışkan bir not gibidir. Aslında Coke veya Budweiser olup olmadığını anlamak için altı paketi almalısınız.

1
philosodad

http://cslibrary.stanford.edu/

Bu site, işaretçiler ve bellek yönetimi öğrenmek için harika eğiticilere sahiptir.

Size sitede verilen işaretçiler temelleri, işaretçiler ve bellek üzerinden yürümek öneririz. İşaretçi kavramlarını daha da güçlendirmek için bağlantıda verilen bağlantılı listelere de bakabilirsiniz.

1
deovrat singh

Kod verildiğinde:

int v=42; // basit bir değişkeni bildirme ve başlatma

int *p = &v; // v değişkenine p noktası oluşturma

Yukarıdaki kod hakkında aşağıdaki söylenebilir:

int * p // "int işaretçi p" ... int türündeki değişkene bir işaretçi bu şekilde bildirilir

*p // "p ile işaret edildi" ... p'nin işaret ettiği veri, v ile aynı.

&v // "v değişkeninin adresi" ... bu, p için değişmez değeri temsil eder

1
zener

İşaretçileri açıklamanın anahtarı, açıkladığınız insanların zaten bellek kavramını anladığından emin olmaktır. Gerçekten düşük seviyeyi anlamışlarsa güzel olurken, belleğin büyük bir dizi olarak var olduğuna inanıyor ve dizideki herhangi bir konuma dizin konumuna göre erişebileceğinizi anlamak yeterli.

Bir sonraki adım, tüm belleği kopyalamak yerine indeks konumunu geçirme kavramına sahip olmak çoğu insan için mantıklıdır. Ve bu, çoğu insanın işaretçilerin neden faydalı olduğunu anlamasına izin vermek için yeterlidir.

işaretçileri anlamanın son adımı, tüm verilerin depolandığı dizin konumunu saklama yöntemi için bir bellek dizini konumunu parametre olarak nasıl aktarabileceğinizi açıklamaktır. Bunun bazı insanların başa çıkması için çok ileri bir adım olabileceğini buldum.

Birisi bu temel adımları kavradığında, gerçek veri nesnesini bulmak için adreslere kaç kez bakmanız gerektiğini takip ettiğiniz sürece, işaretçileri süresiz olarak zincirleyebildiğinizi kavramak için düz ileridir.

Birisi işaretçileri kavradığında, hızlı bir şekilde kavramaları gereken bir sonraki şey, yığın belleği ve yığın belleği arasındaki fark ve yöntemin dışına iletildiğinde belleği biriktirmek için neden tehlikeli olduğudur.

1
Michael Shaw

İşin püf noktası, bir şeyin yeri ve şeyin kendisinin aynı olmadığını, tıpkı bir borunun resmi gibi bir boru değildir olduğunu açıklamaktır. Bir şeyi taşıdığınızda, konumu değişir. Konumu kalır ve başka bir şey oraya konabilir.

1
sal

Dizileri en azından yüzeysel bir düzeyde zaten bildiğinizi varsayarsak, işaretçiler için en iyi açıklamam şudur:

Bilgisayarınızdaki tüm belleği (veya daha kesin olmasını istiyorsanız işleminizdeki adres alanını) dev bir bayt dizisi olarak hayal edin. İşaretçi bu dizinin yalnızca bir dizinidir. Bu nedenle işaretçiler sadece özel bir tamsayıdır.

C ve Assembly kodlayıcılarının işaretçileri tamsayı olarak ele alarak yapabileceği tüm püf noktaları ve ayrımın sadece Meclis dil düzeyinde nasıl bir kongre olduğunu öğrenmek, bu anlayışın benim için sağlamlaşmasına yardımcı oldu.

0
dsimcha

Üniversitedeyken profesörüm, bir noktayı kendi başına ayrı bir değişken olarak gösteren bir bellek konumuna (bir dizi olarak temsil edilir) bir okla (gerçekten bir dizi gibi temsil edilir) tasvir eden gerçekten düzgün PowerPoint slaytları vardı ve Bağlantılı Listeler yaparken, adım adım, ok değiştiğinde, işaretçi kayıttan kaldırıldığında vb ..., bir kaç dakika içinde anlayamadığımız bir yol yoktu. Kavramın kendisi gerçekten kolaydır, ancak doğru yapmak veya pratik programlarda uygulamak daha fazla uygulama gerektirir.

0
chiurox

Bunu yapmadan önce, programlamada "her şeyin bellek kullanır" ve bellekte (statik) değişken tahsisini açıklarım. Ayrıca bir bellek adresinin ne olduğunu ve bellek alanı, bellek adresi ve değişkenler arasındaki ilişkiyi açıklayacağım.

Son olarak, tamsayı veri türü ve değişkenleri, dize veri türü ve değişkenleri olduğunu açıklarım ... vb. boş olarak adlandırılır.

Ve son olarak, işaretçilerin kullanımı yoluyla dinamik olarak tahsis edilen değişkenler.

0
umlcat

Tamamen kütüphanede bulunan birkaç programlama/bilgisayarla ilgili kitaptan biri olduğu için okuduğum "C yapbozları" veya benzeri bir kitabı hatırlıyorum, C anlayışım ilkeldi. Size bir C ekspresyonu attı ve gittikçe daha karmaşık hale gelmesini istedi.

0
peterchen