Apa perbedaan antara variabel dan pointer?

10

Whist membaca sebuah artikel yang menguraikan perbedaan dalam pemrograman OO dan Fungsional. Saya menemukan pointer fungsi. Sudah lama sejak saya menyelesaikan gelar Ilmu Komputer saya (2003) dan jadi saya mencari petunjuk untuk menyegarkan ingatan saya.

Pointer adalah variabel yang berisi referensi ke alamat memori. Mereka dapat dianggap menunjuk ke data yang terkandung dalam alamat memori itu jika data tersebut ada. Atau, seperti dalam kasus di artikel, mereka mungkin menunjukkan titik masuk ke bagian kode dan dapat digunakan untuk memanggil kode itu.

Mengapa ini berbeda dari variabel? Variabel adalah nama simbolis untuk alamat memori dan kompiler akan mengganti nama dengan alamat yang sebenarnya. Ini berarti bahwa variabel berisi referensi ke lokasi memori dan dapat dianggap menunjuk ke data di alamat itu jika data tersebut ada.

Jika perbedaan dalam perilaku (mungkin pointer tidak dapat ditugaskan kembali pada saat runtime, atau hanya dapat diberi nama variabel simbolik, bukan nilai lain) bukankah itu berarti itu hanya variabel dari tipe tertentu, tipe pointer? Dengan cara yang sama variabel yang dideklarasikan sebagai tipe integer dibatasi oleh kompilasi untuk apa variabel itu dapat digunakan.

Apa yang kulewatkan di sini?

NectarSoft
sumber
4
Tidak ada, pointer secara efektif adalah tipe yang interpretasi semantiknya adalah bahwa isi variabel adalah alamat. Perhatikan tentu saja bahwa ada dua alamat, ada alamat penunjuk (yaitu tempat variabel disimpan) dan alamat penunjuk referensi (data aktual di alamat variabel). Pointer adalah jenis referensi .
Luke Mathieson

Jawaban:

8

Pertanyaan Anda menarik dalam beberapa cara, karena memerlukan pembedaan yang cermat untuk beberapa masalah. Tetapi visi Anda menurut saya pada dasarnya benar. Saya tidak membaca referensi Anda sebelum menulis sebagian besar jawaban ini untuk menghindari bias jawaban saya.

Pertama, pernyataan Anda Variables are symbolic names for memory addresses, itu hampir benar, tetapi membingungkan konsep dan implementasinya yang biasa. Variabel sebenarnya hanya sebuah wadah yang bisa berisi nilai yang bisa diubah. Biasanya, wadah ini diimplementasikan pada komputer sebagai bock ruang memori, ditandai oleh dan alamat dan ukuran karena variabel dapat berisi objek yang memerlukan representasi dengan informasi lebih atau kurang.

Tapi saya akan mempertimbangkan sebagian besar sudut pandang yang lebih abstrak dari semantik bahasa, terlepas dari teknik implementasi.

Jadi variabel hanyalah wadah dari sudut pandang abstrak. Wadah seperti itu tidak perlu memiliki nama. Namun, bahasa sering memiliki variabel yang dinamai dengan mengaitkannya sebagai pengenal, sehingga penggunaan variabel dapat diungkapkan oleh pengenal. Sebuah variabel sebenarnya dapat memiliki beberapa pengidentifikasi melalui berbagai mekanisme aliasing. Variabel juga bisa menjadi sub bagian dari variabel yang lebih besar: contohnya adalah sel variabel array, yang dapat dinamai dengan menentukan variabel array dan indeks sel, tetapi juga bisa juga dikaitkan dengan pengidentifikasi melalui aliasing.

Saya sengaja menggunakan wadah kata yang agak netral, untuk menghindari memanggil kata-kata lain yang mungkin secara teknis dimuat secara semantik. Ini sebenarnya dekat dengan konsep referensi yang dijelaskan dalam wilipedia , yang sering dikacaukan dengan alamat memori. Kata penunjuk itu sendiri sering dipahami sebagai alamat memori, tetapi saya tidak berpikir itu bermakna ketika mempertimbangkan sebagian besar bahasa tingkat tinggi, dan mungkin tidak sesuai dalam makalah diskusi yang Anda rujuk (meskipun alamat dapat digunakan), karena tidak tepat merujuk pada implementasi spesifik. Namun, itu sesuai untuk bahasa seperti C, yang seharusnya lebih dekat dengan konsep implementasi dan arsitektur mesin.

Sebenarnya, jika Anda melihat variabel atau nilai-nilai pada tingkat implementasi, mungkin ada beberapa sistem tipuan yang kompleks, "pointer level mesin", tetapi yang (dan harus) tidak terlihat oleh pengguna, sehingga sudut pandang abstrak Saya mengembangkan bisa valid. Untuk sebagian besar bahasa pemrograman, pengguna tidak perlu khawatir, atau bahkan tahu, tentang implementasi, karena implementasi dapat sangat bervariasi untuk bahasa tertentu. Ini mungkin tidak benar untuk beberapa bahasa, seperti C, yang sengaja dekat dengan arsitektur mesin, sebagai pengganti lanjutan untuk bahasa rakitan yang hampir berhubungan langsung dengan pengkodean biner eksplisit, tetapi tingkat yang terlalu rendah untuk penggunaan yang mudah di sebagian besar situasi.

Apa yang harus diketahui oleh pengguna bahasa, dan kadang-kadang lebih dari itu, adalah apa yang merupakan nilai dan operasi terkait, di mana mereka dapat terkandung, bagaimana mereka dapat dikaitkan dengan nama, cara kerja sistem penamaan, bagaimana cara baru jenis nilai didefinisikan, dll.

612

Asosiasi nilai yang tidak berubah dengan pengenal biasanya disebut konstanta. Litterals adalah konstanta dalam pengertian itu.

"Wadah nilai" juga dapat dianggap sebagai nilai, dan hubungannya dengan pengenal adalah variabel dalam arti "naif" yang biasa Anda gunakan. Jadi, Anda mungkin mengatakan bahwa variabel adalah "konstanta wadah".

Sekarang Anda mungkin bertanya-tanya apa perbedaan antara mengaitkan pengidentifikasi dengan nilai (deklarasi konstan) atau menetapkan nilai ke variabel, yaitu menyimpan nilai dalam wadah yang didefinisikan sebagai konstanta wadah. Pada dasarnya, deklarasi dapat dilihat sebagai operasi yang mendefinisikan notasi, yang mengaitkan pengenal yang merupakan entitas sintaksis dengan beberapa nilai yang merupakan entitas semantik. Tugas adalah operasi semantik murni yang mengubah keadaan, yaitu memodifikasi nilai wadah. Dalam beberapa hal, deklarasi adalah konsep meta tanpa efek semantik, selain menyediakan mekanisme penamaan (yaitu sintaksis) untuk entitas semantik.

Sebenarnya, penugasan adalah operasi semantik yang terjadi secara dinamis ketika program dieksekusi, sedangkan deklarasi memiliki sifat yang lebih sintaksis dan biasanya ditafsirkan dalam teks program, tidak tergantung pada eksekusi. Inilah sebabnya mengapa pelingkupan statis (yaitu pelingkupan tekstual) biasanya merupakan cara alami untuk memahami makna pengidentifikasi.

Setelah semua ini, saya dapat mengatakan bahwa nilai pointer hanyalah nama lain untuk sebuah wadah, dan variabel pointer adalah variabel wadah, yaitu wadah (konstan) yang dapat berisi wadah lain (dengan kemungkinan pembatasan pada permainan yang mengandung yang dikenakan oleh beberapa jenis sistem).

Mengenai kode, Anda menyatakan [pointers] might indicate the entry point to a section of code and can be used to call that code. Sebenarnya ini tidak sepenuhnya benar. Bagian kode sering tidak berarti sendirian (dari sudut pandang implementasi atau tingkat tinggi). Dari sudut pandang tingkat tinggi, kode biasanya berisi pengidentifikasi, dan Anda harus menafsirkan pengidentifikasi ini dalam konteks statis di mana mereka dideklarasikan. Tetapi sebenarnya ada duplikasi yang mungkin dari konteks statis yang sama, karena pada dasarnya rekursi yang merupakan fenomena dinamis (run-time), dan kode hanya dapat dieksekusi dalam contoh dinamis yang sesuai dari konteks statis. Ini agak rumit, tetapi konsekuensinya adalah bahwa konsep yang tepat adalah bahwa penutupan yang mengasosiasikan sepotong kode dan lingkungan di mana pengidentifikasi harus ditafsirkan. Penutupan adalah konsep semantik yang tepat, yaitu nilai semantik yang dapat didefinisikan dengan baik. Maka Anda dapat memiliki konstanta penutupan, variabel penutupan,

Fungsi adalah penutupan, biasanya dengan beberapa parameter untuk mendefinisikan atau menginisialisasi beberapa entitasnya (konstanta dan variabel).

Saya melewatkan banyak variasi dalam penggunaan mekanisme ini.

Penutupan dapat digunakan untuk mendefinisikan struktur OO dalam bahasa imperatif atau fungsional. Sebenarnya, pekerjaan awal pada gaya OO (mungkin sebelum nama) dilakukan dengan cara itu.

Makalah yang Anda referensi, yang saya skim dengan cepat, tampaknya menjadi yang menarik, ditulis oleh orang yang kompeten, tetapi mungkin bukan bacaan yang mudah jika Anda tidak memiliki pengalaman yang signifikan dengan berbagai bahasa dan model komputasi yang mendasarinya.

Tetapi ingat: banyak hal yang ada di mata yang melihatnya, selama dia mempertahankan pandangan yang konsisten. Sudut pandang mungkin berbeda.

Apakah ini menjawab pertanyaan Anda?

PS: Ini jawaban yang panjang. Jika Anda menganggap beberapa bagiannya tidak memadai, harap secara eksplisit tentang bagian mana itu. Terima kasih.

babou
sumber
Saya harus membacanya beberapa kali tetapi saya pikir itu menjawab pertanyaan saya, ya. Meskipun definisi saya terlalu implementasi sentris, gagasan bahwa penunjuk adalah jenis variabel tertentu tampaknya akurat, yaitu "nilai penunjuk hanyalah nama lain untuk wadah, dan variabel penunjuk adalah variabel wadah" Di mana saya tidak dapatkan perbedaan yang Anda buat adalah antara pointer yang berisi alamat blok kode dan menjadi wadah yang berisi kontainer yang berisi penutup. Apakah perbedaan antara konteks statis dan program dieksekusi?
NectarSoft
1
@NectarSoft Perbedaannya hanya antara blok kode dan penutupan. Yang saya katakan adalah, dengan sendirinya, terisolasi dari konteks apa pun, satu blok kode biasanya tidak berarti apa-apa. Jika saya katakan kepada Anda bahwa " jika mome raths lebih besar dari borogoves, maka jumlah yang lebih besar ", kalimat itu tidak berarti apa-apa karena Anda melewatkan konteks di mana semua konsep ini didefinisikan. Konteks statis ini biasanya berupa teks yang menyertakan fragmen kode. Masalahnya adalah bahwa konteks statis ini sendiri dapat memiliki beberapa contoh runtime, dan fragmen kode harus merujuk hanya satu dari mereka.
babou
1
@NectarSoft (lanjutan) Jadi nilai penutupan adalah asosiasi dari fragmen kode dan contoh dinamis dari konteks statis yang memberi makna pada fragmen ini. Asosiasi dari fragmen kode yang sama dengan instance dinamis yang berbeda dari konteks statis yang sama memberikan penutupan yang berbeda. Biasanya, kode Anda mungkin menggunakan variabel yang termasuk dalam konteks th, tetapi itu akan menjadi variabel yang berbeda untuk setiap instance dinamis konteks, meskipun namanya (yang ditentukan secara statis) tetap sama. Apakah ini mengklarifikasi masalah, atau haruskah saya membangun contoh dalam jawaban (format komentar dibatasi)?
babou
Itu mengklarifikasi masalah, terima kasih, sambil memunculkan pertanyaan lain yang saya akan menghabiskan waktu untuk berpikir. Misalnya, jika pointer berbeda diperlukan untuk setiap penutupan, sepertinya pointer menjadi bagian dari konteks dinamis dan oleh karena itu termasuk dalam penutupan! Saya juga bertanya-tanya tentang batas penutupan dan hirarki penutupan, karena masing-masing konteks ini terkait dengan blok kode statis dan direferensikan oleh pointer akan selalu menjadi variabel dalam penutupan sendiri. Semua ini di luar topik, jadi saya akan membaca dan mungkin mengajukan pertanyaan lain ketika saya macet sekali lagi
NectarSoft
@NectarSoft Sebenarnya. ketika Anda membangun penutupan, Anda mencoba membatasi konteks yang terkait dengan kode untuk apa yang diperlukan untuk memberikan makna yang tepat untuk kode itu (hingga beberapa kendala praktis untuk menghindari informasi pengelolaan mikro). Ini dapat diputuskan secara statis.
babou
2

Perbedaannya adalah dengan definisi dan aplikasi, pointer adalah variabel khusus untuk menyimpan alamat memori variabel lain; dalam istilah OO pointer mungkin akan dianggap mewarisi perilakunya dari kelas umum yang disebut variabel.

Ricardo
sumber