Karena Anda baru belajar C, saya sarankan Anda untuk benar-benar mencoba memahami perbedaan antara array dan pointer terlebih dahulu daripada hal - hal umum .
Di bidang parameter dan array, ada beberapa aturan membingungkan yang harus jelas sebelum melanjutkan. Pertama, apa yang Anda nyatakan dalam daftar parameter diperlakukan istimewa. Ada beberapa situasi di mana hal-hal yang tidak masuk akal sebagai parameter fungsi dalam C. Ini adalah
- Berfungsi sebagai parameter
- Array sebagai parameter
Array sebagai parameter
Yang kedua mungkin tidak segera jelas. Tetapi menjadi jelas ketika Anda menganggap bahwa ukuran dimensi array adalah bagian dari tipe C (dan array yang ukuran dimensi tidak diberikan memiliki tipe tidak lengkap). Jadi, jika Anda ingin membuat fungsi yang mengambil array dengan nilai (menerima salinan), maka itu bisa dilakukan hanya untuk satu ukuran! Selain itu, array dapat menjadi besar, dan C mencoba untuk menjadi secepat mungkin.
Di C, karena alasan ini, nilai array tidak ada. Jika Anda ingin mendapatkan nilai array, yang Anda dapatkan adalah pointer ke elemen pertama array itu. Dan di sini sebenarnya sudah ada solusinya. Alih-alih menggambar parameter array tidak valid di muka, kompiler C akan mengubah tipe parameter masing-masing menjadi pointer. Ingat ini, ini sangat penting. Parameter tidak akan menjadi array, melainkan akan menjadi pointer ke tipe elemen masing-masing.
Sekarang, jika Anda mencoba untuk melewatkan sebuah array, apa yang diteruskan adalah sebuah pointer ke elemen pertama array.
Ekskursi: Berfungsi sebagai parameter
Untuk penyelesaiannya, dan karena saya pikir ini akan membantu Anda lebih memahami masalah ini, mari kita lihat seperti apa keadaannya saat Anda mencoba memiliki fungsi sebagai parameter. Memang, pertama tidak masuk akal. Bagaimana suatu parameter bisa berfungsi? Huh, tentu saja kami menginginkan variabel di tempat itu! Jadi apa yang dilakukan kompiler ketika itu terjadi adalah, sekali lagi, untuk mengubah fungsi menjadi sebuah fungsi pointer . Mencoba untuk melewatkan suatu fungsi akan meneruskan sebuah pointer ke fungsi masing-masing sebagai gantinya. Jadi, berikut ini sama (analog dengan contoh array):
void f(void g(void));
void f(void (*g)(void));
Perhatikan bahwa tanda kurung *g
diperlukan. Jika tidak, itu akan menentukan fungsi yang kembali void*
, bukan penunjuk ke fungsi yang kembali void
.
Kembali ke array
Sekarang, saya katakan di awal bahwa array dapat memiliki tipe yang tidak lengkap - yang terjadi jika Anda belum memberi ukuran. Karena kita sudah mengetahui bahwa parameter array tidak ada tetapi parameter array adalah pointer, ukuran array tidak menjadi masalah. Itu artinya, kompiler akan menerjemahkan semua hal berikut, dan semuanya adalah hal yang sama:
int main(int c, char **argv);
int main(int c, char *argv[]);
int main(int c, char *argv[1]);
int main(int c, char *argv[42]);
Tentu saja, tidak masuk akal untuk dapat menempatkan ukuran apa pun di dalamnya, dan itu hanya dibuang begitu saja. Karena alasan itu, C99 memunculkan makna baru untuk angka-angka itu, dan memungkinkan hal-hal lain muncul di antara tanda kurung:
// says: argv is a non-null pointer pointing to at least 5 char*'s
// allows CPU to pre-load some memory.
int main(int c, char *argv[static 5]);
// says: argv is a constant pointer pointing to a char*
int main(int c, char *argv[const]);
// says the same as the previous one
int main(int c, char ** const argv);
Dua baris terakhir mengatakan bahwa Anda tidak akan dapat mengubah "argv" dalam fungsi - itu telah menjadi pointer const. Hanya beberapa kompiler C yang mendukung fitur-fitur C99 itu. Tetapi fitur-fitur ini memperjelas bahwa "array" sebenarnya bukan satu. Ini sebuah pointer.
Sebuah kata peringatan
Perhatikan bahwa semua yang saya katakan di atas hanya benar ketika Anda sudah mendapatkan array sebagai parameter fungsi. Jika Anda bekerja dengan array lokal, array tidak akan menjadi pointer. Ini akan berperilaku sebagai pointer, karena seperti yang dijelaskan sebelumnya sebuah array akan dikonversi menjadi sebuah pointer ketika nilainya dibaca. Tapi jangan sampai bingung dengan pointer.
Salah satu contoh klasik adalah sebagai berikut:
char c[10];
char **c = &c; // does not work.
typedef char array[10];
array *pc = &c; // *does* work.
// same without typedef. Parens needed, because [...] has
// higher precedence than '*'. Analogous to the function example above.
char (*array)[10] = &c;