Apa yang Anda katakan di postingan Anda benar sekali. Saya akan mengatakan bahwa setiap pengembang C sampai pada penemuan yang persis sama dan pada kesimpulan yang persis sama ketika (jika) mereka mencapai tingkat kemahiran tertentu dengan bahasa C.
Ketika spesifikasi area aplikasi Anda memanggil larik dengan ukuran tetap tertentu (ukuran larik adalah konstanta waktu kompilasi), satu-satunya cara yang tepat untuk meneruskan larik tersebut ke suatu fungsi adalah dengan menggunakan parameter penunjuk-ke-larik
void foo(char (*p)[10]);
(dalam bahasa C ++ ini juga dilakukan dengan referensi
void foo(char (&p)[10]);
).
Ini akan mengaktifkan pemeriksaan tipe tingkat bahasa, yang akan memastikan bahwa larik dengan ukuran yang benar-benar tepat disediakan sebagai argumen. Faktanya, dalam banyak kasus orang menggunakan teknik ini secara implisit, bahkan tanpa menyadarinya, menyembunyikan tipe array di belakang nama typedef.
typedef int Vector3d[3];
void transform(Vector3d *vector);
/* equivalent to `void transform(int (*vector)[3])` */
...
Vector3d vec;
...
transform(&vec);
Perhatikan juga bahwa kode di atas adalah invariant dengan relasi ke Vector3d
tipe menjadi array atau a struct
. Anda dapat mengganti definisi Vector3d
kapan saja dari array ke a struct
dan kembali, dan Anda tidak perlu mengubah deklarasi fungsi. Dalam kedua kasus, fungsi akan menerima objek gabungan "dengan referensi" (ada pengecualian untuk ini, tetapi dalam konteks diskusi ini hal ini benar).
Namun, Anda tidak akan melihat metode pengoperan array ini terlalu sering digunakan secara eksplisit, hanya karena terlalu banyak orang yang bingung dengan sintaks yang agak berbelit-belit dan tidak cukup nyaman dengan fitur bahasa C seperti itu untuk menggunakannya dengan benar. Karena alasan ini, dalam kehidupan nyata rata-rata, meneruskan array sebagai penunjuk ke elemen pertamanya adalah pendekatan yang lebih populer. Itu hanya terlihat "lebih sederhana".
Tetapi pada kenyataannya, menggunakan pointer ke elemen pertama untuk pengoperan array adalah teknik yang sangat khusus, sebuah trik, yang melayani tujuan yang sangat spesifik: satu-satunya tujuannya adalah untuk memfasilitasi lintasan yang lewat dengan ukuran yang berbeda (yaitu ukuran run-time) . Jika Anda benar-benar harus dapat memproses array ukuran run-time, maka cara yang tepat untuk meneruskan array tersebut adalah dengan pointer ke elemen pertamanya dengan ukuran konkret yang disediakan oleh parameter tambahan.
void foo(char p[], unsigned plen);
Sebenarnya, dalam banyak kasus, sangat berguna untuk dapat memproses array ukuran run-time, yang juga berkontribusi pada popularitas metode. Banyak pengembang C tidak pernah menemukan (atau tidak pernah mengenali) kebutuhan untuk memproses array ukuran tetap, sehingga tetap tidak menyadari teknik ukuran tetap yang tepat.
Namun demikian, jika ukuran array tetap, meneruskannya sebagai pointer ke elemen
void foo(char p[])
adalah kesalahan tingkat teknik utama, yang sayangnya agak meluas akhir-akhir ini. Teknik pointer-to-array adalah pendekatan yang jauh lebih baik dalam kasus seperti itu.
Alasan lain yang mungkin menghalangi pengadopsian teknik passing larik ukuran tetap adalah dominasi pendekatan naif untuk pengetikan larik yang dialokasikan secara dinamis. Misalnya, jika program memanggil array tipe tetap char[10]
(seperti dalam contoh Anda), rata-rata pengembang akan malloc
seperti array seperti
char *p = malloc(10 * sizeof *p);
Larik ini tidak dapat diteruskan ke fungsi yang dideklarasikan sebagai
void foo(char (*p)[10]);
yang membingungkan developer rata-rata dan membuat mereka meninggalkan deklarasi parameter ukuran tetap tanpa memikirkannya lebih lanjut. Namun kenyataannya, akar masalahnya terletak pada malloc
pendekatan yang naif . The malloc
Format yang ditunjukkan di atas harus disediakan untuk array ukuran run-time. Jika tipe array memiliki ukuran waktu kompilasi, cara yang lebih baik untuk malloc
itu akan terlihat sebagai berikut
char (*p)[10] = malloc(sizeof *p);
Ini, tentu saja, dapat dengan mudah diteruskan ke pernyataan di atas foo
foo(p);
dan kompilator akan melakukan pemeriksaan jenis yang benar. Tetapi sekali lagi, ini terlalu membingungkan bagi pengembang C yang tidak siap, itulah sebabnya Anda tidak akan melihatnya terlalu sering dalam kode harian rata-rata yang "biasa".
10
dapat diganti dengan variabel apa pun dalam cakupan