C de boşluk neden boş değil demektir?


25

Java ve C # gibi kuvvetle yazılmış dillerde bir yöntem için dönüş türü olarak , void(veya Void) gibi görünüyor:

Bu yöntem hiçbir şey döndürmez. Hiçbir şey değil. İade yok. Bu yöntemden hiçbir şey almayacaksınız.

Asıl garip olan, C cinsinden, voidbir geri dönüş türü olarak veya hatta bir yöntem parametresi türü olarak şu anlama gelir:

Gerçekten bir şey olabilir. Bunu öğrenmek için kaynak kodunu okumalısınız. İyi şanslar. Bir işaretçi ise, ne yaptığınızı gerçekten bilmelisiniz.

Aşağıdaki örnekleri C göz önünde bulundurun:

void describe(void *thing)
{
    Object *obj = thing;
    printf("%s.\n", obj->description);
}

void *move(void *location, Direction direction)
{
    void *next = NULL;

    // logic!

    return next;
}

Açıkçası, ikinci yöntem, tanımı gereği herhangi bir şey olabilecek bir gösterici döndürür.

C, Java ve C # 'dan daha eski olduğundan, bu diller neden void“hiçbir şey” veya “işaretçi” olarak kullanılırken neden “hiçbir şey” olarak benimsemiştir ?


138
voidKod örneğinin kullandığı void*ve tamamen farklı bir şey olan soru başlığı ve metninizden bahsediyor .

4
Ayrıca, Java ve C # 'nın da aynı konsepte sahip olduklarını, sadece Objectbir durumda kesinleştirmek için çağırdıklarını unutmayın .
Mooing Duck

4
@Phe onlar tam olarak yazılmamış değil mi? C # kullanarak ördek yazarak, dynamicnadiren kullanılan türü kastediyor musunuz?
Axarydax

9
@Mephy: En son Vikipedi'yi kontrol ettiğimde , "kesinlikle yazılmış" kelimelerin karşılıklı çelişkili anlamlarını listeledik . Bu nedenle, "C # kesinlikle yazılmadı" demek anlamsızdır.
Eric Lippert

8
@LightnessRacesinOrbit: Hayır, demek istediğim, terimin yetkili bir tanımı olmadığıdır. Vikipedi, bir terimin doğru anlamını söyleyen , kuralcı bir kaynak değildir . Bu açıklayıcı bir kaynaktır. Onbir farklı çelişkili anlamlara açıklanan gerçektir kanıtlar olduğunu terim dikkatle tanımlamadan konuşmada kullanılamaz . Aksi taktirde, konuşmalardaki insanların birbirleriyle değil geçmişle konuşacak olma ihtimallerinin çok iyi olduğu anlamına gelir.
Eric Lippert

Yanıtlar:


58

Anahtar kelime void(işaretçi değil), bu dillerde "hiçbir şey" anlamına gelir. Bu tutarlı.

Belirttiginiz gibi, void*ham imleçleri (C ve C ++) destekleyen dillerde "imlece işaret" anlamına gelir. Bu talihsiz bir karardır çünkü belirttiğiniz gibi, voidiki farklı şey ifade ediyor.

voidFarklı bağlamlarda "hiçbir şey" ve "hiçbir şey" demeyi reddetmenin ardındaki tarihsel sebebi bulamadım , ancak C bunu başka yerlerde de yapıyor. Örneğin, staticfarklı bağlamlarda farklı amaçlara sahiptir. C dilinde, uygulama hakkında ne düşündüğüne bakılmaksızın, anahtar kelimeleri bu şekilde tekrar kullanmak için açıkça bir yöntem vardır.

Java ve C #, bu sorunların bazılarını düzeltmek için temiz bir ara verebilecek kadar farklı. Java ve "safe" C # ayrıca ham işaretçilere izin vermez ve kolay C uyumluluğu gerekmez (Unsafe C # işaretçilere izin vermez , ancak C # kodunun büyük çoğunluğu bu kategoriye girmez). Bu, geriye dönük uyumluluk konusunda endişelenmeden işleri biraz değiştirmelerini sağlar. Bunu yapmanın bir yolu, Objecttüm sınıfların miras aldığı hiyerarşinin kökenine bir sınıf tanıtmaktır ; bu nedenle Objectreferans void*, tür sorunları ve ham bellek yönetimi sıkıntısı olmadan aynı işlevi görür .


2
Eve geldiğimde bir referans vereceğim

4
They also do not allow raw pointers and do not need easy C compatibility.Yanlış. C # işaretçilere sahiptir. Genelde (ve genellikle olmalı), ama oradalar.
Magus,

8
Neden tekrar kullandıklarına ilişkin olarak void: bariz bir neden, yeni bir anahtar kelime eklemekten kaçınmak (ve potansiyel olarak mevcut programları kırmak) olabilir. Özel bir anahtar kelime (ör. unknown) void*Tanıtsalardı , o zaman anlamsız (ve muhtemelen yasa dışı) bir yapı unknownolurdu ve sadece biçiminde yasal olurdu unknown*.
jamesdlin

20
Hatta içinde void *, voidyollara "hiçbir şey" değil "bir şey". Yönetmelik alamazsınız void *, önce başka bir işaretçi türüne atmanız gerekir.
Ağustos'ta

2
@oefe ben çünkü o saçı bölmek için anlamsız olduğunu düşünüyorum voidve void*farklı türleri (aslında vardır void"hayır tip" dır). Bu şunu demek kadar his gibi yapar " intin int*araçlar şey." Hayır, bir işaretçi değişkenini bildirdiğinizde, "bu bir şeyi tutabilecek bir hafıza adresidir" diyorsunuz. Durumda, void*"bu adres bir şey barındırıyor ama bir şeyin işaretçi türünden çıkarılamayacağını " söylüyorsunuz .

32

voidve void*iki farklı şey. voidC, Java’da olduğu gibi, aynı zamanda bir dönüş değerinin olmaması anlamına gelir. A void*, türü olmayan bir işaretçidir.

C'deki tüm işaretçilerden kaldırılmaya çalışılması gerekir. A'yı reddetmiş void*olsaydın, ne tür bir şey beklersin? C işaretçilerinin herhangi bir çalışma zamanı türü bilgisi taşımadığını unutmayın, bu nedenle türün derleme zamanında bilinmesi gerekir.

Bu bağlam göz önüne alındığında, mantıksal olarak bir hakemle yapabileceğiniz tek şey void*, görmezden gelmektir , bu tam olarak voidtürün gösterdiği davranıştır .


1
"Görmezden gel" kısmına ulaşana kadar katılıyorum. Dönen şeyin nasıl yorumlanacağı hakkında bilgi içermesi olasıdır. Başka bir deyişle, bir BASIC Varyantının C eşdeğeri olabilir. “Bunu aldığınızda, ne olduğunu anlamaya bir göz atın - size ne bulacağınızı söyleyemem”.
Floris

1
Ya da başka bir deyişle, varsayımsal olarak, ilk baytta, imleç tarafından belirtilen bellek konumuna programlayıcı tanımlı bir "tip tanımlayıcı" koyabilirim, bu da izleyen baytlarda hangi veri tipini bulmayı beklediğimi söylerdi.
Robert Harvey,

1
Elbette, ancak C de bu ayrıntıları dilde pişirmek yerine programcıya bırakmaya karar verildi. Gönderen dil açısından, bu görmezden dışında başka ne bilmiyor. Bu, çoğu durumda, statik olarak belirleyebildiğiniz zaman, her zaman ilk bayt olarak tür bilgisi içeren ek yükü önler.
Karl Bielefeldt

4
@RobertHarvey evet, ancak o zaman boş bir işaretçiyi kaldırmıyorsunuz; void işaretçisini bir char işaretçisine atıyor ve sonra char işaretçisini kaldırıyorsunuz.
user253751

4
@ Floris sana gcckatılmıyorum. Değeri kullanmaya çalışırsanız, gccsöyleyerek bir hata mesajı oluşturun error: void value not ignored as it ought to be.
kasperd

19

Belki de voidgeri dönüş tipi olarak düşünmek daha yararlı olacaktır . Sonra ikinci yönteminiz "yazılmamış bir işaretçi döndüren bir yöntem" i okuyacaktı .


Bu yardımcı olur. Nesne yönelimli dillerde geçirilen yıllardan sonra C'yi öğrenen (nihayet!) Birisi olarak, işaretçiler benim için çok yeni bir kavram. Bir işaretçiyi döndürürken void, kabaca *"herhangi bir geri dönüş türü" anlamına gelen ActionScript 3 gibi dillere eşdeğer olduğu anlaşılıyor .
Naftuli Kay

5
Eh, voidjoker değildir. Bir işaretçi sadece bir hafıza adresidir. *"Bu işaretçi tarafından belirtilen bellek adresinde bulmayı umduğunuz veri türü" ifadesinden önce bir tür koymak . Koyarak voidönce *derleyiciye diyor "Ben türü bilmiyorum; sadece bana çiğ işaretçi döndürür, ve bunun işaret eden verilerle ne yapacağını anlamaya edeceğiz."
Robert Harvey,

2
void*"Boşluk" a işaret ettiğini bile söyleyebilirim . İşaret ettiği hiçbir şeyi olmayan çıplak bir işaretçi. Yine de başka herhangi bir işaretçi gibi onu kullanabilirsiniz.
Robert

11

Biraz terminolojiyi sıkılalım.

Gönderen çevrimiçi C 2011 standardı :

6.2.5 Tipler
...
19 voidTip boş bir değerler setinden oluşur; tamamlanamayan eksik bir nesne türüdür.
...
6.3 Dönüşümler
...
6.3.2.2 geçersiz

1 Bir voidifadenin (varolmayan) değeri (türü olan bir ifade void) hiçbir şekilde kullanılmayacak ve örtük veya açık dönüştürmelere (hariç void) uygulanmayacaktır. böyle bir ifade. Başka türdeki bir void ifade, ifade olarak değerlendirilirse , değeri veya göstericisi atılır. (Bir voidifade yan etkileri için değerlendirilir.)

6.3.2.3 İşaretçiler

1voidbir işaretçiye veya bir işaretçiden herhangi bir nesne türüne dönüştürülebilir. Herhangi bir nesne türüne yönelik bir işaretçi, geçersiz kılmak ve tekrar geri dönmek için bir işaretleyiciye dönüştürülebilir; sonuç, orijinal işaretçiyle eşit olarak karşılaştırılmalıdır.

Bir voidifadenin değeri yoktur (yan etkileri olsa da). Geri dönmek için tanımlanmış bir işleve sahipsem void, şöyle:

void foo( void ) { ... }

sonra çağrı

foo();

bir değere göre değerlendirilmez; Sonucu hiçbir şeye atayamam çünkü sonuç yok.

Bir işaretçi için voidesas olarak bir "genel" işaretçi tipidir; void *Açık bir döküm kullanmadan başka bir nesne işaretçi türüne bir değer atayabilirsiniz (bu nedenle tüm C programcılarının sonuçlarını almanız için size bağırmaları gerekir malloc).

Doğrudan hakaret edemezsiniz a void *; sivri uçlu nesneye erişmeden önce onu farklı bir nesne işaretçi türüne atamanız gerekir.

voidişaretçiler genel (veya daha az) genel arayüzleri uygulamak için kullanılır; kanonik örnek, yazı qsorttipinde bir karşılaştırma işlevi sağladığınız sürece herhangi bir türdeki dizileri sıralayabilen kütüphane işlevidir.

Evet, aynı anahtar kelimeyi iki farklı kavram için kullanmak (değere karşı genel işaretçi yok) kafa karıştırıcıdır, ancak emsal olmayan bir şey değildir; staticHem C hem de C ++ 'da birden çok ayrı anlama sahiptir.


9

Java ve C # 'da, bir yöntem için bir dönüş türü olarak geçersiz olduğu anlaşılıyor: bu yöntem hiçbir şey döndürmüyor. Hiçbir şey değil. İade yok. Bu yöntemden hiçbir şey almayacaksınız.

Bu ifade doğru. C ve C ++ için de doğru.

C de, bir geri dönüş türü olarak veya bir yöntem parametresi türü olarak bile geçersiz, farklı bir şey anlamına gelir.

Bu ifade yanlış. voidC veya C ++ dilinde bir dönüş türü olarak C # ve Java ile aynı şey anlamına gelir. Sen karıştırıyorsun voidile void*. Onlar tamamen farklı.

Bunu karıştırmak voidve void*tamamen iki farklı şey demek değil mi?

Evet.

Bir işaretçi nedir? Boşluk işaretçisi nedir?

Bir gösterici , bir bir değerini edilebilir duruma gelmiş . Geçerli bir işaretçi referansının kaldırılması , sivri tipte bir saklama yeri verir . Bir boşluk işaretçisi , özel bir sivri tipine sahip olmayan bir işaretçidir; değerin bir depolama yeri oluşturmak için seçilmeden önce daha spesifik bir işaretçi türüne dönüştürülmesi gerekir .

Boşluk işaretçileri C, C ++, Java ve C # öğelerinde aynı mıdır?

Java'da geçersiz işaretçiler yoktur; C # yapar. Bunlar, C ve C ++ ile aynıdır - kendisiyle ilişkili herhangi bir özel türü olmayan, bir depolama yeri oluşturmak için ayırmadan önce daha spesifik bir türe dönüştürülmesi gereken bir işaretçi değeri.

C, Java ve C # 'dan daha eski olduğu için, bu diller neden “hiçbir şey” olarak kullanılırken, “hiçbir şey” olarak kullanılırken, bu diller neden “hiçbir şey” anlamına gelmiyordu?

Soru tutarsızdır, çünkü yanlışlıkları varsaymaktadır. Daha iyi sorular soralım.

Java ve C # void, örneğin, işlevlerin asla boşa dönmediği ve alt yordamların her zaman boşa dönmediği Visual Basic kuralını kullanmak yerine, geçerli bir geri dönüş türü olan kuralları kabul etti.

Java veya C # 'ya gelen programcıların voidgeri dönüş tipi olduğu dillerden haberdar olmak.

C # neden void*tamamen farklı bir anlamı olan kafa karıştırıcı sözleşmeyi kabul etti void?

void*İşaretçi tipi olan dillerden C # 'ya gelen programcılara aşina olmak .


5
void describe(void *thing);
void *move(void *location, Direction direction);

İlk işlev hiçbir şey döndürmez. İkinci işlev geçersiz bir işaretçi döndürür. İkinci işlevi olarak ilan ederdim.

void* move(void* location, Direction direction);

Eğer "boşluksuz" anlamsız "anlamsız" olarak düşünürseniz yardımcı olabilir. Dönüş değeri describe"anlamsız" dır. Böyle bir işlevden bir değer döndürmek yasadışıdır, çünkü derleyiciye dönüş değerinin anlamsız olduğunu söylediniz. Bu işlevden dönüş değerini yakalayamazsınız, çünkü anlamı yoktur. Bir tür değişkeni bildiremezsiniz, voidçünkü anlamı yoktur. Örneğin void nonsense;saçmalık ve aslında yasadışı. Ayrıca, bir boşluk dizisinin void void_array[42];de saçmalık olduğuna dikkat edin .

Void ( void*) için bir işaretçi farklı bir şeydir. Bu bir işaretçidir, dizi değil. void*"Anlamsız" bir şeye işaret eden bir işaretçi olarak anlamını okuyun . İşaretçi "anlamsız" dır, yani böyle bir göstergeyi kaldırmanın anlamı yoktur. Bunu yapmaya çalışmak aslında yasa dışı. Bir boş göstericiyi geçersiz kılan kod derlenmez.

Öyleyse, bir boş göstericiyi kaldıramazsanız ve bir dizi boşluğu yapamazsanız, bunları nasıl kullanabilirsiniz? Cevap, herhangi bir tür için bir göstericinin kullanılabildiği şeydir void*. Bir işaretçiyi bir yere işaretlemek void*ve bir işaretçiye orijinal türüne geri almak, orijinal işaretçiye eşit bir değer verir. C standardı bu davranışı garanti eder. C de bu kadar çok boş işaretçi görmenin birincil nedeni, bu kabiliyetin, nesneye yönelik olmayan bir dilde ne olduğunu gizleme ve nesne tabanlı programlamanın uygulanmasında bir yol sağlamasıdır.

Son olarak, nedeni genellikle bakınız moveilan void *move(...)ziyade void* move(...)ziyade türü daha adının yanındaki yıldız işareti koyarak C. çok yaygın bir uygulamadır çünkü sebebi şu beyanı büyük derde edecektir edilir: int* iptr, jptr;Bu seni ne bir iki işaretçi bildirdiğinizi düşünüyorum int. Sen değilsin. Bu bildirim, jptrbir intişaretçi yerine bir işaretçi yapar int. Uygun bildirim: int *iptr, *jptr;Beyan beyanı başına yalnızca bir değişken bildirme uygulamasına bağlı kalırsanız, yıldızın tipine ait olduğunu iddia edebilirsiniz. Ama numara yaptığını unutmayın.


"Boş bir işaretçiyi geçersiz kılan kod derlenmez." Boşluk göstergesini iptal eden kodun derlenmeyeceğini kastediyorsunuz . Derleyici, boş bir işaretçiyi düzenlemekten sizi korumaz; bu bir çalışma zamanı sorunudur.
Cody Gray

@CodyGray - Teşekkürler! Bunu düzeltdim. Boş bir işaretçiyi geçersiz kılan kod derlenir (işaretçi olmadığı sürece void* null_ptr = 0;).
David Hammen

2

Basitçe söylemek gerekirse, fark yoktur . Sana bazı örnekler vereyim.

Diyelim ki Car adında bir sınıfım var.

Car obj = anotherCar; // obj is now of type Car
Car* obj = new Car(); // obj is now a pointer of type Car
void obj = 0; // obj has no type
void* = new Car(); // obj is a pointer with no type

Burada karışıklık tanımladığınız nasıl kapalı dayanır burada inanıyoruz voidvs void*. Bir geri dönüş türü void"Ben hiçbir şey döndürmez" anlamına gelirken geri dönüş türü void*"hiçbir şey türünden bir işaretçi döndürmez" anlamına gelir.

Bu, bir işaretçinin özel bir durum olması nedeniyledir. Bir işaretçi nesnesi, orada geçerli bir nesne olup olmadığına bakılmaksızın daima bellekteki bir konuma işaret edecektir. Benim İster void* carreferanslar bir bayt, bir kelime, bir araba ya da bir bisiklet önemli değil benim çünkü void*hiç puan şey yok tanımlanmış türü ile. Daha sonra tanımlamak bize kalmıştır.

C # ve Java gibi dillerde, bellek yönetilir ve işaretçiler kavramı Object sınıfına alınır. "Hiçbir şey" türündeki bir nesneye referans vermek yerine, en azından bizim nesnemizin "Nesne" türünden olduğunu biliyoruz. Nedenini açıklamama izin ver.

Geleneksel C / C ++ 'da bir nesne yaratıp işaretçisini silerseniz, o nesneye erişmek imkansızdır. Bu bellek sızıntısı olarak bilinen şey .

C # / Java'da her şey bir nesnedir ve bu, çalışma zamanının her nesneyi takip etmesini sağlar. Nesnemin bir Araba olduğunu bilmesi gerekmiyor, sadece zaten Object sınıfı tarafından halledilen bazı temel bilgileri bilmesi gerekiyor.

Programcılar için, bu, C / C ++ 'da elle dikkat çekmek zorunda olacağımız bilgilerin çoğunun bizim için Object sınıfı tarafından halledildiği ve işaretçi olan özel durum için gereksinimin ortadan kaldırıldığı anlamına gelir.


"void * tanımlanmamış tipte bir şeye işaret ediyor" - tam olarak değil. Sıfır uzunluktaki bir değere işaretçi olduğunu söylemek daha doğrudur (neredeyse 0 elementli bir diziye benzer, ancak diziyle ilişkili tip bilgisi bile olmadan).
Scott Whitlock

2

Bunları C'de nasıl düşünebileceklerini söylemeye çalışacağım. C standardındaki resmi dil pek rahat voiddeğil ve onunla tamamen tutarlı olmaya çalışmıyorum.

Tip void, tipler arasında birinci sınıf vatandaş değildir. Bir nesne türü olmasına rağmen, herhangi bir nesnenin (veya değerin), bir alanın veya bir işlev parametresinin türü olamaz; bununla birlikte, bir işlevin dönüş türü olabilir ve bu nedenle bir ifade türü olabilir (temel olarak bu tür işlevlerin çağrılarıdır, ancak koşullu işleçle oluşturulan ifadeler de boş yazı tipine sahip olabilir). Ama bile asgari kullanımı voidbir değer türü olarak bu yani dönen bir işlev biten açık yukarıdaki yaprakları kapı voidformunun bir ifadeye tip bir ifadesidir , açıkça (olsa C ++ izin C yasaktır, fakat C için geçerli olmayan nedenlerden dolayı).return E;Evoid

Türdeki nesnelere voidizin verildiyse , 0 bite sahip olurlar (bu, bir tür ifadesinin değerindeki bilgi miktarıdır void); Bu tür nesnelere izin vermek büyük bir sorun olmayacaktı, ancak oldukça işe yaramazlardı (0 büyüklüğündeki nesneler işaretçi aritmetiğini tanımlamakta zorlanacaktı, belki de en iyisi yasak olacaktı). Böyle bir nesnenin farklı değerler kümesinde bir (önemsiz) öğe bulunur; değeri, trivally, herhangi bir maddeye sahip olmadığı için alınabilir, ancak değiştirilemez ( farklı bir değer içermeyen ). Bu nedenle standart, voidboş bir değerler kümesini; böyle bir tür, yapamayan ifadeleri tanımlamak için yararlı olabilirC dili aslında böyle bir tür kullanmasa da değerlendirilebilir (atlamalar veya sonlanmayan aramalar gibi)

Değer türü olarak kabul voidedilmemek, en az iki doğrudan "yasaklı" olarak tanımlamak için doğrudan olmayan bir şekilde kullanılmıştır: (void)işlev türlerinde parametre belirtimi olarak belirtmek , kendilerine herhangi bir argüman vermenin yasaklanması anlamına gelir ('()' aksine her şey anlamına gelirse) izin verilir ve evet, parametre belirtimine voidsahip işlevlere argüman olarak bir ifade sağlamak bile (void)yasaktır) ve beyan etme void *p, başvuruda bulunma ifadesinin *pyasak olduğunu belirtir (ancak geçerli bir ifade türü değildir void). Bu nedenle, bu kullanımların geçerli bir ifade türü olarak voidtutarlı olmadığı konusunda haklısın void. Ancak bir tür nesnevoid*gerçekten herhangi bir türün değerlerine bir işaretçi değildir, işaret edilemez olarak işaretlenmiş olarak kabul edilir ve işaretçi aritmetiği yasaklanmıştır. "İşaretçi olarak kabul edilir" o zaman gerçekten sadece bilgi kaybı olmadan ve herhangi bir işaretçi tipine atılabileceği anlamına gelir. Bununla birlikte, tamsayı değerlerini ve değerlerini almak için de kullanılabilir, bu nedenle hiçbir şeye işaret etmesi gerekmez.


Kesin konuşursak, herhangi bir nesne işaretçi tipinden ve herhangi bir bilgi kaybı olmadan, her zaman ve her zaman değil . Genel olarak void*, başka bir işaretçi türüne çevirme, bilgiyi kaybedebilir (veya UB'ye sahip olsam bile, elimden hatırlayamıyorum), ancak gelenin değeri, void*şu anda yayınladığınız aynı türden bir işaretçi kullanmaktan geliyorsa, o zaman öyle değil.
Steve Jessop,

0

C # ve Java'da her sınıf bir Objectsınıftan türetilir . Dolayısıyla ne zaman "bir şeye" referans vermek istediğimizde, bir tür referans kullanabiliriz Object.

Bu amaçla geçersiz işaretçiler kullanmamız gerekmediğinden, voidburada "bir şey ya da hiçbir şey" anlamına gelmez.


0

C'de, herhangi bir tipte [işaretçiler referans türü gibi davranır] için bir göstericiye sahip olmak mümkündür. Bir işaretçi, bilinen bir türdeki bir nesneyi tanımlayabilir veya isteğe bağlı (bilinmeyen) türdeki bir nesneyi tanımlayabilir. C'yi oluşturanlar, "bazı özel tipteki şeylere imleci" rastgele tip olayına işaretçi "için aynı genel sözdizimini kullanmayı seçtiler. İkinci durumda sözdizimi, türün ne olduğunu belirtmek için bir belirteç gerektirdiğinden, eski sözdizimi, tür biliniyorsa o belirtecin ait olacağı bir şey koymak ister. C "void" anahtar sözcüğünü bu amaç için kullanmayı seçti.

Pascal'da, C'de olduğu gibi, herhangi bir türden işaretçilere sahip olmak mümkündür; Pascal'ın daha popüler lehçeleri de “göstergeyi rastgele türden bir şeye” izin verir, ancak “belirli bir türden bir şeye işaretçi” için kullandıkları sözdizimini kullanmak yerine, sadece eskisi gibi ifade ederler Pointer.

Java'da kullanıcı tarafından tanımlanmış değişken türleri yoktur; her şey ilkel veya yığın nesne başvurusudur. "Belirli bir türdeki bir yığın nesnesine başvuru" veya "rasgele türdeki bir yığın nesnesine başvuru" türündeki tanımlamalar yapılabilir. İlki, referans olduğunu belirtmek için herhangi bir özel noktalama işareti olmadan türün adını kullanır (çünkü başka bir şey olamaz); ikincisi tür adını kullanır Object.

void*Keyfi türdeki bir şeyin işaretçisi olarak isimlendirme olarak kullanılması, C ve C ++ gibi doğrudan türevlere özgü olduğunu bildiğim kadarıyla; Bildiğim diğer diller, sadece açıkça adlandırılmış bir tip kullanarak kavramı ele alıyor.


-1

Anahtar kelimeyi voidboş gibi düşünebilirsiniz struct( C99’da boş yapılar görünüşte izin verilmez , .NET ve C ++’ larda 0'dan fazla bellek kullanırlar ve en son Java’daki her şeyi hatırladım):

struct void {
};

... bu 0 uzunluklu bir tip demektir. voidBir tamsayı dönüş değeri için yığına 4 bayt ayırmak yerine ... döndüren bir işlev çağrısı yaptığınızda , yığın işaretçisini hiç değiştirmez (0 uzunluğuyla artırır) ).

Öyleyse, gibi bazı değişkenleri bildirirseniz:

int a;
void b;
int c;

... ve sonra belki o zaman, bu değişkenlerin adresini aldı bve cçünkü hafızada aynı yerde bulunan olabilir bsıfır uzunluğa sahiptir. Bu nedenle void*, a, sıfır uzunluklu yerleşik tipte bellekte bulunan bir işaretçidir. Bundan hemen sonra sizin için yararlı olabilecek bir şey olduğunu bilmeniz gerçeği başka bir konudur ve ne yaptığınızı (ve tehlikeli) gerçekten bilmenizi gerektirir.


Bunu bildiğim tek derleyici boşluğu yazmak için bir uzunluk atar gcc ve gcc de 1 uzunluğa atar.
Joshua
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.