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
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ı.
Nasıl Python biçiminde sabit genişlik ...
Nasıl PHP çok boyutlu bir dizi anahtar...
Taban işaretçisi türetilmiş nesneleri ...
Sözdizimi, iki boyutlu bir dizi oluştu...
Çok boyutlu bir dizi başlatma...