SORU
27 Kasım 2009, Cuma


C işaretçileri : sabit boyutlu bir dizi işaret

Bu soru C uzmanları oraya gider:

C: bir işaretçi bildirmek mümkündür

char (* p)[10];

bu işaretçi 10 karakter dizisi için puan o temelde Birleşik Devletleri .. Düzgün bir şey hakkında böyle bir işaretçi bildirmek bir p için farklı boyutta bir dizi için bir işaretçi atamak çalışırsanız, bir derleme zamanı hatası alırsınız. Ayrıca eğer basit bir char değişkenin değerini, p atamak çalışırsanız, derleme zamanı hatası verecektir. Gcc ile denedim ve ANSI C89 ve C99 ile iş gibi görünüyor.

Bu bir işlev için bir işaretçi geçirmeden çok yararlı, özellikle de olurdu gibi bir işaretçi bildirmek gibi görünüyor. Genellikle, insanlar bu gibi: böyle bir fonksiyon prototipi yazardı

void foo(char * p, int plen);

Eğer belirli bir boyuttaki bir arabelleği bekliyordun, sadece yeridir değerini test eder. Ancak, p geçer kişi gerçekten bu tampon içinde geçerli bellek konumlarını yeridir verecek sana garanti edemez. Bu işlev adlı kişinin doğru olanı yaptığını güvenmek zorundasın. Diğer taraftan:

void foo(char (*p)[10]);

..arayan belirttiğiniz boyutta bir tampon vermeye zorlayacaktır.

Bu çok yararlı gibi görünüyor ama hiç bir işaretçi hep bu şekilde karşılaştım ben herhangi bir kod ilan gördüm.

Benim soru şudur: insanlar böyle işaretçiler bildirmek değil herhangi bir neden var mı? Bariz bir hatadır göremiyorum?

Şimdiden teşekkürler

CEVAP
27 Kasım 2009, Cuma


Sonrası senin söylediğin kesinlikle doğru. () C dili ile yeterlilik belli bir seviyeye ulaşacaktır C geliştirici aynı keşif için geldiğini söyleyebilirim ve aynı sonuç.

Ne zaman özellikleri uygulama alanı aramak için bir dizi belirli sabit boyut (dizi boyutu bir derleme zamanı sabiti), yalnız bir şekilde geçirmek için böyle bir dizi için bir işlev kullanarak bir işaretçi-dizi parametre

void foo(char (*p)[10]);

(C dili bu da başvuruları ile yapılır

void foo(char (&p)[10]);

).

Bu düzey dil tam olarak doğru boyutta bir dizi bağımsız değişken olarak sağlanan emin olun hangi tür denetlemesini sağlayacaktır. Birçok durumda, aslında, insanlar dolaylı olarak bu tekniği, farkında bile olmadan, bir typedef ismi arkasında dizi türü gizleme kullanın

typedef int Vector3d[3];

void transform(Vector3d *vector);
/* equivalent to `void transform(int (*vector)[3])` */
...
Vector3d vec;
...
transform(&vec);

struct yukarıdaki kodu Vector3d ile ilgili olarak değişmeyen bu tür bir dizi olması ayrıca dikkat edin. struct ve geri bir dizi herhangi bir zamanda Vector3d tanımı geçiş yapabilirsiniz, ve işlevi bildirimi değiştirmek zorunda kalmazsınız. Her iki durumda da işlevlerini toplu bir nesne alacaksınız "başvurusu" (bu istisnalar vardır, ama bu tartışma kapsamında, bu doğrudur).

Ancak, görmeyeceksin bu yöntem geçirilmesi dizisi eskiden çok sık açıkça, basitçe, çünkü çok fazla insan karışıyor tarafından oldukça dolambaçlı sözdizimi ve sadece yeterli değil, böyle özellikleri olan C dilini kullanmak doğru. Ortalama gerçek hayatta bu nedenle, ilk öğe için bir işaretçi olarak bir dizi geçen daha popüler bir yaklaşımdır. Sadece görünüyor "" ... daha

Ama gerçekte, kullanarak işaretçiyi ilk öğenin bir dizi geçiyor bir çok niş tekniği, bir numara, servis çok özel amaç: onun için tek bir amaç için kolaylaştırmak geçen dizilerfarklı boyut(yani çalıştırma boyut). Eğer gerçekten ihtiyacınız etmek, süreci bir dizi çalışma zamanı boyutu, daha sonra düzgün bir şekilde aktarmak gibi bir dizi ile bir işaretçi ilk elemanı ile beton boyut tarafından sağlanan ek bir parametre

void foo(char p[], unsigned plen);

Aslında, birçok durumlarda çok kullanışlı ayrıca yöntemin popülaritesi katkıda çalıştırma boyutu dizileri, işlem yapabilmek için. C geliştiricileri sadece hiç (ya da hiç tanımak) sabit boyutlu bir dizi, böylece sabit boyutlu uygun tekniği kayıtsız kalan süreç için gereken birçok karşılaşma.

Eğer dizi boyutu sabit ise buna rağmen, bir öğe için bir işaretçi geçirmeden

void foo(char p[])

bir büyük ne yazık ki oldukça yaygın bu günlerde teknik düzeyde hata. İşaretçi-dizi tekniği bu gibi durumlarda çok daha iyi bir yaklaşımdır.

Sabit boyutlu dizi geçen tekniği kabulüne engel olabilecek başka bir neden dinamik olarak ayrılan bir dizi yazmak için naif yaklaşımın egemen olması. Eğer program türü sabit diziler için çağırırsa örneğin, char[10] (örnek olarak), ortalama geliştirici 25 ** Bu diziler gibi

char *p = malloc(10 * sizeof *p);

Bu dizi bir fonksiyonu olarak bildirilen geçirilemez

void foo(char (*p)[10]);

ortalama geliştirici karıştırır ve onları daha da bir düşünce vermeden sabit boyutlu parametre bildirimi terk yapar. Aslında, sorunun kökü malloc naif bir yaklaşım yatıyor. malloc biçimi yukarıda gösterilen çalıştırma boyutu dizileri için ayrılmalıdır. Eğer dizi türü derleme boyutu malloc daha iyi bir yolu varsa aşağıdaki gibi görünecektir

char (*p)[10] = malloc(sizeof *p);

Bu, tabii ki, kolayca yukarıdaki foo ilan geçebilir

foo(p);

ve derleyici doğru tür denetimi gerçekleştirir. Fakat yine de, bu "ortalama günlük kod. tipik olarak çok sık görmezsiniz yüzden hazırlıksız C bir geliştirici, fazlasıyla kafa karıştırıcı.

Bunu Paylaş:
  • Google+
  • E-Posta
Etiketler:

YORUMLAR

SPONSOR VİDEO

Rastgele Yazarlar

  • Karan Thakur

    Karan Thakur

    23 HAZİRAN 2010
  • LimeFire

    LimeFire

    2 ŞUBAT 2012
  • TheDroidDemos

    TheDroidDemo

    15 ŞUBAT 2011