Diğer cevaplar doğrudur, ancak hiçbiri üçünün de aynı değeri içermesinin mümkün olduğunu düşünmemektedir ve bu yüzden bir şekilde eksiktirler.
Bunun diğer cevaplardan anlaşılamamasının nedeni, tüm örneklerin, yararlı ve kesinlikle makul olsa da, işaretçinin x
kendisine işaret ettiği durumu kapsamamaktadır .
Bu inşa etmek oldukça kolay, ama anlaşılması biraz daha zor. Aşağıdaki programda, üç değerin tümünü aynı olmaya nasıl zorlayabileceğimizi göreceğiz.
NOT: Bu programda davranış tanımlanmamış, ama ben işaretçileri bir şeye ilginç bir göstergesi olarak tamamen buradan post ediyorum edebilir , ama olmamalı .
#include <stdio.h>
int main () {
int *(*x)[5];
x = (int *(*)[5]) &x;
printf("%p\n", x[0]);
printf("%p\n", x[0][0]);
printf("%p\n", x[0][0][0]);
}
Bu, hem C89 hem de C99'da uyarı olmadan derlenir ve çıktı aşağıdaki gibidir:
$ ./ptrs
0xbfd9198c
0xbfd9198c
0xbfd9198c
İlginçtir, her üç değer de aynıdır. Ama bu bir sürpriz olmamalı! İlk olarak, programı yıkalım.
Biz beyan x
her bir eleman int türü işaretçisi olan 5 elemanlı bir dizi için bir işaretçi olarak. Bu bildirim, çalışma zamanı yığınına 4 bayt x
ayırır (veya uygulamanıza bağlı olarak daha fazla; makine işaretçilerimde 4 bayttır), bu nedenle gerçek bir bellek konumuna atıfta bulunur. C dil ailesinde, içeriği x
sadece çöptür, konumun önceki kullanımından kalan bir şeydir, bu yüzden x
kendisi hiçbir yere işaret etmez - kesinlikle ayrılmış alana değil.
Yani, doğal olarak, değişkenin adresini alabilir x
ve bir yere koyabiliriz, bu yüzden tam olarak bunu yaparız. Ama devam edip x'in içine koyacağız. Yana &x
farklı bir türe sahip x
, biz uyarıları alamadım bu yüzden bir döküm yapmak gerekir.
Bellek modeli şöyle görünecektir:
0xbfd9198c
+------------+
| 0xbfd9198c |
+------------+
Böylece adresteki 4 baytlık bellek bloğu 0xbfd9198c
, onaltılı değere karşılık gelen bit desenini içerir 0xbfd9198c
. Yeterince basit.
Ardından, üç değeri yazdırıyoruz. Diğer cevaplar her ifadenin neyi ifade ettiğini açıklar, bu yüzden ilişki şimdi açık olmalıdır.
Değerlerin aynı olduğunu, ancak sadece çok düşük bir düzeyde olduğunu görebiliriz ... bit kalıpları aynıdır, ancak her bir ifadeyle ilişkili tip verileri yorumlanmış değerlerinin farklı olduğu anlamına gelir. Örneğin x[0][0][0]
, biçim dizesini kullanarak yazdırırsak %d
, çok büyük bir negatif sayı elde ederiz, bu nedenle "değerler" pratikte farklıdır, ancak bit modeli aynıdır.
Bu gerçekten çok basit ... şemalarda, oklar farklı bellek yerine aynı bellek adresini gösteriyor. Ancak, tanımlanmamış bir davranıştan beklenen bir sonucu zorlayabilmemizle birlikte, bu sadece tanımsızdır. Bu üretim kodu değil, sadece bir bütünlük uğruna bir gösteri.
Makul bir durumda, malloc
5 int işaretçisi dizisini oluşturmak için ve yine o dizide işaret edilen girişleri oluşturmak için kullanırsınız. malloc
her zaman benzersiz bir adres döndürür (bellekte kalmadığınız sürece, bu durumda NULL veya 0 döndürür), bu nedenle böyle kendinden referanslı işaretçiler hakkında asla endişelenmenize gerek kalmaz.
Umarım aradığınız tam yanıt budur. Sen beklememelisiniz x[0]
, x[0][0]
ve x[0][0][0]
eşit olmak, ama zorla eğer onlar olabilir. Başının üstünde bir şey olursa, açıklığa kavuşturmak için bana haber ver!
x[0]
,x[0][0]
Vex[0][0][0]
farklı türleri vardır. Karşılaştırılamazlar. Ne demek istiyorsun!=
?