Apa gunanya kasing dan kelebihan pointer? [Tutup]

10

Saya sering kesulitan untuk melihat keuntungan dari pointer (kecuali untuk pemrograman tingkat rendah).

Mengapa menggunakan char * alih-alih String atau char [] atau keuntungan apa yang dibawa oleh aritmatika pointer.

Jadi apa pro dan penggunaan kasus pointer?

Oliver
sumber
6
Ini akan terdengar agak elitis, tetapi IMHO jika Anda harus bertanya tentang pro dan kontra dari pointer, Anda kemungkinan besar tidak membutuhkannya.
Jas
3
Mungkin! Namun pertanyaannya masih valid!
Zolomon
1
Ini juga bukan bahasa-agnostik, karena tidak semua bahasa pemrograman memiliki pointer nyata dalam pengertian C.
David Thornley

Jawaban:

6

Pointer diperlukan untuk lokasi memori dinamis, banyak struktur data, dan penanganan data dalam jumlah besar secara efisien. Tanpa pointer, Anda harus mengalokasikan semua data program secara global atau dalam fungsi atau yang setara, dan Anda tidak akan memiliki jalan lain jika jumlah data tumbuh melebihi apa yang semula Anda izinkan. Saya ragu untuk menggunakan absolut di sini, tetapi sejauh yang saya tahu semua bahasa komputer modern memiliki petunjuk dalam beberapa bentuk atau lainnya.

Di sebagian besar bahasa yang menggunakan pointer, ada beberapa jenis referensi yang merupakan pointer, dan mungkin beberapa jenis referensi yang tidak, dan tidak ada perbedaan notasi lebih lanjut. consSel Lisp adalah sepasang pointer, meskipun a fixnumbukan pointer. Di Jawa, variabel yang digunakan untuk instance kelas adalah pointer, tetapi inttidak. Sintaks bahasa tidak mencerminkan hal itu.

C tidak biasa dalam pointer adalah opsional, eksplisit, dan memungkinkan aritmatika pointer eksplisit. Sangat mungkin untuk menulis struct foo bar; struct foo * baz;, dan setelah Anda mengalokasikan memori untuk bazAnda dapat menggunakan keduanya bardan bazuntuk mewakili struct foo. Karena pointer bersifat opsional, maka berguna untuk memiliki perbedaan notasi. (Sangat penting dalam C ++ untuk pointer cerdas, seperti yang diberikan boost::shared_ptr<foo> bar;, bar.reset()memiliki satu makna dan bar->reset()cenderung memiliki yang jauh berbeda.)

(Sebenarnya, pointer eksplisit sering digunakan dalam bahasa lain ketika C pada awalnya dikembangkan, seperti ^dalam Pascal. C adalah bahasa yang lebih tua daripada kebanyakan yang umum digunakan saat ini, dan itu menunjukkan.)

Salah satu tujuan desain C adalah menulis Unix, dan karena itu diperlukan untuk menangani lokasi memori secara rinci. (C sebenarnya adalah salah satu dari keluarga bahasa implementasi sistem yang umum ketika sedang dirancang, contoh lain adalah Cybol untuk komputer Data Kontrol. C adalah salah satu yang menjadi hit besar.) Oleh karena itu, dimungkinkan untuk memanipulasi pointer C secara langsung, menetapkan alamat memori dan menghitung yang baru. Ini juga menyebabkan beberapa keputusan desain dalam array C. C sangat didasarkan pada aritmatika pointer, dan memang array meluruh menjadi pointer dalam situasi yang sangat banyak. Melewati variabel ke fungsi C dengan referensi dilakukan oleh pointer. Tidak ada kebutuhan yang kuat untuk array dan variabel lewat dengan referensi dalam bentuk yang dimiliki bahasa kontemporer lainnya, jadi C tidak mendapatkannya.

Jadi, jawabannya adalah bahwa, di sebagian besar bahasa saat ini, Anda menggunakan pointer secara konstan tanpa diingatkan akan kenyataan. Dalam C, dan pada tingkat lebih rendah C ++, Anda menggunakan pointer untuk melakukan hal-hal tingkat rendah, atau untuk mencapai hal-hal tingkat tinggi yang tidak ada notasi khusus untuk.

David Thornley
sumber
jawaban yang sangat bagus
Kate Gregory
1
Saya menerima jawaban ini karena ini menjelaskan perbedaan terbaik yang saya tidak bisa pahami antara pointer dalam C / C ++ dan Referensi di Jawa.
OliverS
Akan lebih baik untuk menambahkan penjelasan singkat mengapa Jawa tidak menggunakan pointer untuk lebih memperjelas "con" yang dirasakan oleh Gosling (pencipta utama Java).
Guido Anselmi
10

Struktur data yang kompleks. Anda tidak dapat membangun sesuatu seperti daftar tertaut atau pohon biner tanpa pointer.

Tidak ada "pro" dan "kontra" dari pointer. Mereka hanya alat, seperti palu.

zvrba
sumber
5
Di Jawa, tidak ada petunjuk. Namun, adalah mungkin untuk membangun daftar tertaut dan pohon biner. Ada perbedaan antara referensi (seperti di Jawa) dan pointer (seperti dalam C).
StartClass0830
7
Tidak ada perbedaan antara referensi dan petunjuk. Aritmatika pointer adalah spesifik-C; ada bahasa lain yang memiliki pointer, tetapi tidak memiliki aritmatika pointer (misalnya, Pascal).
zvrba
1
Pointer dan referensi tidak sama dengan yang Anda pikirkan. Baca ini untuk melihat perbedaannya. stackoverflow.com/questions/57483/…
StartClass0830
4
Untuk mengatasi dua item pertama dari daftar itu: Referensi Java BISA ditugaskan ulang dan mereka BISA menunjuk ke nol. Fitur yang membedakan dari pointer adalah memungkinkan Anda untuk secara tidak langsung merujuk objek lain. Tes lakmus saya adalah: jika Anda dapat membangun struktur data melingkar (yang Anda dapat dengan referensi Java), itu adalah sebuah pointer. (Perhatikan bahwa Anda tidak dapat membangun struktur data melingkar dengan referensi C ++.)
zvrba
1
Ada perbedaan antara pointer dan referensi. C #, misalnya, memiliki keduanya . ( blogs.msdn.com/b/ericlippert/archive/2009/02/17/… )
Steven Evers
2
  • Dengan pointer Anda dapat mengalokasikan dan membatalkan alokasi memori dalam runtime.
  • Dan Anda dapat menggunakan struktur data besar di luar cakupan yang diizinkan tanpa disalin.

Referensi dalam C ++, Java dan jenis bahasa lain yang sama hanyalah 'pointer aman'. Dan referensi ini banyak digunakan di Jawa.

Gulshan
sumber
1
Referensi dalam C ++ BUKAN pointer aman. Referensi dalam C ++ tidak ada hubungannya sama sekali dengan pointer. Referensi dalam C ++ adalah alias . Mereka tidak dapat ditugaskan NULL, dan mereka tidak dapat dimodifikasi setelah dibuat.
Billy ONeal
@Illy: Referensi C ++ biasanya diimplementasikan menggunakan pointer, dan bekerja serupa dalam beberapa hal, sehingga orang-orang tetap menganggapnya sebagai semacam pointer terbatas.
David Thornley
2

Hampir semua program komputer perlu memeriksa dan mengubah nilai dalam memori (dikenal sebagai mengintip dan menyodok, bagi kita yang sudah cukup umur). Anda perlu mengontrol di mana dalam memori nilai-nilai tersebut berada, sehingga hasilnya dapat diprediksi (dan dalam kasus tertentu, urutannya penting: memuat kode yang dapat dieksekusi adalah salah satu contoh). Oleh karena itu Anda perlu memiliki tipe data yang mewakili lokasi di memori. Bahkan jika lingkungan pemrograman Anda menyembunyikan itu di bawah abstraksi, itu masih ada.


sumber
2

char*adalah contoh pointer yang payah. Anda mungkin lebih baik menggunakan std::string(atau jenis yang lebih baik yang menangani unicode / ansi / multibyte Anda) daripada char*. Untuk hampir semua contoh lain dari pointer ( Employee*, PurchaseOrder*, ...), namun, ada banyak keuntungan:

  • ruang lingkup lebih besar dari satu fungsi - mengalokasikan objek pada heap dan meneruskan pointer di sekitar untuk waktu yang lama
  • fungsi yang lebih cepat memanggil objek besar karena Anda tidak memiliki biaya salinan nilai per nilai
  • salah satu cara untuk mengaktifkan fungsi untuk mengubah parameter yang diteruskan ke sana
  • menghemat ruang dan waktu dalam koleksi hanya menyalin alamat daripada seluruh objek

Bahkan, pointer sangat penting sehingga sebagian besar bahasa yang tampaknya tidak memilikinya sebenarnya hanya memiliki mereka. Tipe referensi dalam C # dan Java pada dasarnya adalah pointer yang disamarkan sebagai objek padat.

Sekarang, manipulasi pointer ( p++pada pointer, atau p += delta) adalah keseluruhan cerita nother. Beberapa orang berpikir itu berbahaya, beberapa orang berpikir itu hebat. Tapi itu jauh dari pertanyaan Anda.

Kate Gregory
sumber
1

Pointer dapat lebih cepat dan dapat menyebabkan lebih sedikit overhead, baik dalam struktur data maupun dalam menjaga tapak pelaksanaan program. (Harap perhatikan kata 'bisa'.)

Secara umum aturannya adalah, jika Anda mengalokasikan sumber daya, baik dengan melakukan alokasi Anda sendiri atau melakukan sesuatu atas nama Anda, maka tugas Anda untuk melepaskannya ketika dilakukan.

Beban melakukan hal di atas adalah mengembalikan tanggung jawab kepada pengembang, daripada meminta runtime melakukannya. Ini memiliki beberapa keuntungan lebih dalam hal hal-hal dapat hidup lebih lama, atau melintasi batas, atau dibuang pada waktu yang lebih tepat, atau tidak perlu membawa beban pengumpul sampah di sekitar.

Dalam kasus eksotis, biasanya melibatkan pengecualian dan ruang lingkup, ada beberapa kasus tepi yang mengharuskan seseorang untuk sedikit lebih berhati-hati jika kode pembersihan tidak dihindari. Secara realistis, kasing ini dapat dirancang. Kami hidup tanpa kode yang dikelola selama beberapa dekade.

Seringkali yang membuat pointer "sulit" hanyalah tidak memahami apa yang terjadi pada tingkat perangkat keras. Ini tidak lebih dari tipuan.

Pointer memberi Anda lebih banyak akses mentah, dan ini bisa sangat membantu, pintar, atau perlu. Anda dapat menunjuk ke mana saja dan memperlakukannya seperti apa saja. Jika Anda menggunakan kekuatan seperti Tuhan untuk kebaikan, itu sangat, sangat bagus.

Sisi con biasanya membuang-buang dengan lupa untuk melepaskan sesuatu, atau dengan melepaskannya lebih dari sekali, atau merujuk sesuatu setelah itu dirilis, atau memperbaiki sesuatu ketika Anda tidak menunjuk ke mana pun. Hal-hal ini sering mengakibatkan crash spektakuler, dan jujur ​​biasanya menunjukkan bahwa Anda punya masalah logika, daripada pointer yang rapuh.

Jika Anda seorang pengembang yang solid, menggunakan pointer seharusnya tidak menjadi lebih bermasalah daripada struktur data lainnya. Sekali lagi, ini bukan ilmu roket, dan orang-orang melakukannya selama beberapa dekade tanpa berkedip. Ini hanya diajarkan kurang teliti akhir-akhir ini.

Semua yang dikatakan, kecuali Anda membutuhkan pointer, kasus-kasus kenyamanan dan exoitic yang disediakan oleh pengumpulan sampah yang baik membuat bekerja di lingkungan yang dikelola jauh lebih baik. Sangat bagus untuk dapat mengambil beberapa memori, menggunakannya, dan meninggalkannya, mengetahui bahwa beberapa waktu kemudian, mungkin akan dibuang, jika masuk akal untuk melakukannya. Itu kode yang sedikit lebih sedikit pada bagian coder, dengan imbalan runtime yang melakukan beberapa pengangkatan tambahan.

Walt Stoneburner
sumber
0

Jawaban terbaik sebenarnya termasuk dalam pertanyaan: petunjuk adalah untuk pemrograman tingkat rendah. Memang, jika Anda menggunakan C, tidak menggunakan pointer seperti pemrograman dengan satu tangan terikat di belakang Anda, tetapi jawabannya adalah dengan menggunakan bahasa tingkat yang lebih tinggi.

Larry Coleman
sumber
-1

Pointer memberikan visibilitas ke dalam mesin yang diperlukan untuk pemrograman paling menarik. Sebagian besar bahasa modern menyembunyikan bit-bit kasar dari Anda.

Paul Nathan
sumber