Apa perbedaan antara variabel dan lokasi memori? [Tutup]

38

Baru-baru ini saya mencoba menjelaskan pointer dengan cara visual, sebagai kartu flash.

Pertanyaan 001: Ini adalah gambar lokasi di memori komputer. Benarkah alamatnya 0x23452? Mengapa?

masukkan deskripsi gambar di sini

Jawab: Ya, karena 0x23452menjelaskan di mana komputer dapat menemukan lokasi ini.


Pertanyaan 002: Benarkah karakter bitu disimpan di dalam lokasi memori 0x23452? Mengapa?

masukkan deskripsi gambar di sini

Jawab: Tidak, karena karakter asebenarnya tersimpan di dalamnya.


Pertanyaan 003: Benarkah pointer disimpan di dalam lokasi memori 0x23452? Mengapa?

masukkan deskripsi gambar di sini

Jawab: Ya, karena alamat lokasi memori 0x34501tersimpan di dalamnya.


Pertanyaan 004: Benarkah pointer disimpan di dalam lokasi memori 0x23452? Mengapa?

masukkan deskripsi gambar di sini

Jawab: Ya, karena alamat lokasi memori lain disimpan di dalamnya.


Sekarang untuk bagian yang membuat saya khawatir. Seorang insinyur perangkat lunak menjelaskan petunjuk kepada saya seperti ini:

Pointer adalah variabel yang nilainya adalah alamat memori variabel lain.

Berdasarkan empat kartu flash yang saya tunjukkan pada Anda semua, saya akan mendefinisikan pointer dengan cara yang sedikit berbeda:

Pointer adalah lokasi memori yang nilainya adalah alamat memori lokasi memori lain.

Apakah aman untuk mengatakan bahwa suatu variabel sama dengan lokasi memori?

Jika tidak, lalu siapa yang benar? Apa perbedaan antara variabel dan lokasi memori?

keturunan
sumber
37
Ada asumsi implisit di sini bahwa setiap orang membaca foto-foto akan tahu Anda maksud bahwa jumlah heksadesimal bawah kotak adalah alamat memori, dan bahwa a, 0x23453. nildll barang-barang di dalamnya adalah nilai-nilai. Itu mungkin tampak jelas bagi Anda, tetapi saya tidak akan merasa nyaman memberikan jawaban tegas untuk pertanyaan-pertanyaan itu tanpa melihat bagaimana bidang-bidang itu didefinisikan. Benar-benar tidak ada cara untuk mengetahui apakah apada gambar kedua adalah karakter, string (jika mereka berbeda), atau nama variabel. Jika itu adalah string, maka apakah niljuga string? Atau nilai "null"?
ilkkachu
39
Pertanyaan 1 adalah pertanyaan yang buruk. Itu adalah sesuatu yang perlu Anda sampaikan kepada pembaca sebelum mereka dapat menjawab pertanyaan lain. Alih-alih sebuah pertanyaan, itu seharusnya informasi yang diberikan kepada pembaca: "Dalam pertanyaan berikut, kotak adalah lokasi memori dan nomor hex di bawahnya adalah alamat mereka".
17 dari 26
15
Pertanyaan 3 tidak mungkin dijawab mengingat konteksnya. Tidak ada cara untuk mengetahui pada tingkat byte bagaimana nilai yang disimpan dalam memori ditafsirkan / digunakan pada tingkat aplikasi.
17 dari 26
6
Patut dicatat: semua yang Anda tulis di sini benar untuk C atau C ++ tetapi salah pada dasarnya bahasa apa pun yang tidak memiliki referensi / dereferensi pointer eksplisit. Seluruh metafora variabel menjadi slot yang nilainya dimasukkan ke dalam suatu bahasa (seperti Python, atau Java, atau C #, atau Ruby, atau JavaScript, atau banyak lainnya) di mana tugas hanya membuat variabel menunjuk ke suatu objek tanpa menyalinnya , dan mutasi ke objek terlihat melalui semua variabel yang menunjuk padanya. Dokumentasi Python menggunakan metafora variabel alternatif sebagai papan nama yang tergantung pada objek karena alasan ini.
Mark Amery
19
BTW, dan maafkan saya jika Anda sudah mengerti ini, tetapi sepertinya ini mungkin menjadi titik kebingungan - notasi "0x23452" ini hanyalah cara untuk menunjukkan angka dalam format heksadesimal, dan itu dilakukan hanya untuk kenyamanan. Tapi itu hanya angka - awalan 0x sama sekali tidak menunjukkan bahwa itu adalah pointer, apa yang disimpan dalam memori secara harfiah hanya angka yang tidak berarti (Anda bisa memberi label lokasi memori dengan bilangan bulat desimal polos). Arti (yaitu, bagaimana angka harus ditafsirkan) berasal dari bahasa - jenis variabel & cara itu digunakan.
Filip Milovanović

Jawaban:

69

Variabel adalah konstruk logis yang mengarah ke maksud suatu algoritma, sedangkan lokasi memori adalah konstruk fisik yang menggambarkan operasi komputer. Secara umum, untuk menjalankan program ada pemetaan (kompiler dihasilkan) antara gagasan logis dari variabel dan penyimpanan komputer.

(Bahkan dalam bahasa assembly kami memiliki gagasan tentang variabel (logis) pergi ke algoritma dan niat, dan lokasi memori (fisik), meskipun mereka lebih digabungkan dalam perakitan.)

Variabel adalah konsep tingkat tinggi (er). Variabel mewakili salah satu yang tidak diketahui (seperti dalam matematika, atau tugas pemrograman) atau place-holder yang dapat diganti dengan nilai (seperti dalam pemrograman: parameter).

Lokasi memori adalah konsep level rendah (er). Lokasi memori dapat digunakan untuk menyimpan nilai, kadang-kadang, untuk menyimpan nilai variabel. Namun, register CPU adalah cara lain untuk menyimpan nilai beberapa variabel. Register CPU juga merupakan lokasi penyimpanan level rendah (er), tetapi mereka bukan lokasi memori karena mereka tidak memiliki alamat, hanya nama.

Dalam beberapa hal, variabel adalah mekanisme abstraksi untuk mengekspresikan maksud program, sedangkan lokasi memori adalah entitas fisik dari lingkungan pemrosesan yang menyediakan penyimpanan & pengambilan.

Pertanyaan 003: Benarkah pointer disimpan di dalam lokasi memori 0x23452? Mengapa?

Kita tidak bisa mengatakan sebelumnya. Hanya karena ada nilai di sana yang akan berfungsi sebagai alamat, bukan berarti alamat itu, itu bisa berupa bilangan bulat (desimal) 144466, sebagai gantinya. Kami tidak dapat membuat asumsi pada interpretasi nilai hanya berdasarkan pada bagaimana mereka muncul secara numerik.

Pertanyaan 004: Benarkah pointer disimpan di dalam lokasi memori 0x23452? Mengapa?

Ini memang pertanyaan aneh. Namun mereka mengharapkan beberapa asumsi berdasarkan kotak, mari kita perhatikan bahwa alamat bertambah 1 untuk setiap kotak. Di komputer modern mana pun, itu berarti bahwa setiap kotak dapat menampung kemampuan byte byte telah menjadi norma selama beberapa dekade sekarang. Namun byte hanya 8-bit dan dapat berkisar dari 0 hingga 255 (untuk nilai yang tidak ditandatangani); namun mereka menunjukkan nilai yang jauh lebih besar disimpan dalam salah satu alamat ini, sangat mencurigakan. (Ini bisa bekerja jika ini adalah mesin yang ditujukan untuk kata-kata, tetapi tidak dikatakan demikian, dan, beberapa mesin saat ini, meskipun beberapa mesin pendidikan begitu.)

Berdasarkan empat kartu flash yang saya tunjukkan pada Anda semua, saya akan mendefinisikan pointer dengan cara yang sedikit berbeda:

Pointer adalah lokasi memori yang nilainya adalah alamat memori lokasi memori lain.

Meskipun ada situasi di mana pemikiran ini benar, Anda mencampur metafora di sini. Gagasan suatu variabel mengarah ke algoritma dan tujuannya - tidak perlu mengasumsikan semua variabel memiliki lokasi memori. Beberapa variabel (terutama array) memiliki lokasi memori karena lokasi memori mendukung pengalamatan (sedangkan register CPU hanya bisa dinamai tidak diindeks).

Untuk eksekusi, ada pemetaan logis antara variabel & pernyataan dan lokasi memori prosesor & urutan instruksi prosesor. Variabel yang nilainya tidak pernah berubah (misalnya konstanta) bahkan tidak perlu memerlukan lokasi memori, karena nilainya dapat direproduksi sesuka hati (mis. Sesuai kebutuhan untuk urutan kode yang dihasilkan oleh kompiler).

Erik Eidt
sumber
4
Dan bahkan byte 8-bit masih belum universal.
Deduplicator
14
@ JimmyJames Pertimbangkan kasus forindeks loop ketika kompiler memutuskan untuk membuka gulungan sepenuhnya. Tidak ada dalam kode output yang dihasilkan (baik itu kode perakitan atau mesin atau kode byte) ada lokasi memori di mana penghitung loop disimpan. Tapi itu masih variabel.
dmckee
4
@JimmyJames, Dalam kasus pointer loop yang tidak dikontrol, maka ya, jika kode Anda benar-benar menggunakan nilai penghitung, maka harus dimuat di suatu tempat , tetapi (a) tempat itu bisa menjadi register, dan (b) tidak ada alasan pada prinsipnya mengapa itu harus menjadi lokasi yang sama pada setiap iterasi dari loop yang belum dibuka.
Solomon Slow
3
Jika loop melakukan sesuatu seperti menyalin array panjang tetap sourceke array sama panjang destloop dikodekan for (int i=0; i<8; ++i) dest[i] = source[i];juga mungkin mengkompilasi ke sesuatu yang setara dengan pengulangan dest++ = source++;jumlah yang tepat kali. Dengan penghitung lingkaran itu sendiri tidak ada dalam bukti (bahkan dalam register), dan hanya jumlah pengulangan yang memberitahu Anda tentang kondisi loop.
dmckee
2
Perbedaannya agak dikacaukan oleh bahasa-bahasa seperti C yang semantiknya berdasarkan pada abstraksi mesin yang ingatannya terdiri dari lokasi-lokasi bernomor.
Michael Kay
20

Apakah aman untuk mengatakan bahwa suatu variabel sama dengan lokasi memori?

Tidak. Variabel dan lokasi memori adalah dua abstraksi pada dua tingkat abstraksi yang berbeda. Variabel dan pointer adalah konsep level yang lebih tinggi pada level kode / bahasa, lokasi memori adalah konsep level yang lebih rendah pada level mesin. Setelah kode dikompilasi menjadi executable, tidak ada lagi variabel. Mencoba berbicara tentang lokasi memori dan variabel dengan cara ini adalah kesalahan kategoris.

Variabel dapat diimplementasikan menggunakan memori, tetapi tidak selalu karena kompiler dapat mengoptimalkan perhitungan dan melakukan semua perhitungan yang berkaitan dengan variabel sepenuhnya dalam register, atau dapat menempatkan variabel tunggal ke beberapa lokasi memori, atau dapat menggunakan memori tunggal lokasi untuk beberapa variabel.

Pointer adalah lokasi memori yang nilainya adalah alamat memori lokasi memori lain.

Rangkaian kartu flash ini sangat membingungkan, mereka tidak hanya tidak benar, tetapi mereka bahkan tidak salah.

Lie Ryan
sumber
1
Once a code had been compiled into an executable, there's no longer any variables.Itu adalah sesuatu yang saya tidak setuju dengan. Benar bahwa variabel Anda seperti yang Anda kenal (yaitu dengan nama itu) tidak ada lagi, tetapi frasa Anda tampaknya menyarankan bahwa executable yang dikompilasi hanya menggunakan alamat memori. Itu tidak benar. File executable yang dikompilasi-tetapi-tidak-dieksekusi tidak tahu alamat memori yang akan digunakan ketika dieksekusi. Konsep variabel (yaitu referensi yang dapat digunakan kembali ke alamat memori mana pun yang akan ditetapkan saat runtime) masih ada di dalam executable yang dikompilasi.
Flater
2
Atau kompiler dapat mengoptimalkan variabel sepenuhnya, dengan berbagai cara. Pra-komputasi sesuatu, pangkas variabel yang tidak perlu. Jika variabel adalah konstanta, maka kompiler dapat berakhir menggunakan instruksi CPU yang menggunakan konstanta, dan saya berpendapat bahwa itu tidak lagi dianggap sebagai variabel yang ada di mana saja.
kutschkem
16

Variabel adalah konstruksi bahasa . Mereka memiliki nama, berada dalam lingkup, dapat dirujuk oleh bagian lain dari kode, dll. Mereka adalah entitas yang logis . Kompiler bebas untuk mengimplementasikan konstruksi bahasa ini dengan cara apa pun yang diinginkan, selama perilaku yang dapat diamati adalah yang ditentukan oleh standar bahasa. Dengan demikian, variabel bahkan tidak perlu disimpan di mana pun jika kompiler dapat membuktikan bahwa itu tidak diperlukan.

Lokasi memori adalah konsep perangkat keras . Mereka menandakan tempat dalam memori virtual / fisik. Setiap lokasi memori memiliki tepat satu alamat fisik dan sejumlah alamat virtual yang dapat digunakan untuk memanipulasinya. Tetapi selalu ada persis satu byte yang disimpan di setiap lokasi memori.

Pointer adalah jenis nilai khusus . Mengatakan sesuatu adalah pointer sama dengan mengatakan sesuatu itu tipe double. Ini menandakan berapa banyak bit yang digunakan untuk nilai, dan bagaimana bit-bit itu diinterpretasikan, tetapi itu tidak berarti bahwa nilai ini disimpan dalam variabel, juga tidak berarti bahwa nilai ini disimpan dalam memori.


Untuk memberikan contoh dalam C: Ketika saya memiliki array 2D int foo[6][7];dan saya mengakses elemen itu foo[1][2], maka fooadalah variabel yang menyimpan array. Ketika foodigunakan dalam konteks ini, itu berubah menjadi pointer ke elemen pertama dari array. Pointer ini tidak disimpan dalam variabel apa pun, juga tidak disimpan dalam memori, nilainya hanya dihasilkan dalam register CPU, digunakan, dan kemudian dilupakan. Demikian juga, ekspresi foo[1]diubah menjadi pointer lain dalam konteks ini, yang, sekali lagi, bukan dalam variabel, tidak disimpan dalam memori, tetapi dihitung dalam CPU, digunakan, dan dilupakan. Variabel tiga konsep , lokasi memori , dan penunjuk adalah tiga konsep yang berbeda.


Btw, saya benar-benar berarti "selalu ada persis satu byte yang disimpan di setiap lokasi memori". Ini tidak terjadi pada zaman batu komputasi sekitar lima puluh tahun yang lalu, tetapi memang benar untuk hampir semua perangkat keras yang digunakan saat ini. Setiap kali Anda menyimpan nilai dalam memori yang lebih besar dari satu byte, Anda sebenarnya menggunakan sejumlah lokasi memori yang berurutan. Yaitu (dengan asumsi pesanan byte besar endian) nomor 0x01234567 disimpan dalam memori sebagai

+------+------+------+------+
| 0x01 | 0x23 | 0x45 | 0x67 |
+------+------+------+------+
    ^      ^      ^      ^
    |      |      |      |
 0x4242 0x4243 0x4244 0x4245

(Mesin endian kecil seperti arsitektur X86 menyimpan byte dalam urutan terbalik.) Ini juga berlaku untuk pointer: Pointer pada mesin 64 bit disimpan dalam delapan byte berturut-turut, masing-masing dengan alamat memori sendiri. Anda tidak dapat melihat sel memori dan berkata: "Oh, ini pointer!" Anda selalu hanya melihat byte ketika Anda melihat memori .

cmaster
sumber
Bagaimana komputer tahu kapan sekelompok lokasi memori berurutan dimulai dan berakhir?
progner
6
@progner Tidak. Ini mengartikan byte dalam memori sesuai dengan instruksi yang didapatnya. Instruksi-instruksi itu juga disimpan hanya dalam urutan byte itu sendiri. Untuk CPU, satu-satunya perbedaan antara byte yang menyimpan instruksi, byte yang menampung karakter, dan byte yang menampung bit floating point, adalah bagaimana ia diinstruksikan untuk menggunakan byte ini. Jika byte diambil karena penghitung program menunjuk ke sana, byte tersebut digunakan sebagai instruksi. Jika itu diambil karena instruksi mengatakan untuk memuatnya ke register float, itu digunakan sebagai data floating point.
cmaster
7
@progner Itu sebenarnya inovasi kunci arsitektur von-Neuman: Untuk menyimpan instruksi dan data dalam memori yang sama, memungkinkan instruksi untuk mengubah data yang kemudian dieksekusi sebagai instruksi lainnya. Ini memungkinkan kode modifikasi diri, tetapi juga memungkinkan kernel sistem untuk memuat beberapa program ke dalam memori, dan kemudian memberitahu CPU untuk menjalankan program itu. Sebelum von-Neuman, komputer seperti mesin Zuse akan mendapatkan instruksi mereka melalui saluran yang sepenuhnya independen dari data yang mereka operasikan.
cmaster
5

Biarkan saya fokus pada pertanyaan Anda yang sebenarnya - "siapa yang benar?" saat membandingkan dua pernyataan ini:

  • Pointer adalah variabel yang nilainya adalah alamat memori variabel lain
  • Pointer adalah lokasi memori yang nilainya adalah alamat memori lokasi memori lain.

Jawabannya tidak ada . Yang pertama berbicara tentang "alamat memori variabel lain", tetapi variabel tidak harus memiliki alamat memori, seperti jawaban lain sudah dijelaskan. Yang kedua mengatakan "pointer adalah lokasi memori", tetapi pointer secara harfiah hanya angka, yang dapat disimpan dalam variabel, tetapi seperti sebelumnya, variabel tidak selalu memiliki alamat memori.

Beberapa contoh untuk pernyataan yang lebih tepat:

  • "Suatu pointer adalah angka yang mewakili alamat memori dari lokasi memori", atau

  • "Variabel penunjuk adalah variabel yang nilainya adalah alamat memori lokasi memori."

  • "Alamat memori dapat menyimpan pointer yang menunjukkan alamat memori lokasi memori."

Perhatikan terkadang istilah "pointer" digunakan sebagai jalan pintas untuk "variabel pointer", yang boleh saja selama tidak menyebabkan kebingungan.

Doc Brown
sumber
Anda dapat mengubah "yang lain" menjadi "a" karena sebuah pointer dapat menunjuk ke dirinya sendiri.
Pieter B
@PieterB: nitty, nitty ;-) tidak yakin apakah ini benar-benar membuatnya lebih jelas, karena saya hanya ingin mengubah kata-kata aslinya ke tingkat yang benar-benar diperlukan untuk membuatnya masuk akal. Tapi sayangnya, saya sudah mengeditnya.
Doc Brown
Agar adil, jika Anda mendapatkan nitpicky itu "tetapi sebuah pointer secara harfiah hanya sebuah angka" juga tidak benar, sebenarnya sebuah pointer adalah pengidentifikasi referensi nomor;) Atau setidaknya kita harus tahu bahasa spesifik untuk masuk ke ini detail.
Zaibis
2
Pointer adalah nilai (angka sudah terlalu spesifik untuk beberapa implementasi) yang berpotensi merujuk ke beberapa objek. Berpotensi karena ada juga pointer nol, pointer liar, dan pointer menggantung, meskipun beberapa (atau bahkan semua!) Dari mereka dapat dikesampingkan oleh bahasa yang digunakan.
Deduplicator
2
@Dupuplikator: Anda benar, tapi saya pikir model mental penunjuk sebagai angka cukup baik untuk keperluan pertanyaan ini. Jadi mari kita menjaga hal-hal sederhana.
Doc Brown
5

Saya tentu tidak akan mengatakan bahwa pointer adalah lokasi memori yang berisi alamat. Untuk satu, saya tidak mengetahui arsitektur di mana 0x23453bisa muat dalam satu byte. :) Bahkan jika Anda menghapus perbedaan byte / kata, Anda masih memiliki masalah bahwa setiap lokasi memori berisi alamat. Alamat hanyalah angka, dan isi memori hanyalah angka.

Saya pikir triknya di sini adalah "pointer" menggambarkan maksud manusia , bukan fitur arsitektur tertentu. Ini mirip dengan bagaimana "karakter" atau "string" bukan hal yang konkrit yang dapat Anda lihat di memori - semua itu juga hanya angka, tetapi mereka berfungsi sebagai string karena itulah cara mereka diperlakukan. "Pointer" hanya berarti nilai yang dimaksudkan untuk digunakan sebagai alamat.

Jujur saja, jika tujuan Anda adalah mengajarkan bahasa tertentu (Objective C?), Saya tidak yakin menggambar kaset memori klasik bahkan berguna. Anda sudah berbohong putih dengan menunjukkan nilai dan nilai yang diketik terlalu besar untuk byte. Ajarkan semantik, bukan mekanika - wawasan utama tentang petunjuk adalah bahwa mereka memberikan tipuan , yang merupakan alat yang sangat berguna untuk dipahami.

Saya pikir perbandingan yang baik mungkin dengan URL, yang memberi tahu Anda di mana menemukan beberapa data, tetapi bukan data itu sendiri. Dengarkan aku:

  • Anda jarang peduli apa sebenarnya URL itu ; sebagian besar dari mereka terseret dalam tautan dengan nama. Banyak orang menggunakan internet tanpa tahu persis bagaimana hasil URL dalam halaman; beberapa orang sama sekali tidak menyadari URL.

  • Tidak setiap string adalah URL, atau dimaksudkan untuk digunakan sebagai URL.

  • Jika Anda mencoba mengunjungi URL palsu, atau halaman yang dulu ada tetapi telah dihapus, Anda mendapatkan kesalahan.

  • Sebuah URL mungkin menunjuk ke suatu gambar, beberapa teks, beberapa musik, atau sejumlah item individual lainnya - atau mungkin menunjuk ke suatu halaman dengan berbagai hal yang terkandung di dalamnya. Sangat umum untuk memiliki banyak halaman dengan tata letak yang serupa tetapi data yang berbeda.

  • Jika Anda membuat halaman web, dan Anda ingin merujuk ke data di beberapa halaman web lain, Anda tidak perlu menyalin dan menempelkan semuanya di; Anda bisa membuat tautan ke sana.

  • Sejumlah halaman lain dapat ditautkan ke URL yang sama.

  • Jika Anda memiliki koleksi halaman yang serupa, Anda dapat membuat halaman indeks yang mencantumkan tautan ke semuanya, atau Anda mungkin hanya memiliki tautan "berikutnya" di bagian bawah halaman 1 yang membawa Anda ke halaman 2, dan seterusnya. Keuntungan dan kerugian dari kedua pendekatan ini segera jelas, terutama jika Anda mempertimbangkan apa yang perlu dilakukan webmaster untuk menambah atau menghapus halaman di berbagai tempat.

Analogi ini membuatnya sangat jelas apa pointer untuk , yang sangat penting untuk memahami mereka - jika tidak mereka hanya tampaknya sewenang-wenang, rumit, dan sia-sia. Memahami cara kerja sesuatu jauh lebih mudah jika Anda sudah mengerti apa yang dilakukannya dan mengapa itu berguna. Jika Anda sudah menginternalisasi bahwa pointer adalah beberapa kotak hitam yang memberi tahu Anda di mana ada sesuatu yang lain, dan kemudian Anda belajar tentang seluk-beluk model memori, maka mewakili pointer sebagai alamat cukup jelas. Plus, mengajar semantik akan menempatkan siswa Anda di tempat yang jauh lebih baik untuk memahami dan menemukan bentuk tipuan lainnya - yang bagus ketika sebagian besar bahasa utama tidak memiliki petunjuk sama sekali!

Eevee
sumber
every memory location contains an address- Setiap lokasi memori memiliki alamat. Tidak terkandung di mana pun, kecuali mungkin dalam variabel pointer.
Robert Harvey
@RobertHarvey setiap lokasi memori (kata, setidaknya) berisi angka, yang dapat ditafsirkan secara sepele sebagai alamat. intinya adalah bahwa tidak ada dalam perangkat keras yang benar-benar membedakan alamat dari bukan alamat
Eevee
2

Saya tahu Anda sudah menerima jawaban, dan pertanyaan ini sudah memiliki lima jawaban, tetapi ada satu hal yang tidak mereka sebutkan, satu yang menurut saya membuat Anda tersandung. Buku teks CS sering mencoba menjadi agnostik tentang pilihan bahasa pemrograman, yang mengarah pada asumsi implisit bahwa terminologi yang digunakan untuk menggambarkan berbagai hal adalah universal. Bukan itu.

Dalam C, operator ampersand unary disebut operator "address-of". Pemrogram C tidak akan ragu untuk mengatakan bahwa ekspresi &xmengevaluasi ke alamat variabel x. Tentu saja mereka berarti "alamat memori di mana nilai variabel x disimpan" tetapi tidak ada orang yang sehebat itu dalam percakapan biasa. Dalam C kata "pointer" biasanya merujuk pada tipe data dari variabel yang dimaksudkan memiliki alamat memori sebagai nilainya. Atau ekuivalen dengan tipe data nilai. Tetapi beberapa orang akan menggunakan "pointer" sebagai nilai itu sendiri.

Di Jawa, semua variabel objek atau tipe array berperilaku seperti pointer C (kecuali untuk aritmatika pointer), tetapi programmer Java menyebutnya referensi, bukan pointer.

C ++ menganggap referensi dan petunjuk untuk konsep yang berbeda. Mereka terkait, tetapi bukan hal yang sama, sehingga programmer C ++ harus membuat perbedaan dalam percakapan. Ampersand dibaca sebagai "alamat" dalam beberapa konteks, dan "referensi untuk" dalam konteks lain.

Pointer adalah variabel yang nilainya adalah alamat memori variabel lain.

Begitulah cara seorang programmer C menggambarkannya, menggunakan "sebuah pointer" dalam arti yang sama dengan "sebuah int." (Seperti pada, "pointer memegang alamat memori sementara int memegang integer dalam rentang tertentu.")

Pointer adalah lokasi memori yang nilainya adalah alamat memori lokasi memori lain.

Itu cara yang aneh untuk mengatakannya, karena itu memerlukan definisi yang longgar dan tidak resmi tentang "apa adanya".

Apakah aman untuk mengatakan bahwa suatu variabel sama dengan lokasi memori?

Akan lebih jelas untuk mengatakan alamat memori adalah lokasi di memori tempat nilai variabel disimpan. (Memang, tidak semua variabel disimpan dalam memori, karena optimisasi kompiler, tetapi variabel yang alamatnya akan diambil &x.)

Gatkin
sumber
Saat kita menjadi bertele-tele: Alamat di mana sesuatu disimpan. Selain dari suatu alamat yang tidak dapat menyimpan apa pun, seringkali barang disimpan di beberapa lokasi yang berdekatan hanya satu yang (biasanya dipilih oleh aturan yang agak konsisten) ditangani (dan hanya menggunakan salah satu dari banyak alamat yang berpotensi).
Deduplicator
@Dupuplikator I untuk seseorang saya tidak mencoba untuk menjadi sombong.
gatkin
Standar C bahkan membedakan, secara formal, antara variabel yang harus secara ketat mengikuti langkah-langkah dari mesin abstrak di setiap "titik urutan" - demi keselamatan benang dan operasi tingkat rendah tertentu pada perangkat keras yang dipetakan memori - dan yang tidak t, yang bebas untuk dipindahkan ke register atau dioptimalkan sepenuhnya.
Davislor
@ Davidvis: Standar C menggunakan istilah "objek" di tempat-tempat di mana spesifikasi bahasa lain menggunakan "variabel", serta untuk menggambarkan hal-hal lain yang bukan variabel. Beberapa diskusi mungkin menggunakan istilah bahasa-agnostik "variabel", tetapi untuk alasan apa pun Standar tidak memiliki istilah untuk membedakan antara alokasi disjoint yang dinamai (variabel) dari jenis objek lain seperti alokasi bersarang (struct / anggota serikat) atau objek tanpa nama yang dihasilkan oleh pointer dereferencing. Secara informal, "variabel" adalah istilah yang bagus, tetapi Standar tidak menggunakannya.
supercat
@supercat Itu tidak benar. Standar C11 menggunakan istilah "variabel" lebih dari seratus kali, di mana beberapa lusin merupakan kata benda, misalnya, "Akses bersamaan ke variabel yang diinisialisasi, bahkan melalui operasi atom, merupakan perlombaan data."
Davislor
1

Pernyataan Pointer adalah variabel yang nilainya adalah alamat memori variabel lain terlalu disederhanakan. Tetapi pada saat pembaca memahami apa sebenarnya lokasi memori itu, dan bagaimana itu berbeda dari suatu variabel, mereka sudah akan mengerti apa sebenarnya penunjuk itu dan karena itu tidak perlu lagi mengandalkan penjelasan yang tidak akurat ini.

Pernyataan Penunjuk adalah lokasi memori yang nilainya adalah alamat memori lokasi memori lain salah. Nilai pointer tidak perlu disimpan di lokasi memori, dan itu bisa diperdebatkan jika pointer perlu menunjuk ke lokasi memori, tergantung pada definisi "memori" yang dimaksud.

Apa perbedaan antara variabel dan lokasi memori

Lokasi memori adalah salah satu dari beberapa tempat yang memungkinkan di mana data dapat disimpan. Data itu bisa berupa variabel, atau bagian dari variabel. Variabel adalah cara pelabelan data.

Peter
sumber
0

Jawaban ini berfokus pada C dan C ++; yang sepertinya tepat karena pertanyaan Anda berkaitan dengan pointer yang merupakan bagian yang lebih integral dari C / C ++ daripada bahasa lain. Sebagian besar posting ini akan berlaku untuk sebagian besar bahasa yang dikompilasi tanpa waktu proses yang rumit (seperti Pascal atau Ada, tetapi tidak seperti Java atau C #).

Jawaban baik yang sudah diberikan menekankan bahwa variabel adalah konstruksi bahasa pada tingkat yang lebih abstrak daripada memori fisik. Saya ingin menekankan bahwa abstraksi ini memiliki alasan dan sistem tertentu untuk itu:

Abstraksi terutama terdiri dari penggunaan nama alih-alih alamat literal.

Gagasan prinsipnya adalah bahwa variabel adalah pegangan bernama untuk objek yang diketik; objek dalam C / C ++ biasanya dalam memori. Bahasa-bahasa tersebut kemudian menambahkan beberapa hal yang berkaitan dengan manajemen seumur hidup dan pengelolaan data untuk konversi jenis. Konsep variabel lebih abstrak daripada alamat fisik karena kita tidak benar-benar peduli tentang nilai numerik alamat atau lokasi fungsi dalam memori. Kami cukup menamainya dan kemudian mengatasinya dengan nama, dan kompiler, linker dan sistem runtime mengurus rincian berpasir.

Dan jangan berpura-pura bahwa C / C ++ adalah agnostik memori: Bagaimanapun, ada operator alamat yang berlaku secara universal. Ya benar, Anda tidak dapat mengambil alamat variabel C di kelas penyimpanan register; tetapi kapan Anda terakhir menggunakannya? Ini adalah pengecualian khusus untuk konsep umum, bukan pemecatan grosir argumen. Aturan umum adalah, sebaliknya, bahwa mengambil alamat variabel sebenarnya memaksa kompiler untuk benar-benar membuat objek dalam memori, bahkan jika itu tidak akan melakukannya sebaliknya (misalnya dengan konstanta). Konsep "named handle" juga merupakan paradigma yang baik untuk referensi C ++: Referensi hanyalah nama lain untuk objek yang sama.

Ketika saya menulis inline assembler untuk 68k itu bagus untuk melihat bagaimana Anda bisa menggunakan nama variabel sebagai offset untuk mengatasi register (dan Anda bisa menggunakan nama variabel yang dideklarasikan registerdaripada nama register logam kosong!). Untuk kompiler, variabel adalah offset alamat konstan. Untuk mengulangi: Variabel diberi nama pegangan, biasanya untuk objek dalam memori.

Peter - Pasang kembali Monica
sumber
Pointer adalah bagian yang sangat mendasar dari C #, Java, JS, dan bahasa lainnya juga. Memanggil mereka secara berbeda tidak mengubah itu, meskipun itu adalah PR yang baik.
Deduplicator
@Dupuplikator :-) Good ol 'Tony ...
Peter - Reinstate Monica
0

Kedengarannya pertanyaan tersebut ditujukan pada bahasa populer yang dibentuk dengan menambah Standar C dengan jaminan tambahan "Dalam kasus di mana beberapa bagian dari Standar atau dokumentasi implementasi menggambarkan perilaku beberapa tindakan, dan beberapa bagian lainnya mengkategorikannya sebagai tidak terdefinisi , bagian sebelumnya mendominasi. ", serta definisi" variabel "yang konsisten dengan penggunaan bahasa lain dari istilah tersebut.

Dalam bahasa itu, setiap lokasi memori dapat dilihat sebagai kotak surat bernomor yang selalu menampung beberapa nomor (biasanya delapan) bit, yang masing-masing dapat secara independen menjadi nol atau satu. Lokasi memori biasanya diatur dalam baris dua, empat, atau delapan. dan beberapa proses operasi pada beberapa lokasi memori berturut-turut sekaligus. Tergantung pada mesin, beberapa operasi yang beroperasi pada kelompok dua, empat, atau delapan lokasi memori mungkin terbatas pada operasi di lokasi dalam satu baris. Lebih lanjut, sementara beberapa mesin mungkin memiliki satu ruangan kotak surat bernomor berturutan, yang lain mungkin memiliki beberapa kelompok terpisah dari kotak surat bernomor.

Variabel mengidentifikasi berbagai lokasi memori yang terkait secara eksklusif dengannya, dan jenis yang harus ditafsirkan lokasi memori tersebut. Membaca variabel akan menyebabkan bit dalam lokasi penyimpanan terkait ditafsirkan dengan cara yang sesuai dengan jenis variabel, dan menulis variabel akan menyebabkan bit terkait diatur dengan cara yang sesuai dengan jenis dan nilainya.

Alamat merangkum informasi apa pun yang diperlukan untuk mengidentifikasi kotak surat. Ini dapat disimpan sebagai nomor sederhana, atau sebagai semacam penunjuk grup bersama dengan jumlah kotak surat di dalam grup itu.

Menerapkan &operator ke variabel akan menghasilkan pointer yang merangkum alamat dan jenisnya. Menerapkan unary *atau []operator ke penunjuk akan menyebabkan bit kotak surat mulai dari alamat yang dienkapsulasi ditafsirkan atau diatur dengan cara yang sesuai dengan tipe yang dienkapsulasi.

supercat
sumber
Sepertinya Anda terlalu memikirkan pertanyaan itu.
Robert Harvey
0

Saya datang terlambat ke pesta ini tapi saya tidak bisa menolak memasukkan 2 sen saya.

Pada saat ini, apa perbedaan antara nilai yang disimpan di lokasi memori ini?

Waktu 1

masukkan deskripsi gambar di sini

Waktu 2

masukkan deskripsi gambar di sini

Jawaban yang benar: tidak ada. Semua itu adalah nilai-nilai identik yang disajikan dengan interpretasi yang berbeda tentang maknanya.

Bagaimana saya tahu itu? Karena akulah yang mengada-ada. Anda belum benar-benar tahu itu.

Anda mengalami sesuatu yang saya sebut masalah band keluar . Cara menafsirkan makna nilai-nilai ini dengan benar tidak disimpan di sini. Pengetahuan itu disimpan di tempat lain. Namun ketika Anda menyajikan nilai-nilai ini di atas kertas Anda memasukkan interpretasi itu. Itu berarti Anda telah menambahkan informasi yang tidak ada di lokasi memori ini.

Sebagai contoh, nilai-nilai di sini identik, tetapi Anda hanya tahu bahwa itu benar jika Anda benar ketika Anda menganggap pengkodean karakter ASCII / UTF-8 adalah bagaimana saya mendapatkan yang pertama, daripada mengatakan EBCDIC . Dan Anda juga harus mengasumsikan bahwa yang kedua adalah ekspresi heksadesimal dari nilai numerik yang disimpan di lokasi memori itu, yang semuanya bisa menjadi pointer ke alamat lain, daripada mengatakan referensi ke string yang semuanya dimulai dengan "0x". : P

Tidak ada yang tersimpan di lokasi memori ini yang memberi tahu Anda asumsi mana pun yang benar. Informasi itu dapat disimpan. Tapi itu akan disimpan di tempat lain.

Ini adalah masalah presentasi . Anda tidak dapat mengungkapkan angka apa pun tanpa terlebih dahulu menyetujui cara menyajikannya. Anda dapat bersandar pada asumsi, konvensi, dan konteks tetapi jika Anda menggaruknya dalam-dalam, ketika presentasi tidak didefinisikan secara eksplisit, satu-satunya jawaban yang benar adalah "tidak cukup informasi".

candied_orange
sumber
Ini bahkan lebih menyenangkan ketika memori yang sama digunakan untuk hal-hal konstan yang berbeda secara bersamaan.
Deduplicator
@Dupuplikator Benar. Itu selalu membuat saya berpikir tentang pemeran ulang c ++ . Bit yang sama terlihat dengan cara yang berbeda.
candied_orange
@Deduplicator atau, kalau dipikir-pikir itu, penyatuan di c
candied_orange