Saya baru-baru ini senang menjelaskan pointer ke pemula pemrograman C dan menemukan kesulitan berikut. Mungkin tidak tampak seperti masalah sama sekali jika Anda sudah tahu cara menggunakan pointer, tetapi cobalah untuk melihat contoh berikut dengan pikiran yang jernih:
int foo = 1;
int *bar = &foo;
printf("%p\n", (void *)&foo);
printf("%i\n", *bar);
Bagi pemula absolut hasilnya mungkin mengejutkan. Pada baris 2 dia baru saja menyatakan * bar sebagai & foo, tetapi pada baris 4 ternyata * bar sebenarnya foo bukan & foo!
Kebingungan, Anda mungkin mengatakan, berasal dari ambiguitas simbol *: Pada baris 2 digunakan untuk mendeklarasikan pointer. Pada baris 4 digunakan sebagai operator unary yang mengambil nilai titik penunjuk. Dua hal yang berbeda, bukan?
Namun, "penjelasan" ini sama sekali tidak membantu pemula. Ini memperkenalkan konsep baru dengan menunjukkan perbedaan yang halus. Ini bukan cara yang tepat untuk mengajarkannya.
Jadi, bagaimana Kernighan dan Ritchie menjelaskannya?
Operator unary * adalah operator tipuan atau dereferencing; ketika diterapkan pada sebuah pointer, ia mengakses objek yang ditunjuk oleh pointer itu. [...]
Deklarasi pointer ip,
int *ip
dimaksudkan sebagai mnemonik; dikatakan bahwa ekspresinya*ip
adalah int. Sintaks deklarasi untuk variabel meniru sintaks ekspresi di mana variabel mungkin muncul .
int *ip
harus dibaca seperti " *ip
akan mengembalikan sebuah int
"? Tetapi mengapa kemudian penugasan setelah deklarasi tidak mengikuti pola itu? Bagaimana jika seorang pemula ingin menginisialisasi variabel? int *ip = 1
(baca: *ip
akan mengembalikan int
dan int
is 1
) tidak akan berfungsi seperti yang diharapkan. Model konseptual sepertinya tidak koheren. Apakah saya melewatkan sesuatu di sini?
Sunting: Ini mencoba merangkum jawaban di sini .
*
dalam sebuah deklarasi adalah makna token "menyatakan pointer", dalam ekspresi itu adalah operator dereference, dan bahwa keduanya mewakili hal-hal berbeda yang kebetulan memiliki simbol yang sama (sama seperti operator perkalian - simbol yang sama, makna yang berbeda). Ini membingungkan, tetapi sesuatu yang berbeda dari keadaan sebenarnya akan menjadi lebih buruk.
int* bar
membuatnya lebih jelas bahwa bintang itu sebenarnya bagian dari tipe, bukan bagian dari pengenal. Tentu saja ini membawa Anda ke masalah yang berbeda dengan hal-hal yang tidak intuitif seperti int* a, b
.
*
dapat memiliki dua arti berbeda tergantung pada konteksnya. Sama seperti huruf yang sama dapat diucapkan berbeda tergantung pada kata itu di mana membuatnya sulit untuk belajar berbicara banyak bahasa. Jika setiap konsep / operasi memiliki simbolnya sendiri, kita akan membutuhkan keyboard yang lebih besar, jadi simbol tersebut didaur ulang ketika masuk akal untuk melakukannya.
int* p
), sembari memperingatkan siswa Anda agar tidak menggunakan banyak deklarasi di baris yang sama ketika pointer terlibat. Ketika siswa telah sepenuhnya memahami konsep pointer, jelaskan kepada siswa bahwa int *p
sintaks is adalah setara dan kemudian jelaskan masalahnya dengan beberapa deklarasi.