Bir değişken ve bir bellek konumu arasındaki fark nedir? [kapalı]


38

Son zamanlarda işaretçileri, flashcards olarak görsel bir şekilde açıklamaya çalışıyorum.

Soru 001: Bu, bilgisayar belleğindeki bir yerin çizimidir. Adresinin doğru olduğu doğru 0x23452mu? Neden?

görüntü tanımını buraya girin

Cevap: Evet, çünkü 0x23452bilgisayarın bu konumu nerede bulabileceğini açıklar.


Soru 002: Karakterin bhafıza konumunda saklandığı doğru 0x23452mu? Neden?

görüntü tanımını buraya girin

Cevap: Hayır, çünkü karakter aaslında içinde saklanır.


Soru 003: Bir işaretleyicinin bellek konumuna kaydedildiği doğru 0x23452mu? Neden?

görüntü tanımını buraya girin

Cevap: Evet, çünkü hafıza yerinin adresi içinde 0x34501saklanır.


Soru 004: Bir işaretleyicinin bellek konumuna kaydedildiği doğru 0x23452mu? Neden?

görüntü tanımını buraya girin

Cevap: Evet, çünkü başka bir hafıza konumunun adresi içinde saklanır.


Şimdi beni endişelendiren kısım için. Bir yazılım mühendisi bana işaretçileri şöyle açıkladı:

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

Hepinize gösterdiğim dört karttan yola çıkarak, işaretçileri biraz farklı şekilde tanımlardım:

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

Bir değişkenin bellek konumu ile aynı şey olduğunu söylemek güvenli midir?

Eğer değilse, o zaman kim haklı? Bir değişken ve bir bellek konumu arasındaki fark nedir?


37
Orada bir örtük varsayım kutusu altında onaltılık sayı bir bellek adresi olduğunu senin niyet bilecek o resimleri okuma herkesin burada var, o da a, 0x23453. nilvb onların içindeki şeyler değerlerdir. Bu size açık gelebilir, ancak bu alanların nasıl tanımlandığını görmeden bu sorulara kesin cevaplar vermekten rahat edemem. aİkinci resimde bir karakter, bir dize (eğer farklıysa) veya bir değişkenin ismi olup olmadığını bilmenin hiçbir yolu yoktur . Bir dize ise, o zaman nilda bir dizedir? Ya da "boş" bir değer?
ilkkachu

39
Soru 1 kötü bir soru. Bu, diğer sorulara cevap vermeden önce okuyuculara söylemeniz gereken bir şey. Bir soru yerine, okuyucuya verilen bilgiler olmalıdır: "Aşağıdaki sorularda, kutular hafıza yerleridir ve altındaki altıgen sayıları adresleridir".
26

15
Soru 3 bağlamında verilen cevap vermek mümkün değildir. Bayt düzeyinde, bellekte depolanan değerin uygulama düzeyinde nasıl yorumlandığını / kullanıldığını söylemenin bir yolu yoktur.
26

6
Kayda değer: Buraya yazdığınız her şey C veya C ++ için doğrudur, ancak temelde açıkça işaretçi başvuru / başvuru kaldırma özelliği olan herhangi bir dil için yanlıştır. Değişkenlerin tüm metaforu, değerlerin bir araya getirildiği yuvalar (Python veya Java veya C # veya Ruby veya JavaScript veya JavaScript gibi) için atama işleminin kopyalanmadan bir nesneye sadece bir değişken noktası gösterdiği ve nesneye yapılan mutasyonlar, kendisine işaret eden tüm değişkenler tarafından görülebilir. Python'un belgeleri, değişkenlerin alternatif metaforunu bu nedenle nesnelerde asılı isim etiketleri olarak kullanır.
Mark Amery

19
BTW ve bunu zaten anladıysanız beni affedin, ama bu bir karışıklık noktası olabilir gibi görünüyor - bu "0x23452" notasyonu sadece onaltılık bir sayıdaki bir sayıyı ifade etmenin bir yoludur ve sadece kolaylık sağlamak için yapılır. Ancak bu sadece bir sayıdır - 0x öneki hiçbir şekilde bir işaretçi olduğunu göstermez, bellekte kayıtlı olan kelimenin tam anlamıyla anlamsız bir sayıdır (bellek konumlarını düz ondalık tamsayılarla etiketleyebilirsiniz). Anlamı (yani, sayının nasıl yorumlanması gerektiği) dilden gelir - değişkenin türü ve kullanım şekli.
Filip Milovanović

Yanıtlar:


69

Değişken, bir algoritmanın amacına giden mantıksal bir yapıdır, oysa bir bellek konumu bir bilgisayarın çalışmasını tanımlayan fiziksel bir yapıdır. Genel olarak konuşursak, bir programı yürütmek için bir değişkenin mantıksal kavramı ile bilgisayarın depolanması arasında (derleyici oluşturulmuş) haritalama vardır.

(Assembly dilinde bile, algoritmada ve kasıtta olacak (mantıksal) değişkenler kavramına ve (fiziksel) bellek konumlarına, montajda daha fazla karışmış olmalarına rağmen.)

Değişken yüksek (er) seviye bir kavramdır. Bir değişken ya bilinmeyen (matematikte olduğu gibi, ya da programlama ödevinde) ya da bir değerle ikame edilebilecek bir yer tutucuyu temsil eder (programlamada olduğu gibi: parametreler).

Bir hafıza yeri düşük (er) seviye bir konsepttir. Bir bellek konumu, bazen bir değişkenin değerini kaydetmek için bir değeri saklamak için kullanılabilir. Bununla birlikte, bir CPU kaydı bazı değişkenlerin değerini saklamanın başka bir yoludur. CPU kayıtları da düşük (er) seviye depolama yerleridir, ancak adresleri olmadığı için hafıza yerleri değildirler, sadece isimleri.

Bir anlamda, bir değişken programın amacını ifade etmek için bir soyutlama mekanizmasıdır, oysa bir bellek konumu depolama ve geri alma sağlayan işlem ortamının fiziksel bir varlığıdır.

Soru 003: Bir işaretçinin 0x23452 bellek konumuna kaydedildiği doğru mu? Neden?

Kesin olarak söyleyemeyiz. Bir adres olarak çalışacak bir değer olduğu için, o adres olduğu anlamına gelmez, bunun yerine 144466 tamsayı olabilir. Değerlerin yorumlanmasına sadece sayısal olarak nasıl göründüklerine dayanarak varsayımlarda bulunamayız.

Soru 004: Bir işaretçinin 0x23452 bellek konumuna kaydedildiği doğru mu? Neden?

Bu gerçekten garip bir soru. Ancak, kutulara dayanarak bazı varsayımlar bekliyorlar, ancak adreslerin her kutu için 1 arttığını not edelim. Herhangi bir modern bilgisayarda, bu her kutunun bir bayt bayt adreslenebilirliğine sahip olabileceği anlamına gelir, on yıllardır norm olmuştur. Bununla birlikte, bir bayt sadece 8 bittir ve 0 ila 255 arasında değişebilir (işaretsiz değerler için); Ancak bu adreslerden birinde depolanan çok daha büyük bir değer gösterirler, bu yüzden çok şüpheli. (Bu, bir kelime adresli makine olsaydı işe yarayabilirdi, ama söylemedi, ve bugün birkaç makine olsa da, bazı eğitim makineleri öyle.)

Hepinize gösterdiğim dört karttan yola çıkarak, işaretçileri biraz farklı şekilde tanımlardım:

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

Bu düşüncenin doğru olduğu durumlar varken, burada metaforları karıştırıyorsunuz. Bir değişken kavramı, algoritmaya ve amacına gider - tüm değişkenlerin bellek konumlarına sahip olduğunu varsaymaya gerek yoktur. Bazı değişkenler (özellikle diziler) bellek konumlarına sahiptir, çünkü bellek yerleri adreslemeyi destekler (oysa CPU kayıtları sadece indekslenmemiş olabilir).

Yürütme için değişkenler ve ifadeler ile işlemci belleği konumları ve işlemci talimat dizileri arasında mantıksal bir haritalama vardır. Değeri asla değişmeyen (örneğin bir sabit) bir değişken, mutlaka bir hafıza konumu gerektirmez, çünkü değer istendiğinde yeniden üretilebilir (örneğin, derleyici tarafından üretilen kod dizileri için gerektiği gibi).


4
Ve hatta 8 bit baytlar hala evrensel değildir.
Deduplicator

14
@JimmyJames forDerleyici döngüyü tamamen açmaya karar verdiğinde bir döngü indeksi durumunu düşünün . Üretilen çıktı kodunun hiçbir yerinde (montaj veya makine kodu veya bayt kodu olsun) döngü sayacının kaydedildiği bir bellek konumu yoktur. Ancak bu hala bir değişkendir.
dmckee

4
@JimmyJames, Kontrol edilmemiş döngü göstergesinde, o zaman evet, kodunuz gerçekte sayacın değerini kullanıyorsa, o zaman bir yere yüklenmelidir , ancak (a) bu yer bir kayıt olabilir ve (b) Prensipte , kontrolsüz döngünün her yinelemesinde neden aynı konum olması gerektiğinin bir nedeni yoktur .
Solomon Yavaş

3
Eğer döngü sabit uzunluklu diziyi sourceeşit uzunluklu diziye kopyalamak gibi bir şey yapıyorsa, destkodlanmış bir döngü , bileşik sayının for (int i=0; i<8; ++i) dest[i] = source[i];tekrarı için eşdeğer bir şeye kadar derlenebilir dest++ = source++;. Döngü sayacı ile kendisi hiçbir yerde kanıt (hiçbir kayıt bile), ve sadece tekrar sayısı döngü döngüsünü hakkında size söyler.
dmckee

2
Farklılığı, bir kısmı, semantikleri yakından bellekten numaralı konumlardan oluşan bir makinenin bir soyutlamasına dayanan C gibi dillerle karıştırılıyor.
Michael Kay,

20

Bir değişkenin bellek konumu ile aynı şey olduğunu söylemek güvenli midir?

Hayır. Değişken ve bellek konumu iki farklı soyutlama seviyesindeki iki soyutlamadır. Değişkenler ve işaretçiler kod / dil düzeyinde daha yüksek seviye kavramıdır, bellek konumu ise makine düzeyinde daha düşük seviye bir kavramdır. Bir kod çalıştırılabilir bir dosyada derlendikten sonra, artık hiçbir değişken yoktur. Hafıza konumu ve değişkenler hakkında bu şekilde konuşmaya çalışmak kategorik bir hatadır.

Bellek kullanılarak bir değişken uygulanabilir, ancak her zaman bir derleyici olarak bir hesaplamayı optimize edemez ve bir değişkene ilişkin tüm hesaplamaları tamamen kayıt defterlerinde yapabilir veya tek bir değişkeni birden fazla bellek konumuna koyabilir veya tek bir bellek kullanabilir. çoklu değişkenler için konum.

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

Bu flashcard dizisi çok karışık, sadece doğru değiller, hatta yanlış da değiller.


1
Once a code had been compiled into an executable, there's no longer any variables.Bu tartışmaya kesinlikle katılmıyorum. Bildiğiniz gibi değişkeninizin (yani bu isimle) artık var olmadığı doğru, ancak ifadeniz derlenmiş yürütülebilir dosyanın sadece bellek adreslerini kullandığını gösteriyor gibi görünüyor. Bu doğru değil. Derlenmiş, ancak yürütülmeyen çalıştırılabilir çalıştırıcınızın, yürütürken hangi bellek adreslerini kullanacağına dair hiçbir fikri yoktur. Değişken kavramı (yani çalışma zamanında atanacak olan hafıza adreslerine yeniden kullanılabilir referans) derlenen yürütülebilir dosyanın içinde hala mevcuttur.
Flater

2
Veya derleyici, değişkeni çeşitli şekillerde tamamen uzaklaştırabilir. Bir şeyi önceden hesaplamak, gereksiz değişkenleri budamak. Değişken bir sabitse, derleyici sabitleri kullanan CPU komutlarını kullanarak sona erebilir ve o zaman artık değişkenin hiçbir yerde olmadığı sayılmayacağını savunuyorum.
kutschkem

16

Değişkenler dil yapılarıdır . Bir kapsam içinde bulunan bir isme sahiptirler, kodun diğer bölümleri tarafından belirtilebilirler . Mantıksal bir varlıktırlar. Derleyici, bu dil yapısını dilediği gibi uygulamakta özgürdür, gözlemlenebilir davranış dil standardı tarafından öngörüldüğü sürece. Dolayısıyla, derleyicinin gerekmediğini ispatlayabiliyorsa, değişkenin hiçbir yerde depolanması gerekmez.

Hafıza yerleri bir donanım konseptidir . Sanal / fiziksel bellekteki bir yeri ifade ediyorlar. Her bellek konumunda tam olarak bir fiziksel adres ve onu işlemek için kullanılabilecek herhangi bir miktarda sanal adres bulunur. Ancak her zaman her hafıza konumunda tam olarak bir bayt vardır.

İşaretçiler özel bir tür değerlerdir . Bir şey söylemek bir işaretçidir, bir şey türünden bahsetmeye benzer double. Bu değer için kaç bitin kullanıldığını ve bu bitlerin nasıl yorumlandığını gösterir, ancak bu değerin bir değişkende saklandığı ve bu değerin bellekte saklandığı anlamına gelmez.


C'de bir örnek vermek gerekirse: Bir 2D dizilim olduğunda int foo[6][7];ve onunla bir öğeye eriştiğimde foo[1][2], o zaman foodiziyi tutan bir değişkendir. Tüm foobu bağlamda kullanıldığında, dizideki ilk elemanı bir işaretçi haline getirilir. Bu işaretçi herhangi bir değişkende saklanmaz, ya da bellekte saklanmaz, değeri sadece CPU'nun bir kaydı içinde oluşturulur, kullanılır ve sonra unutulur. Aynı şekilde, ifade foo[1]de, bir değişkende olmayan, bellekte depolanmayan, kullanılan ve unutulan CPU'da hesaplanan, bu bağlamda başka bir göstergeye dönüştürülür. Üç kavram değişkeni , hafıza yeri ve işaretçi gerçekten üç farklı kavramdır.


BTW, gerçekten "her bir bellek konumunda her zaman tam olarak bir bayt vardır" demiştim. Bu, elli yıl önce hesaplanan taş çağında durum böyle değildi, ancak bugün kullanılan tüm donanımlar için de geçerlidir. Ne zaman bir bayttan daha büyük olan bellekte bir değer saklarsanız, aslında birkaç ardışık bellek konumu kullanıyorsunuzdur. Yani (büyük endian bayt sırasına göre) 0x01234567 sayısı bellekte saklanır.

+------+------+------+------+
| 0x01 | 0x23 | 0x45 | 0x67 |
+------+------+------+------+
    ^      ^      ^      ^
    |      |      |      |
 0x4242 0x4243 0x4244 0x4245

(X86 mimarisi gibi küçük endian makineleri, baytları ters sırada saklar.) Bu, işaretçiler için de geçerlidir: Her biri kendi bellek adresine sahip, arka arkaya sekiz baytlık bir 64 bitlik makinedeki bir işaretçi saklanır. Bir bellek hücresine bakamaz ve şöyle diyemezsiniz: "Ah, bu bir işaretçi!" Hafızaya baktığınızda sadece baytları görürsünüz .


Bir grup ardışık hafıza yeri grubunun ne zaman başladığını ve bittiğini bilgisayar nasıl biliyor?
progner

6
@ progner Öyle değil. Bu yorumladığı o alır talimatlara göre bellekte bayt. Bu talimatlar ayrıca bir dizi bayttan başka hiçbir şeyde saklanmaz. İşlemciye, talimatı içeren bir bayt, karakter içeren bir bayt ve bazı kayan nokta bitlerini içeren bir bayt arasındaki tek fark, bu baytı kullanması için nasıl talimat verildiğidir. Program sayacı işaret ettiği için bayt alınırsa, komut olarak kullanılır. Bir komut, onu bir kayan noktaya kaydettirdiğini söylediğinden getirilirse, kayan nokta verileri olarak kullanılır.
cmaster

7
@progner Bu von-Neuman mimarisinin en önemli yeniliğiydi: Talimatları ve verileri aynı hafızaya koymak, talimatların daha sonra daha fazla talimat olarak uygulanacak verileri değiştirmesine izin vermek. Bu, kendi kendini değiştiren kodlara izin verdi, ancak aynı zamanda bir sistemin çekirdeğinin bir programı belleğe yüklemesini ve ardından CPU'ya bu programı çalıştırmasını söyle. Von Neuman'dan önce, Zuse makineleri gibi bilgisayarlar, talimatlarını, çalıştıkları verilerden tamamen bağımsız bir kanal aracılığıyla alırlardı.
cmaster

5

Asıl sorunuza odaklanmama izin verin - "kim haklı?" bu iki ifadeyi karşılaştırırken:

  • İşaretçi, değeri başka bir değişkenin hafıza adresi olan bir değişkendir.
  • İşaretçi, değeri başka bir bellek konumunun bellek adresi olan bir bellek konumudur.

Bunun cevabı hiçbiri değil . İlki, "başka bir değişkenin hafıza adresi" nden bahsediyor, ancak değişkenlerin illa ki cevapları olması gerekmiyor, diğer cevaplar da daha önce açıklandığı gibi. İkincisi "bir işaretçi bir bellek konumudur" diyor, ancak işaretçi kelimenin tam anlamıyla sadece bir değişkende saklanan bir sayıdır, ancak önceden olduğu gibi, bir değişken mutlaka bir bellek adresine sahip değildir.

Daha kesin ifadeler için bazı örnekler:

  • "İşaretçi, bir hafıza konumunun hafıza adresini gösteren bir sayıdır", veya

  • "İşaretçi değişkeni, değeri bir bellek konumunun bellek adresi olan bir değişkendir."

  • "Bir hafıza adresi, bir hafıza yerinin hafıza adresini temsil eden bir işaretçi tutabilir."

Bazen "pointer" teriminin, karışıklığa yol açmadığı sürece tamam olan "pointer değişkeni" için bir kısayol olarak kullanıldığını unutmayın.


Bir imleç kendini gösterebileceği için "diğerini" "a" olarak değiştirebilirsiniz.
Pieter B,

@PieterB: nitty, nitty ;-) bu gerçekten daha net yapıp yapmadığından emin değilim, çünkü yalnızca orijinal ifadeleri gerçekten onları mantıklı kılmak için gereken dereceye getirmek istedim. Ama ne yazık ki, düzenlemeyi yaptım.
Doktor Brown

Adil olmak gerekirse, eğer o nitpicky "ama bir işaretçi kelimenin tam anlamıyla sadece bir sayıdır" ya da doğru değilse, aslında bir işaretçi bir sayıyı belirleyen bir tanımlayıcıdır; detaylar.
Zaibis

2
İşaretçi, potansiyel olarak bazı nesnelere gönderme yapan bir değerdir (sayı bazı uygulamalara zaten çok özeldir). Potansiyel olarak boş işaretçiler, vahşi işaretçiler ve sarkan işaretçiler olduğu gibi, bunlardan bazıları (hatta hepsi!) Kullanılan dilin dışına çıkarılabilir.
Deduplicator

2
@Deduplicator: haklısınız, ancak bir işaretçinin sayı olarak zihinsel modelinin bu sorunun amacı için yeterince iyi olduğunu düşünüyorum. Öyleyse işleri basit tutalım.
Doc Brown,

5

Bir işaretçinin, adres içeren bir hafıza yeri olduğunu kesinlikle söyleyemem. İlk olarak, 0x23453tek bir bayta sığabilecek bir mimarinin farkında değilim . :) Bayt / word farkını elinizden çıkarsanız bile, her hafıza konumundaki bir adres içermekte sorun yaşarsınız . Adresler sadece sayılar ve hafızanın içeriği de sayılardır.

Bence buradaki püf nokta "işaretçi" nin mimarlığın herhangi bir özelliğini değil, insanın niyetini tanımladığıdır . Bu, bir "karakter" veya "string" in bellekte görebileceğiniz somut bir şey olmadığına benzer - hepsi de sadece sayılardır, ancak karakter dizileri olarak işlev görürler çünkü bu şekilde işlem görürler. "İşaretçi" yalnızca adres olarak kullanılması amaçlanan bir değer anlamına gelir.

Dürüst olmak gerekirse, amacınız belirli bir dili öğretmek ise (Objective C?), Klasik hafıza bandını çizmenin o kadar kullanışlı olduğundan bile emin değilim. Zaten yazılan değerleri ve bir bayt için çok büyük değerleri göstererek beyaz yalan söylüyorsunuz. Mekaniği değil, anlambilimi öğretin - işaretçilerle ilgili temel içgörü, dolaylı olarak sağlamalarıdır ki bu anlaşılması çok yararlı bir araçtır.

Bence, bazı verileri nerede bulacağınızı söyleyen , ancak verilerin kendisi olmayan bir URL ile karşılaştırılabileceğini düşünüyorum . Bana kulak ver:

  • Sen nadiren URL aslında umrumda olduğunu ; bunların büyük çoğunluğu isimlerle bağlantılı olarak uzaklaşıyor. Bir URL, bir sayfada tam olarak nasıl sonuçlandığını bilmeden pek çok insan interneti kullanır ; bazı insanlar URL’leri tamamen habersizler.

  • Her dize bir URL değildir veya URL olarak kullanılması amaçlanmamıştır.

  • Sahte bir URL’yi veya eskiden beri silinmiş bir sayfayı ziyaret etmeye çalışırsanız, hata alırsınız.

  • Bir URL bir görüntüye, bir metne, bir miktar müziğe veya herhangi bir sayıda başka öğeye işaret edebilir - veya içinde çeşitli şeyler bulunan bir sayfaya işaret edebilir. Benzer düzenlere sahip ancak farklı veriler içeren bir sürü sayfaya sahip olmak çok yaygındır.

  • Bir web sayfası hazırlarsanız ve başka bir web sayfasındaki verilere başvurmak istiyorsanız, hepsini kopyalayıp yapıştırmanız gerekmez; sadece bir link yapabilirsin.

  • Herhangi bir sayıda başka sayfa aynı URL’ye bağlanabilir.

  • Benzer sayfalardan oluşan bir koleksiyonunuz varsa, hepsine bağlantıların listelendiği bir dizin sayfası hazırlayabilir veya sayfa 1'in altında sizi sayfa 2'ye vb. Götüren "sonraki" bir bağlantıya sahip olabilirsiniz. Her iki yaklaşımın avantajları ve dezavantajları, özellikle web yöneticisinin çeşitli yerlere sayfa eklemek veya kaldırmak için ne yapması gerektiğini düşünüyorsanız, hemen açıktır.

Bu benzetme, işaretçilerin ne için olduğunu ve onları anlamak için kritik öneme sahip olduğunu açıkça ortaya koyar - aksi halde sadece keyfi, karmaşık ve anlamsız görünürler. Bir şeyin nasıl çalıştığını anlamak, ne yaptığını ve neden yararlı olduğunu zaten anlıyorsanız daha kolay. Bir işaretçinin, başka bir şeyin nerede olduğunu söyleyen bir kara kutu olduğunu zaten içselleştirdiyseniz ve ardından bellek modelinin inceliklerini öğrenirsiniz, ardından işaretçileri adres olarak göstermek oldukça açıktır. Ayrıca, anlambilimi öğretmek, öğrencilerinizi diğer dolaylı biçimleri anlamak ve icat etmek için çok daha iyi bir yere koyacaktır - çoğu ana dilin hiç imleci olmadığı durumlarda iyidir!


every memory location contains an address- Her hafıza konumu vardır bir adres. O değil içeriyordu belki haricinde, herhangi bir yere işaretçi değişkeni.
Robert Harvey,

@RobertHarvey her hafıza yeri (en azından kelime), önemsiz olarak bir adres olarak yorumlanabilecek bir sayı içerir . Mesele, donanımdaki hiçbir şeyin adresleri adres dışı adreslerden ayırt
edemediğidir

2

Zaten bir cevabı kabul ettiğinizi biliyorum ve bu sorunun zaten beş cevabı var; CS ders kitapları genellikle programlama dilinin seçimi konusunda agnostik olmaya çalışır, bu da olayları tanımlamak için kullanılan terminolojinin evrensel olduğu varsayımına yol açar. Değil.

C de unary ampersand operatörü "adres" operatörü olarak adlandırılır. C programcıları, ifadenin &xx değişkeninin adresini değerlendirdiğini söylemekte tereddüt etmeyeceklerdir . Tabii ki "x değişkeninin değerinin saklandığı hafıza adresi" anlamına geliyor, fakat hiç kimse sıradan konuşmalarda bu kadar bilgili değil. C'de "pointer" kelimesi genellikle değeri olarak bir hafıza adresine sahip olan bir değişkenin veri tipini ifade eder. Veya eşdeğerde değerin veri tipi. Ancak bazı insanlar değerin kendisi olarak "pointer" kullanırlar.

Java'da, nesne veya dizi türündeki tüm değişkenler C işaretçilerine benzer şekilde davranır (işaretçi aritmetiği hariç), ancak Java programcıları işaretçiler değil, referanslar olarak adlandırır.

C ++ referansları ve işaretçileri farklı kavramlar olarak görür. İlgili, ama tamamen aynı şey değil, bu yüzden C ++ programcıları konuşmada ayrım yapmak zorundalar. Ve işareti bazı bağlamlarda "adres", bazılarında ise "referans" olarak okunur.

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

Bir C programcısı bunu, "bir int" ile aynı anlamda "işaretçi" kullanarak tanımlayabilir. ("İnt, belirli bir aralıktaki bir tamsayıyı tutarken, bir işaretçi bir bellek adresini tutar.")

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

Bunu söylemenin garip bir yolu çünkü çok gevşek ve gayrı resmi bir "is" tanımı gerekiyor.

Bir değişkenin bellek konumu ile aynı şey olduğunu söylemek güvenli midir?

Bir bellek adresinin, bir değişkenin değerinin depolandığı bellekteki konum olduğunu söylemek daha açık olacaktır. (Verilmişse, derleyici optimizasyonları nedeniyle tüm değişkenler bellekte saklanmaz, ancak adresleri alınmış olan herhangi bir değişken &xolacaktır.)


Pedantik olduğumuz için: Bir şeyin depolandığı adres. Herhangi bir şeyi saklayamamak bir adresin yanı sıra, sık sık şeyler sadece biri (genellikle biraz tutarlı bir kural tarafından seçilen) adreslenen (ve sadece potansiyel olarak birçok adreslerden birini kullanarak) bitişik çoklu yerlerde saklanır.
Deduplicator

@Deduplicator Ben bir insan için bilgiçlik etmeye çalışmıyorum.
gatkin

C standardı, resmen, soyut makinenin her “sıra noktasında” adımlarını kesinlikle takip etmesi gereken değişkenler arasında - iplik güvenliği ve hafıza eşlemeli donanımdaki bazı düşük seviyeli işlemler için - ve bunları yapanlar arasında ayrım yapar. Bir sicile taşınması veya tamamen optimize edilmesi serbesttir.
Davislor

@Davislor: C Standard, diğer dil özelliklerinin "değişken" kullandığı yerlerde, değişken olmayan diğer şeyleri tanımlamak için "nesne" terimini kullanır. Bazı tartışmalar "değişken" dil-agnostik terimini kullanabilir, ancak herhangi bir nedenle Standart, adlandırılmış ayrık tahsisler (değişkenler) veya iç içe tahsisler (yapı / sendika üyeleri) gibi diğer nesnelerden türetilmiş nesneler arasında ayrım yapmak için bir terimden yoksundur. işaretçilerden kaldırılarak. Gayri resmi olarak, "değişken" harika bir terimdir ancak Standart bunu kullanmaz.
supercat

@supercat Bu doğru değil. C11 standart kullanımları “Değişken” terimi isimler, örneğin Birkaç tanesi düzine fazla yüz kere, “değişkene Eşzamanlı erişim bile bir atom işletilmesi sayesinde başlatıldı, veri yarışı teşkil etmektedir.”
Davislor

1

Bildirimi bir işaretçi değeri başka bir değişkenin bellek adresi olan bir değişkendir basitleştirilmiş edilir. Ancak bir okuyucu tam olarak bir bellek konumunun ne olduğunu ve bir değişkenden ne kadar farklı olduğunu anladığı zaman, tam olarak bir göstericinin ne olduğunu anlar ve bu nedenle bu yanlış açıklamaya güvenmeleri gerekmeyecektir.

İfade bir işaretçi, değeri başka bir bellek konumunun bellek adresi olan bir bellek konumudur . Bir işaretçinin değerinin bir hafıza konumunda saklanması gerekmez ve bir işaretçinin, amaçlanan "hafıza" tanımına bağlı olarak bir hafıza konumuna işaret etmesi gerekiyorsa tartışılmaz.

Bir değişken ve bir bellek konumu arasındaki fark nedir

Bir hafıza konumu, verilerin saklanabileceği birden fazla yerden biridir. Bu veri bir değişken veya bir değişkenin parçası olabilir. Değişkenler verileri etiketlemenin bir yoludur.


0

Bu cevap C ve C ++ 'ya odaklanır; Sorunuz C / C ++ 'ın diğer dillerden daha ayrılmaz bir parçası olan işaretçilerle ilgilendiği için uygun görünüyor. Bu gönderinin çoğu, ayrıntılı çalışma süresi olmayan derlenmiş dillere uygulanır (Pascal veya Ada gibi, ancak Java veya C # gibi değil).

Zaten verilen iyi cevaplar, bir değişkenin fiziksel bellekten daha soyut bir seviyede bir dil yapısı olduğunu vurgulamaktadır. Bu soyutlamanın belirli bir gerekçesi ve sistemi olduğuna rağmen vurgulamak isterim:

Soyutlama, esas olarak değişmez adres yerine bir ad kullanılmasından ibarettir.

İlke fikri, bir değişkenin yazılı bir nesne için adlandırılmış bir tanıtıcı olmasıdır; C / C ++ 'daki nesneler genellikle bellektedir. Dilleri daha sonra ömür boyu yönetimi ve tür dönüşümleri için veri marşalizasyonu ile ilgili bazı güzellikler ekleyin. Değişkenler kavramı fiziksel adreslerden daha soyut çünkü adreslerin sayısal değerini veya bellekteki işlevlerin yerini gerçekten umursamıyoruz. Bunları basitçe adlandırır ve daha sonra adlarına göre adlandırabiliriz ve derleyici, bağlayıcı ve çalışma zamanı sistemi titizlikle ilgilenir.

Ve C / C ++ 'nın hafıza agnostik olduğunu iddia etmeyin: Sonuçta, evrensel olarak uygulanabilir adres operatörü vardır. Evet, doğru, register storage sınıfındaki C değişkeninin adresini alamazsınız; ama en son ne zaman birini kullandın? Bu genel kavramın özel bir istisnasıdır, argümanın toptan olarak reddedilmesi değildir. Genel kural, tam tersine, bir değişkenin adresini almanın, derleyiciyi gerçekte, aksi halde (örneğin sabitlerle) yapmasa bile bellekte bir nesne oluşturmaya zorlamasıdır. "İsimlendirme" kavramı ayrıca C ++ referansları için iyi bir paradigmadır: Bir referans aynı nesne için sadece başka bir isimdir .

68k için inline assembler yazdığımda, değişken adlarını kayıtlara hitap etmek için ofset olarak nasıl kullanabileceğinizi görmek güzeldi (ve registerçıplak metal kayıt adları yerine bildirilen değişkenlerin adlarını kullanabilirsiniz!). Derleyiciye göre değişken sabit bir adres kaymasıdır. Tekrarlamak için: Değişkenler, genellikle bellekteki nesneler için tanıtıcı olarak adlandırılır.


İşaretçiler, C #, Java, JS ve diğer dillerin de çok temel bir parçasıdır. Onları farklı olarak adlandırmak, iyi bir PR olmasına rağmen bunu değiştirmez.
Deduplicator

@Deduplicator :-) İyi ol 'Tony ...
Peter -

0

Soru, C Standardı ek garantiyle güçlendirmek suretiyle oluşturulmuş popüler bir dile yöneliktir. "Standardın bazı bölümlerinin veya bir uygulamanın belgelerinin bazı eylemlerin davranışlarını tanımladığı durumlarda ve bazı bölümlerin tanımsız olarak sınıflandırdığı durumlarda eski kısım egemendir. "ve diğer dillerin kullanımına uygun" değişken "tanımının yanı sıra.

Bu dilde, her bir hafıza yeri, her biri bağımsız bir şekilde sıfır veya bir olabilen, her zaman bir miktar (tipik olarak sekiz) bit tutan numaralandırılmış bir posta kutusu olarak görülebilir. Bellek konumları genellikle iki, dört veya sekiz satır halinde düzenlenir. ve bazı işlemler aynı anda birden fazla ardışık hafıza konumunda çalışır. Makineye bağlı olarak, iki, dört veya sekiz hafızalı grupta çalışan bazı işlemler, tek bir sıradaki konumlarda çalışmakla sınırlı olabilir. Ayrıca, bazı makineler ardışık olarak numaralandırılmış tek bir posta kutusundan oluşan bir odaya sahip olabilirken, diğerlerinde birden fazla ayrık numaralandırılmış posta kutusu grubu bulunabilir.

Bir değişken, yalnızca kendisiyle ilişkilendirilen bir dizi bellek konumunu ve bu bellek konumlarının yorumlanması gereken bir türü tanımlar. Bir değişkeni okumak, ilişkili depolama konumlarındaki bitlerin değişkenin tipine uygun bir şekilde yorumlanmasına ve bir değişkenin yazılmasının ilişkili bitlerin türüne ve değerine uygun bir şekilde ayarlanmasına neden olacaktır.

Bir adres, bir posta kutusunu tanımlamak için gerekli olan her şeyi içerir. Bu, basit bir numara olarak veya o grup içindeki bir posta kutusunun numarası ile birlikte bir grup grup belirleyicisi olarak saklanabilir.

&Operatörü bir değişkene uygulamak, adresini ve tipini içine alan bir işaretçi verecektir. Unary *veya []işlecin bir işaretçiye uygulanması, kapsüllenmiş adresten başlayan posta kutularının bitlerinin kapsüllenmiş tipe uygun bir şekilde yorumlanmasına veya ayarlanmasına neden olacaktır.


Soruyu fazla düşünmüş gibisin.
Robert Harvey,

0

Bu partiye geç geleceğim ama 2 sentimi koyamayacağım.

Bu zamanlarda, bu bellek konumlarında saklanan değerler arasındaki fark nedir?

Zaman 1

görüntü tanımını buraya girin

Zaman 2

görüntü tanımını buraya girin

Doğru cevap: hiçbir şey. Hepsi, anlamlarının farklı yorumlarıyla sunulan özdeş değerlerdir.

Bunu nasıl bilebilirim? Çünkü bunu yapan kişi benim. Bunu henüz bilmiyorsun.

Bant dışı problem dediğim bir şeye rastlıyorsunuz. Bu değerlerin anlamlarının doğru nasıl yorumlanacağı burada saklanmaz. Bu bilgi başka bir yerde saklanır. Ancak bu değerleri kağıda sunduğunuzda, bu yorumu siz koyarsınız. Bu, yalnızca bu bellek konumlarında bulunmayan bilgileri eklediğiniz anlamına gelir.

Örneğin, buradaki değerler aynıdır, ancak yalnızca bir ASCII / UTF-8 karakter kodlaması varsayalım ki doğru olduğunuzu doğru olduğunuzu biliyorsunuz, EBCDIC değil, ilkini nasıl aldığımı . Ayrıca, ikincisinin, hepsinin "0x" ile başlayan dizgelere başvuru yapmaktan ziyade, diğer adreslere işaretçiler olabilecek, bu bellek konumlarında saklanan sayısal değerlerin onaltılık ifadeleri olduğunu varsaymalısınız. : P

Bu bellek konumlarında saklanan hiçbir şey, bu varsayımların hiçbirinin doğru olduğunu söylemez. Bu bilgi saklanabilir. Ancak başka bir yerde saklanırdı.

Bu sunum sorunu . İlk olarak nasıl sunacağına karar vermeden hiçbir numarayı ifade edemezsin. Varsayımlara, sözleşmelere ve içeriğe yaslanabilirsiniz, ancak derinlemesine çizerseniz, sunum açıkça tanımlanmadığında, gerçekten doğru olan tek cevap "yeterli bilgi" değildir.


Aynı bellek, aynı anda farklı sabit şeyler için kullanıldığında daha da eğlencelidir.
Deduplicator

@Deduplicator Doğru. Bu her zaman beni c ++ 'nın yeniden yorumladığını düşündürüyor . Aynı bitler farklı bir yol gördü.
candied_orange

@Deduplicator, ya da düşün,
c'deki
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.