Diziler neden C'de işlev bağımsız değişkenleri olarak iletilemiyor?


12

Bu yorumu takiben neden Google'ı denemeye çalıştım ancak google-fu'm başarısız oldu.

Bağlantıdan yorum:

[...] Ama önemli olan şey, diziler ve işaretçiler C farklı şeyler olmasıdır.

Herhangi bir derleyici uzantısı kullanmadığınızı varsayarsak, genellikle bir dizinin kendisini bir işleve geçiremezsiniz, ancak bir işaretçiyi geçirebilir ve işaretçiyi bir diziymiş gibi dizinleyebilirsiniz.

İşaretçilerin uzunluğunun eklenmediğinden etkili bir şekilde şikayet ediyorsunuz. Dizilerin işlev bağımsız değişkenleri olarak iletilemeyeceğinden veya dizilerin işaretçilere dolaylı olarak bozulduğundan şikayet etmelisiniz.


Cevap olduğundan emin değilim, ancak bir dizi türünün boyutu onun boyutu, bu yüzden kabul etmek istediğiniz her boyut için bir işlev tanımlamak zorunda kalacağına inanıyorum.
clcto

Fonksiyon gösterici olarak mı demek istediniz ? Lütfen soruyu açıklayın.
user949300

2
@ user949300 Hayır, yorumun bağlamından oldukça açık; bir diziyi işleve geçiremezsiniz çünkü işaretçi olur ve neden böyle olduğunu bilmek ister.
Doval

@DocBrown rlemon bunun için bir düzenleme önerdi.
Florian Margaine

Yanıtlar:


18

Nedeni için ilk tahminim sadece performans ve bellek tasarrufu nedenlerinden ve derleyici uygulama kolaylığından kaynaklanıyordu (özellikle C'nin icat edildiği zamandaki bilgisayarlar için). Dev dizileri "değere göre" iletmek, yığın üzerinde büyük bir etkiye sahip gibi görünüyordu, her işlev çağrısı için tam dizi kopyalama işlemine ihtiyaç duyuyor ve muhtemelen derleyici doğru montaj kodunu çıkarmak için daha akıllı olmalı (son nokta tartışmalı olsa da) . Dinamik olarak tahsis edilmiş dizilere, statik olarak tahsis edilen dizilerle (dilin sözdizimi açısından) aynı şekilde davranılması daha zor olacaktır.

DÜZENLEME: Bu bağlantıdan bazı bölümleri okuduktan sonra , gerçek nedenin (ve yapılardaki dizilerin neden değer türleri olarak ele alınmasının nedeni, tek diziler olmasa da) C'nin selefi B ile geriye dönük uyumluluk olduğunu düşünüyorum . İşte Dennis Ritchie'den alıntı:

[...} Çözüm, tipsiz BCPL ile C tipi arasındaki evrim zincirindeki önemli sıçramayı oluşturdu. İşaretçinin depodaki maddileşmesini ortadan kaldırdı ve bunun yerine bir ifadede dizi adı belirtildiğinde işaretçinin oluşturulmasına neden oldu. Bugünün C'sinde hayatta kalan kural, dizi türü değerlerinin ifadelerde göründüklerinde diziyi oluşturan nesnelerin ilkine işaretçiler haline dönüştürülmesidir.

Bu buluş, dilin anlambilimindeki temel kaymaya rağmen, mevcut çoğu B kodunun çalışmaya devam etmesini sağlamıştır. [..]


5
Bir struct Foo { int array[N]; } olabilir değer geçirilecek. Ve dinamik ve statik tahsisleri tedavi konusunda son bit aynı balık (sağın anlamında bir dizi her zaman bir boyut, dizi endeksleme gibi şeyler vardır için birleştirici kavramları içermektedir görünüyor işaretçileri size ayrıntılı olabilir, dizi-to-pointer çürüme ile birleştiğinde)?

@delnan: Bence burada belirtilen genel ilkeler sağlam. Açıkça, dizinizi bir yapıya sarırsanız, niyetinizi belirtirsiniz. Genel durumda, neredeyse her zaman referans olarak geçersiniz.
Robert Harvey

Ayrıca gereksiz yere bilgiçlikle ilgili olarak atıfta bulunulan yorumu da buldum. Açıkça, değere göre bir dizi yerine bir işaretçi geçiriyorsunuz. Yine de eşit derecede doğru olan, bir diziyi referans olarak etkili bir şekilde geçirmenizdir. Eğer itiraz uzunluğa bağlı değilse, bunu geçmek de yeterince kolaydır.
Robert Harvey

Her şey dizi tipleri (hatta bir yapı türü bir parçası olan diziler olsa haricinde değeri tarafından geçirilir: @RobertHarvey hala tip sistemindeki bir asimetri That olan değere göre iletilmiş) ve hatta çağrı yerinde aynı notasyonu (hem kullanır ve işlev imzasında).

@delnan: Hatırlamanız gerekenden başka neden önemli?
Robert Harvey

9

Yalnızca 8 kB belleğe sahip bir PDP mini bilgisayar çok büyük bir yığın ayıramaz. Bu nedenle, böyle bir makinede, beklenen ortak altyordam çağrısı kullanımı için yığın üzerinde neler yapılması gerektiğini en aza indirgemek için bir dil tasarımına (veya evrimine) dikkat etmek gerekir. C bugün hala son derece bellek kısıtlamalı (birkaç kB) gömülü sistemleri programlamak için kullanılmaktadır, bu nedenle takas genellikle iyi bir sistemdir.

Çok az sayıda kaydın bulunduğu bir işlemci mimarisinde, bir diziyi değere göre değil, işaretçiye göre daha sık geçirmek, bir kaydın alt rutin çağrı optimizasyonu olarak kullanılmasına izin verir.


2
Veri için 256 bayt RAM ve kod için 2K EEPROM olan bazı panoları var. Orada bir dizinin kopyasını oluşturmak istemezsiniz.
Jerry Jeremiah
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.