Apa penjelasan yang bagus untuk pointer? [Tutup]

72

Dalam studi Anda sendiri (sendiri, atau untuk kelas) apakah Anda memiliki momen "ah ha" ketika akhirnya, Anda benar-benar memahami petunjuk? Apakah Anda memiliki penjelasan yang Anda gunakan untuk programmer pemula yang tampaknya sangat efektif?

Misalnya, ketika pemula pertama kali menemukan pointer di C, mereka mungkin menambahkan &s dan *s sampai kompilasi (seperti yang pernah saya lakukan sendiri). Mungkin itu adalah gambar, atau contoh yang sangat termotivasi, yang membuat petunjuk "klik" untuk Anda atau siswa Anda. Apa itu, dan apa yang Anda coba sebelumnya yang tampaknya tidak berhasil? Apakah ada topik prasyarat (mis. Struct, atau array)?

Dengan kata lain, apa yang diperlukan untuk memahami arti dari &dan *, kapan Anda bisa menggunakannya dengan percaya diri? Mempelajari sintaks dan terminologi atau kasus penggunaan tidak cukup, pada titik tertentu ide perlu diinternalisasi.


Pembaruan: Saya sangat menyukai jawabannya sejauh ini; tolong teruskan mereka. Ada banyak perspektif hebat di sini, tapi saya pikir banyak penjelasan / slogan yang bagus untuk diri kita sendiri setelah kita menginternalisasikan konsep itu. Saya mencari konteks dan keadaan terperinci saat Anda sadar.

Sebagai contoh:

Saya hanya sedikit mengerti pointer secara sintaksis dalam C. Saya mendengar dua teman saya menjelaskan pointer ke teman lain, yang bertanya mengapa a structditeruskan dengan pointer. Teman pertama berbicara tentang bagaimana itu perlu direferensikan dan dimodifikasi, tetapi itu hanya komentar singkat dari teman lain di mana itu mengenai saya: "Ini juga lebih efisien." Melewati 4 byte, bukan 16 byte, adalah pergeseran konseptual terakhir yang saya butuhkan.

Macneil
sumber
16
Metode 'Shotgun': melempar * di mana-mana sampai berhasil.
Michael K
15
@Michael: Ya, semoga sukses dengan itu.
Robert Harvey
8
Pertanyaan ini muncul tak lama setelah pada awal setiap semester di SO. Inkarnasi terbaru ada di sini: stackoverflow.com/questions/4118647/…
Tim Post
10
Apa penjelasan yang bagus untuk petunjuk? Brian Kernhigan dan Dennis Ritchie membenci insinyur perangkat lunak.
Adam Crossland
3
Itu "diklik" untuk saya setelah menghabiskan beberapa waktu kode mesin stepping tunggal di debugger. Ya, saya terbiasa dengan dasar-dasar arsitektur komputer - saya belajar perakitan di Commodore 64, dan x86 ASM cukup mudah setelah itu. Jadi saya sudah tahu konsep "alamat", saya hanya tidak mengerti bagaimana memetakannya ke konstruksi sintaksis C.
zvrba

Jawaban:

25

Memory-as-a-Grid Diagram

Biasanya yang saya lakukan adalah merepresentasikan memori sebagai "kisi", sehingga saya dapat membuat alamat, menyorot ruang memori yang berbeda dan menulis dalam nilai sel (atau bahkan lebih jauh, representasi binernya) dan menghubungkan pointer dalam memori dengan nilai yang mereka menunjuk pada. (Dan kemudian masih menyebutkan bahwa itu penyederhanaan).

Biasanya ini adalah momen "ohhhh" bagi sebagian besar siswa saya.

Simbol Juggling

Kemudian ketika mereka berhenti membuat mereka lupa bagaimana cara menggunakan & dan *, itu sangat sederhana: sajikan dengan cara yang sama seperti ketika mereka melakukan perhitungan matematika atau fisika. Jika Anda membagi jarak dalam km dengan waktu dalam jam, Anda mendapatkan kecepatan dalam km / jam. Apa yang perlu keluar. Sederhana.

printf ke Penyelamatan

Melakukan hanya beberapa contoh dasar yang secara visual mewakili apa yang Anda jelaskan dengan ini akan menghibur mereka dalam apa yang mereka pikir mereka pahami, atau memberi mereka kesempatan untuk mengatakan "ah, saya tidak mengerti yang ini".

Menjadi Luas

Tutup petunjuk untuk tipe sederhana dan pastikan mereka memahami perbedaan antara pengalamatan dan ukuran tipe data, lalu susun, lalu susun, dan berbagai level.

Kemudian mulai aritmatika pointer.


Tambahan: Rekursi

Saya biasanya menjelaskan rekursi dengan cara yang sama, menggunakan representasi visual. Mintalah mereka mencetak alfabet menggunakan fungsi pra-dibuat yang menulis satu karakter, dan kemudian minta mereka untuk mencetaknya dalam urutan terbalik dengan hanya mengubah dua baris.

Biasanya ada "apa ...?" saat, dan ketika Anda menambahkan hanya parameter lain ke printf Anda untuk mencetak nilai numerik dan indentasi langkah-langkahnya, itu menjadi desahan lega.


Alternatif: Model Play-Doh dan Piala Air

Saya sebenarnya memiliki beberapa rekan kerja di sebuah universitas yang menunjukkan kepada siswa sebuah video yang menjelaskan petunjuk dan akses memori menggunakan pasta play-doh. Itu sangat pintar dan dilakukan dengan baik, meskipun saya sendiri tidak pernah benar-benar menggunakan teknik itu, kecuali untuk pelajar yang sangat muda yang tertarik dalam memahami pemrograman (tetapi biasanya mereka yang saya tidak akan mengarahkan mereka ke bahasa yang menggunakan pointer terlalu dini). Pada dasarnya menggunakan bola-bola play-doh kecil yang dapat Anda pasang ke bola-bola play-doh lain yang lebih besar yang mewakili ruang memori, dan bahwa Anda dapat menggabungkan bersama-sama untuk menautkan keduanya (seperti dalam struktur data yang ditautkan) atau bergabung bersama (seperti dalam berdekatan) ruang memori). Menggunakan warna yang berbeda untuk ruang memori yang ditunjuk dan pointer membantu juga. Tapi saya masih berpikir hal Memory-as-a-Grid bekerja lebih baik, karena Anda dapat dengan jelas menunjukkan bahwa menunjuk sebenarnya masalah "pengalamatan", seperti pada "peta / kotak". Sedangkan mode Play-doh masih membingungkan mereka untuk berpikir bahwa hal-hal benar-benar "saling menyentuh" ​​dalam memori.

Hal Piala Air digunakan langsung oleh seorang rekan juga, tapi saya tidak tahu apakah dia datang dengan itu. Itu adalah pendekatan yang menarik, tetapi saya perhatikan banyak siswa yang bingung dengan penjelasannya. Sesuatu yang mirip dengan teknik Cangkir Kopi DevSolo . Tapi saya pikir itu sebenarnya yang menyesatkan ketika Anda membuat siswa bingung wadah, struktur data, petunjuk dan array. Mungkin ini pendekatan yang menarik untuk menjelaskan array pada awalnya saya anggap, tapi saya tidak akan bertahan terlalu lama.

haylem
sumber
Wow, terima kasih atas hadiahnya. Senang jawabannya dihargai.
haylem
Tarik itu: | itu terdengar seperti pengajaran yang bagus!
Spooks
80

Seseorang yang jauh lebih bijaksana daripada yang pernah saya katakan:

Biarawati Wu Jincang bertanya kepada Patriach Keenam Huineng, "Saya telah mempelajari sutra Mahaparinirvana selama bertahun-tahun, namun ada banyak area yang saya tidak begitu mengerti. Tolong beri tahu saya."

Patriach itu menjawab, "Saya buta huruf. Tolong bacakan karakter untuk saya dan mungkin saya akan bisa menjelaskan artinya."

Kata biarawati itu, "Kamu bahkan tidak bisa mengenali karakternya. Bagaimana kamu bisa mengerti artinya?"

"Kebenaran tidak ada hubungannya dengan kata-kata. Kebenaran dapat disamakan dengan bulan yang cerah di langit. Kata-kata, dalam hal ini, dapat disamakan dengan jari. Jari dapat menunjuk ke lokasi bulan. Namun, jari itu bukan bulan. Untuk melihat bulan, perlu untuk menatap ke luar jari, kan? "

Frank Shearar
sumber
13
+1 untuk mendereferensi bulan. +1 untuk koan, jika aku bisa.
Tim Post
14
Apa suara upvoting satu jari?
Adam Crossland
3
@Adam, itu tergantung pada apakah Anda menggunakan mouse atau trackpad.
Daniel Joseph
7
@ Terus terang Itu adalah kutipan BESAR. Namun saya pikir itu tidak akan membantu untuk memahami gagasan itu. Khusus untuk seseorang yang baru mengenal pointer.
Gulshan
11
Ini adalah kisah yang indah ... tapi saya curiga bahwa orang-orang memilih karena itu, daripada karena itu menjelaskan petunjuk dengan baik.
Kyralessa
46

Saya menemukan bahwa diagram sangat membantu. Contoh:

diagram penunjuk


Diagram semacam ini membantu saya melihat bahwa pointer adalah variabel mereka sendiri, tetapi berisi nilai yang merupakan lokasi objek lain, yaitu array atau string. Juga, ketika dilakukan dengan pensil, saya bisa menggunakannya untuk melacak program saya di atas kertas, atau di papan tulis / papan tulis.

Michael K
sumber
4
Entah nilai dalam "pointer" harus 4 atau indeks array (atau alamat memori) harus dimulai dari 0. Jika tidak, bagaimana bisa sebuah pointer yang menyimpan nilai 3 titik ke lokasi 4?
MAK
++ Ini persis bagaimana saya akan menjelaskannya. Saya mulai di Fortran (baik atau buruk!). Di Fortran, saat itu, kami menggunakan array paralel dan bukan array struct (tidak ada yang baru ). Jika satu array berisi indeks "baris lain" di array, kami menyebutnya "pointer", dan ini sangat menarik. Kami membuat daftar yang ditautkan, pohon, apa saja.
Mike Dunlavey
2
Saya menemukan pointer dijelaskan dengan menggunakan gambar yang menunjukkan apa yang disimpan di mana, dan panah untuk menunjukkan di mana pointer menunjuk.
gablin
32

Ketika saya pertama kali "belajar" tentang pointer, saya agak tertarik padanya. Universitas saya telah membuat keputusan jauh sebelum saya mendaftar untuk memusatkan kurikulum di sekitar Jawa, jadi ketika profesor Struktur Data saya memberikan satu kuliah tentang C dan meminta kami untuk menerapkan Daftar-XOR dengan petunjuk, saya merasa seperti sedang melakukan sesuatu jauh di atas kepalaku.

Saya mengerti definisi:

Pointer adalah variabel yang berisi alamat variabel

Tetapi saya masih belum mengerti sebagian besar konsep itu. Melihat ke belakang, saya pikir itu berpusat pada tiga hal:

  1. Apa sebenarnya adalah lokasi memori? (Pada saat itu saya tidak mengambil kelas Organisasi Komputer)

  2. Sintaks canggung (Jadi um ... mengapa tepatnya itu didefinisikan seperti "int * ip" tapi kemudian saya sebut variabel sebagai "ip"?)

  3. Bagaimana sebenarnya bermanfaat untuk menyimpan alamat variabel daripada hanya menggunakan variabel?

Baru setelah saya membeli buku K&R dan menyelesaikan setiap masalah, saya benar-benar memahami petunjuk. Selain fakta bahwa saya telah lama menyelesaikan kelas Organisasi Komputer (yang saya pikir harus diminta sebelum belajar C), bagian itu ada hubungannya dengan fakta bahwa saya menyadari bahwa pointer dapat digunakan untuk fungsi, array, struct ... untuk melakukan hal-hal yang bermanfaat dan tidak hanya sebagai penyimpanan untuk alamat variabel biasa.

Tapi momen "aha" saya sejauh ini adalah cara K&R menjelaskan sintaks canggung dalam mendefinisikan pointer sederhana. Saya membuat catatan di seluruh buku (di mana saya mengulangi poin-poin yang dibuat oleh buku menjadi kata-kata saya sendiri untuk memajukan pemahaman saya), dan ini adalah yang berkaitan dengan itu:

Pointer adalah variabel yang berisi alamat ke suatu variabel. Suatu pointer didefinisikan dan didereferensiasi (menghasilkan nilai yang disimpan di lokasi memori yang ditunjuknya) dengan operator '*'; ekspresinya mnemonik.

Ex.: 
   int a;      /* Variable 'a' is an integer */

   int *ip;   /* Variable ip is a pointer and dereferencing it gives an integer.
                 In other words, the expression *ip is an int, so ip is a pointer
                 to an int */

Saya selalu merasa bahwa saya tidak dapat sepenuhnya memahami konsep pointer yang lebih maju sampai saya memiliki sesuatu yang begitu mendasar yang tertanam di kepala saya. Itu mengganggu saya tanpa henti setelah penugasan itu (yang saya tidak lakukan dengan baik, omong-omong;)) mengapa "* ip" tidak ada setelah saya (pikir saya) mendefinisikan "* ip". Menguasai ini penting untuk konsep yang lebih maju yang melibatkan pointer, seperti pointer fungsi dan definisi yang lebih rumit seperti ini:

char (*(x())[])()

Secara keseluruhan, saya pikir konsep pointer membutuhkan:

  1. Pemahaman dasar tentang bagaimana memori diletakkan di komputer (dan apa memori itu).

  2. Pengetahuan tentang seberapa kuat pointer dapat digunakan (penggunaan dunia nyata, bukan hanya konsep abstrak lain yang mereka pelajari demi pembelajaran).

  3. Menguraikan hieroglif yang secara sehari-hari dikenal sebagai "definisi penunjuk"

Jadi semuanya, saya pikir harus ada setidaknya 3 "aha" saat belajar tentang pointer. Saya masih mahasiswa jadi saya pikir Anda akan menghargai sudut pandang seseorang yang masih (relatif) baru belajar konsep.

Kevin
sumber
+1 untuk 3 "Ah ha!" monents. Pointer groking datang berlapis-lapis. Saya "mengerti" poin untuk waktu yang lama sebelum saya menyadari bahwa saya hanya mengerti setengah dari pointer ke pointer :)
Binary Worrier
Saya pikir Anda benar sepenuhnya karena sebagian besar dari 'tidak mengerti petunjuk' sebenarnya tersandung pada sintaks C yang aneh. [Berpikir: Saya bertanya-tanya betapa sulitnya untuk grok dengan sintaks semacam ini: PointerTo<int> a]
Benjol
Setuju, @Benjol. Saya terkejut bahwa sintaksinya int* iptidak lebih umum. Saya akhirnya mulai memahami pointer begitu saya melihat kode yang diformat seperti ini. Lalu saya bisa membacanya sebagai "ip adalah type int pointer."
Jacob
19

Pointer agak mirip dengan pintasan aplikasi di desktop Anda. Hapus pintasan dan target masih ada. Mulai pintasan dan target dimulai.

Saya selalu menjelaskan cara kerjanya dengan cara sederhana membuat file txt di desktop saya dan dua pintasan ke file tersebut. Setelah menyalin dan menghapus pintasan, Anda dapat melihat orang memahami ide di balik 'referensi'.

Setelah grup memahami dasar di balik cara pintas Anda dapat mulai menjelaskan petunjuk yang Anda inginkan. Mereka mungkin akan memahaminya dengan mudah.

Barfieldmv
sumber
Itu bukan analogi yang buruk. Hanya beberapa poin untuk ditambahkan bagi siapa saja yang mengambil ini secara harfiah "hard-link" akan selalu menunjuk ke targetnya bahkan jika itu mengubah direktori, pointer akan menunjuk ke memori asli bahkan jika objek telah dipindahkan. "Hard-link" akan memberi tahu Anda ketika target tidak ada lagi, pointer penunjuk menggantung harus ditetapkan ke NULL.
snmcdonald
Tautan keras seperti referensi yang dihitung smart pointer
jk.
1
+1. Salah satu analogi praktis terbaik untuk menjelaskan petunjuk. Saya yakin siswa akan segera mendapatkan ide karena fungsi ini adalah yang paling umum digunakan oleh semua orang.
Karthik Sreenivasan
13

8-10 tahun yang lalu, saya mengajar kursus intro "C" di community college. Ini selalu merupakan topik yang menyenangkan untuk dijelajahi. Apa yang tampaknya paling berhasil, dan ini setelah mendiskusikan beberapa rekan kerja beberapa kali adalah dengan menggunakan cangkir kopi dan tangan Anda.

Saya menggunakan analogi cangkir kopi (atau deretannya untuk array) sebagai variabel (dapat menampung sesuatu). Saya kemudian menggunakan tangan saya, yang juga bisa memegang sesuatu atau, dengan mengulurkan jari telunjuk saya untuk "menunjuk ke" cangkir kopi.

Tangan yang dekat adalah nol, jari menunjuk kepalaku (seperti senjata tiruan) adalah penunjuk yang menggantung.

Kemudian dengan beberapa demonstrasi dan perjalanan melalui debugger, itu diklik dengan sebagian besar.

DevSolo
sumber
3
Anda sudah membingungkan saya.
kirk.burleson
1
@ Kus, bagaimana? biarkan saya melihat apakah saya bisa menjernihkannya.
DevSolo
4
++ Tidak ada yang seperti mengajar untuk membuat Anda memikirkan hal-hal ini.
Mike Dunlavey
Salah satu dosen saya di universitas melakukan hal serupa, menggunakan mahasiswa (salah satunya adalah "Niel", untuk tertawa tambahan), alih-alih cangkir kopi. Menunjuk tangan dengan lambaian pada penonton adalah penunjuk yang menggantung, karena itu bisa menunjuk ke apa pun.
Kaz Dragon
2
Pointer yang menggantung lebih seperti menunjuk ke Neil kemudian membuatnya meninggalkan kursinya tanpa mengubah arah yang Anda tunjuk ... kemudian mencoba mengikuti pointer itu dan menafsirkan apa yang Anda temukan di sana sebagai Neil terlepas dari siapa yang berakhir di sana.
Jon Purdy
10

Saya benar-benar merasa khawatir ketika mendengar pertanyaan "bagaimana Anda memahami petunjuk". Saya selalu berpikir konsepnya sangat sederhana, dan evolusi logis dari bahasa memberikan kekuatan besar bagi para programmer.

Hal yang membuat saya khawatir adalah saya tidak pernah merasa sulit untuk memahami konsep pointer. Jadi ketika Anda di sini "kapan akhirnya Anda bisa" berulang-ulang, Anda mulai berpikir:

Apakah saya benar-benar mendapatkannya? Mungkin saya tidak pernah melakukannya?

Mungkin alasan mengapa konsep itu tampaknya rumit, adalah karena kami terus memberi tahu semua orang yang belum menemukan mereka bahwa petunjuk itu sangat sulit, dan di sini ada ratusan cara yang bisa Anda pelajari?

Hanya melempar ide itu ke luar sana, tentu saja secara pribadi saya suka diagram yang bagus dan Steve Gibson selalu melakukan pekerjaan yang fantastis untuk menjelaskan apa pun !

Marcus Whybrow
sumber
Menarik ... bahasa apa yang Anda gunakan saat itu? Saya pikir sintaks C tersandung banyak orang. Jika Anda tahu perakitan lebih dulu, saya bisa melihat itu menjadi satu alasan. [BTW, saya ingin memilih ini, tetapi saya mencapai topiku untuk hari ini.]
Macneil
Cukup menarik, saya tidak memiliki pengetahuan tentang pointer "berbahaya" untuk waktu yang lama, bekerja di Python (dan Java di University). Kemudian saya mengambil modul "metode berorientasi objek" yang menggunakan bahasa C ++ sebagai bahasa pilihan dan langsung terjun ke sana.
Marcus Whybrow
Juga saya pikir memiliki pemahaman tentang bagaimana suatu program diwakili dalam memori pasti dapat membantu, tapi saya pikir saya lebih suka mengatakan bahwa memahami mengapa pointer adalah tambahan yang berguna untuk bahasa, adalah sudut yang paling efektif, karena Anda sedang mengalami hal yang sama. proses sebagai desainer asli.
Marcus Whybrow
+1 Saya tidak tahu mengapa orang berpikir pointer itu keras atau misterius.
ggambett
Ya, petunjuk selalu sangat sederhana dan bermanfaat sehingga saya tidak bisa membayangkan berpikir ada sesuatu yang "sulit" tentang mereka. Aku benci ketika seorang guru kursus mengatakan "sekarang, ini agak rumit" karena itu hanya subversif. Ajarkan saja semuanya, dan biarkan siswa memutuskan sendiri apakah mereka pikir itu sulit.
Jon Purdy
7

Saya tidak pernah memiliki banyak masalah dengan pointer di C, tetapi itu mungkin karena saya harus belajar assembler terlebih dahulu. Sebenarnya itu melegakan tidak harus mengelola alamat sendiri lagi. Jadi mungkin jawabannya (dengan asumsi ini adalah sesuatu yang Anda ajarkan) adalah untuk memberi siswa bahasa assembly yang dapat ditiru untuk bekerja dengannya. Mereka akan mencari tahu dalam proses penulisan apa pun yang lebih canggih dari "Halo, dunia."

Larry Coleman
sumber
+1 untuk mengadaptasi abstraksi yang lebih primitif, daripada mencoba menggunakan analogi.
Jenis Anonim
Di sekolah menengah saya, satu unit Studi Komputer dikhususkan untuk mempelajari komputer kotak korek api , yang dapat diajarkan dari papan tulis tanpa pernah menyentuh atau melibatkan komputer nyata.
rwong
@Larry Coleman, Majelis !!!!!!!!!!! Saya ingin mencobanya terlebih dahulu sebelum C. Tolong beritahu saya di mana harus mulai belajar. Ebook Gratis, PDF Gratis? IDE? Silahkan!!!!!!!!!!!!!!!!!!!
Spacez Ly Wang
7

Pointer adalah variabel yang nilainya adalah alamat memori variabel lain.

kirk.burleson
sumber
Elegan, mengapa membuatnya lebih rumit.
Bjarke Freund-Hansen
Jika pointer sepertinya tidak langsung intuitif dan bermanfaat, mereka telah dijelaskan salah.
Jon Purdy
6

Bagaimana saya benar-benar belajar tentang petunjuk? Dengan menulis tahun baru kompiler mahasiswa baru kuliah.

Bagaimana cara menjelaskan pointer dalam istilah awam? Saya suka analogi (tanggal?) Dari katalog perpustakaan yang disimpan pada kartu indeks. Setiap kartu ("penunjuk") berisi informasi tentang di mana beberapa buku ("data") berada, tetapi sebenarnya tidak mengandung buku itu sendiri. Jika Anda memodifikasi kartu ("penunjuk aritmatika"), yang dilakukannya hanyalah mengubah buku yang ditunjuknya dan tidak memiliki dampak pada buku itu sendiri - hanya berhati-hati untuk tidak mengacaukan alamat atau Anda mungkin menunjuk ke buku yang tidak ada. atau bahkan perpustakaan yang salah. Namun, jika Anda mengikuti "alamat" pada kartu dan pergi ke bagian perpustakaan yang tepat ("dereference the pointer"), Anda dapat melihat / memodifikasi buku itu sendiri.

Yevgeniy Brikman
sumber
1 untuk memori kursus CS saya di mana saya memiliki penjelasan itu
Gary Rowe
Memang bagus, tapi agak menyesatkan, karena kartunya tidak benar-benar mengatakan di mana buku itu berada. Anda masih perlu menjalankan algoritma pencarian berorientasi-sneaker. Mungkin ini lebih baik memodelkan basis data - merujuk ke objek yang disimpan dengan kunci (nomor panggilan).
DarenW
+1 Analogi ini mempertahankan konsep yang sama dengan yang dijelaskan oleh Barfieldmv tetapi dengan pendekatan kehidupan yang lebih nyata.
Karthik Sreenivasan
5

Saya akan berasumsi seseorang akan belajar pointer tahu apa variabel normal dan bagaimana mereka bekerja dalam C. Sekarang, mari kita coba mendefinisikan pointer dengan beberapa atribut itu-

  • Mereka juga variabel, tetapi sifatnya berbeda. Asumsikan ada dua lapisan dalam ruang variabel. Variabel normal dari berbagai jenis berada di lapisan atas dan pointer di lapisan bawah. Seperti gambar ini-

    teks alternatif

  • Seperti yang ditunjukkan oleh nama 'Pointer', pointer dapat POINT ke sesuatu. Seperti jari kita bisa menunjuk ke suatu objek. Hal-hal apa yang mereka tunjukkan? Ini adalah variabel normal. Singkatnya, "Pointer menunjuk ke variabel normal".

  • Seperti variabel normal, pointer juga memiliki jumlah tipe yang sama seperti int, char atau float. Dan pointer dari tipe tertentu hanya bisa menunjuk ke tipe variabel yang sama.
  • Pointer dapat menunjuk ke satu variabel dan kemudian pointer yang sama dapat menunjuk ke variabel lain. Hanya jenisnya harus sama. Jadi, hubungan pointer dengan beberapa variabel tidak permanen dan dapat diubah.
  • Jadi, bagaimana sebuah pointer dinyatakan? Hampir seperti variabel normal. Anda harus mengawali nama dengan tanda bintang ( *). Suka-

    int *pointer;
    
  • Lalu, bagaimana sebuah pointer dikaitkan dengan suatu variabel? Menggunakan &operator sebelum variabel seperti pernyataan ini-

    pointer = &variable;
    
  • Bagaimana pointer digunakan dengan menunjuk ke suatu variabel? Ini juga dilakukan dengan mengawali nama dengan tanda bintang ( *). Maka itu dapat digunakan di tempat variabel itu menunjuk sekarang-

    *pointer = var1 + var2;
    

    dari pada

    variable = var1 + var2;
    
  • Sekarang, mainkan dengan pointer dengan beberapa kode. Biasakan saja karakteristik pointer ini sekarang. Sampai pada titik ini, kita berbicara tentang apa yang pointer lakukan. Setelah Anda setuju, mulai pelajari bagaimana pointer menunjuk ke beberapa variabel dan bagaimana mereka bereaksi jika operasi aritmatika normal diterapkan pada mereka. Lalu pergi untuk hubungan antara pointer dan array dan pointer ke pointer.

Hanya itu yang akan saya sarankan tentang petunjuk pembelajaran.

Gulshan
sumber
Saya ingin mengikuti proses "pertama apa fungsinya lalu bagaimana". Abstraksi!
Gulshan
5

Diedit untuk mendukung persyaratan pertanyaan yang direvisi

Path saya untuk memahami "post-pointer" (jika saya ingat dengan benar) berjalan seperti ini. Saya memiliki beberapa pengalaman sederhana pemrograman perakitan dari ketika saya masih bercanda dengan BBC Micro jadi saya memiliki konsep memori sebagai sekelompok kotak (lihat di bawah ini untuk ini). Ini diperkuat oleh penggunaan array. Namun, saya pergi ke dunia C dan harus berurusan dengan string dan itu berarti petunjuk. Dalam BASIC ini sepele, di assembler saya tidak pernah harus bekerja dengan mereka, dan sekarang di C klasik itu semua petunjuk dan hal-hal. Ah, tapi saya bisa kembali ke array dengan (null terminated) string seperti ini:

char s[] = "Hello, world!";
printf("%s",s);

Semua baik dan bagus, itu hanya array karakter (8 bit per karakter di dunia kecilku) dengan karakter nol di akhir untuk menunjukkan di mana ia berakhir. Printf hanya mengambil array itu dan menjalankannya mencetaknya. Tetapi bagaimana jika saya ingin meneruskan string ini ke suatu fungsi?

void print_str(char* p) {
  printf("%s",p);
}

Apakah yang dikatakan manual, tetapi tentang apa itu *? Hmm, char * berarti "pointer ke char". OKE ... kehilangan saya. Kemudian saya sadar bahwa char * membuat p sama dengan s [0]. OK, saya bisa menggunakannya, tapi saya masih belum tahu apa artinya. Maksud saya, bagaimana cara mengatur beberapa data dengan salah satu dari hal-hal ini? Pergi ke manual lagi ...

char* p = "Hello World!";

Saat saya menulis di atas, saya berkata pada diri sendiri "menyatakan pointer ke char dan mengaturnya sama dengan array karakter ini". Entah bagaimana pointer itu menghilangkan kebutuhan akan sebuah array. Kira kompiler melakukan beberapa hal untuk saya untuk perubahan. Jadi bagaimana saya bisa mengubah array dengan pointer ini? Saya tahu bahwa saya bisa menggunakan versi array

 s[2] = 'L'; 

tapi apa yang setara dalam "pointer speak"? Pergi ke manual itu lagi ...

*(p+2) = 'L';

Saya kira itu * hanya berarti "isi dari alamat memori" dan (p+2)adalah s[2]. Yang berarti bahwa pointer p adalah ... hanya ... alamat ... bong!

Bahwa ada suara pencerahan. Saya tiba-tiba memutar pointer (sudah lama sekali, kami timer lama tidak "grok" sampai nanti). Itu hanya tipuan.


Asli:

OK, nilai 2c saya:

Bayangkan memori adalah banyak kotak. Setiap kotak memiliki nomor di samping (alamat). Setiap kotak berisi angka (konten). Anda dapat bekerja dengan kotak-kotak ini dalam 2 cara: variabel (saya ingin isi kotak N), pointer (saya ingin isi kotak apa pun yang ada di kotak N ). Pointer hanyalah tipuan.

Dan untuk jawaban besar yang mencakup semua yang perlu Anda ketahui - baca ini .

Gary Rowe
sumber
++ Itu kurang lebih cara saya mengajar subjek.
Mike Dunlavey
Artikel yang diedit untuk mendukung persyaratan OP.
Gary Rowe
Manual mana yang Anda gunakan yang menambahkan karakter NUL tambahan di akhir string Anda?
Rob Gilliam
@raimesh Yang sangat lama (sekitar 1991). Tidak ingat yang mana
Gary Rowe
1991? Itu tidak lama untuk manual bahasa C - edisi pertama K&R diterbitkan pada tahun 1978! Hanya tertarik bahwa pernah ada manual di luar sana yang menyarankan Anda perlu meletakkan \ 0 di akhir konstanta string Anda. (Sebenarnya, melihatnya lagi, apakah Anda bermaksud mengatakannya?)
Rob Gilliam
4

Dapatkan beberapa balok kayu.

tambahkan kait logam ke satu ujung, dan mata logam ke ujung lainnya.

Anda sekarang dapat melakukan daftar tertaut dalam hal-hal yang dapat Anda mainkan.

Coba jelaskan dengan alat fisik ini. Saya sering berharap saya memiliki ini ketika mengajar petunjuk untuk siswa tahun pertama (mahasiswa baru).

Kait logam kecil adalah penunjuknya, balok kayu yang ditunjuknya.

Saya MENGHANCURKAN siapa pun untuk tidak mendapatkannya setelah bermain dengan balok.

Tim Williscroft
sumber
4

Saya membuat hidup saya lebih mudah ketika saya baru saja menghapus semua bulu dan mulai memperlakukan pointer sebagai variabel lain daripada entitas ajaib (lama di kelas 11) .. hanya tahu 3 hal:

  1. Pointer adalah variabel yang menyimpan alamat variabel lain (atau sembarang alamat).
  2. * digunakan untuk mendapatkan nilai di lokasi memori yang disimpan dalam variabel pointer.
  3. & operator memberikan alamat lokasi memori.

Sisanya adalah gula sintaksis dan akal sehat .. Hanya menulis beberapa program C sederhana (seperti menerapkan perpustakaan daftar tertaut) menggunakan pointer untuk memahami itu.

Sridhar Iyer
sumber
2
  1. Pointer dapat dianggap sebagai generalisasi indeks ke dalam array.
    • Pertimbangkan bahwa array besar dapat dipotong menjadi sejumlah array yang lebih kecil, tidak tumpang tindih, dan berukuran variabel. Sekarang, array yang lebih kecil ini adalah apa yang biasanya kita anggap sebagai array. Yang lebih besar adalah seluruh ruang memori komputer. Proses memotong array yang lebih kecil disebut alokasi memori.
  2. Seperangkat struktur yang dihubungkan bersama oleh beberapa pointer dapat dianggap sebagai grafik berarah .
    • Setiap dhuwur adalah variabel yang dapat menampung beberapa nilai.
    • Beberapa variabel adalah pointer, dan masing-masing pointer dapat memiliki tepat satu tepi keluar menjadi sesuatu yang lain.
    • Variabel yang bukan pointer tidak akan memiliki tepi keluar. Mereka dapat memiliki sejumlah tepi yang masuk.
rwong
sumber
2

Saya tidak begitu ingat keadaan di sekitar pointer-aha-moment saya, tetapi saya telah secara retroaktif mengisi memori sekitar pemahaman saya tentang array c-style. (yaitu arr[3]sama dengan *(arr+3))

Untuk beberapa alasan saya merasa sangat membantu untuk melihat pointer sebagai array setiap kali saya terjadi pada situasi pointer.

Zaz
sumber
2

Pada dasarnya @Gary Rowe memperkenalkan model yang tepat. Memori sebagai satu set kotak dengan alamat (angka) di dalamnya. Setiap kotak menyimpan nilai (angka).

Ide pointer adalah menafsirkan nilai dalam satu kotak sebagai alamat dari kotak lain. Nilai ini digunakan untuk merujuk ke kotak tertentu, itulah sebabnya itu disebut referensi . Jadi dereferencing adalah proses membuka kotak yang dirujuk.

jika vvariabel (kotak), maka pernyataan

  • vberarti nilai v, yaitu memberi saya apa yang ada di dalam kotak
  • *vberarti dereference nilai v, yaitu memberi saya apa yang ada di dalam kotak yang dirujuk oleh nilaiv
  • &vberarti referensi v, yaitu beri saya alamat di kotak

Saya pikir itu bukan server tujuan memperkenalkan pointer sebagai sesuatu yang sama sekali berbeda. Itu adalah konsep yang sulit dipahami bagi saya ketika saya masih kecil. Itu selalu tampak seperti sihir gelap yang tidak pernah benar-benar kupahami, yang membutuhkan banyak karakter khusus. Pertama kali saya mengerti adalah ketika saya menulis permainan kecil menggunakan tipuan ganda dalam bahasa yang tidak memiliki aritmatika pointer. Itu mencerahkan saya.

Pointer adalah masalah interpretasi. Saya pikir menjelaskan hal itu membuat banyak hal lebih mudah. Dan pointer arithmetics adalah operasi yang sangat sederhana dan intuitif jika ditunjukkan contoh sederhana dengan memori 10 variabel.

back2dos
sumber
2

Penjelasan bahwa saya benar-benar terpesona adalah:

Pertimbangkan sebuah kotak kota dengan rumah-rumah berbeda yang dibangun di atas tanah. Di tangan Anda, Anda memegang selembar kertas. Di atas kertas yang telah Anda tulis:


Rumah David,

112 Begitu dan begitu jalan.


Selembar kertas (variabel penunjuk) berisi alamat yang menunjuk ke rumah David. Ketika Anda ingin memberi tahu seorang teman untuk melihat rumah keren David, jauh lebih mudah menggunakan pice kertas sebagai referensi ke rumah daripada mengirim bangunan berlantai dua yang sebenarnya melalui pos.

Seperti halnya pointer nyata, Anda bisa mendapatkan masalah ketika Anda mengikuti alamat di selembar kertas. David bisa saja bergerak dan ketika Anda sampai di sana Anda hanya menemukan lubang besar di tanah. Dalam hal ini akan lebih baik untuk menghapus alamat di atas kertas ketika David pindah atau setidaknya mengubahnya ke yang baru. Anda juga dapat menemukan bahwa Anda pergi ke alamat dan memasukkan apa yang Anda pikir adalah ruang tamu teman Anda David, tetapi kali ini Anda berakhir di kolam renang yang benar-benar asing. Orang lain telah menggunakan ruang di alamat yang Anda miliki untuk sesuatu yang sama sekali berbeda.

Per Wiklander
sumber
2

Jika Anda ingin menjelaskan pointer Anda harus menjelaskan memori terlebih dahulu. Saya biasanya melakukannya dengan menggunakan kertas grafik / kertas kuadrat dengan baris dan kolom. Jika "siswa" mengerti ingatan dia bisa mengerti apa alamat itu. Jika Anda mendapat alamat, Anda mendapat petunjuk.

Anda dapat bermain dengan abstraksi ini. Misalnya tulis alamat (nomor) dari satu kotak ke kotak lain. Sekarang gambar panah dari kotak pointer ke kotak tujuan. Sekarang timpa pointer (mis. Increment it) dan sesuaikan panah. Tulis alamat ke kotak lain dan biarkan siswa menggambar panah ...

Langkah selanjutnya: Beri nama kotak (seperti pointer) tertentu. Sekarang Anda bisa menjelaskan dereferencing. Itu dia.

EricSchaefer
sumber
2
Mengingatkan saya pada "komputer" yang saya gunakan sebelum saya bisa mendapatkan satu komputer yang benar-benar menggunakan elektron - kardus "CARDIAC" Saya pikir itu disebut. Secara harfiah, menulis angka dalam kotak bernomor untuk mendapatkan nomor dari kotak bernomor lainnya. Ini adalah pendidikan dan saya tidak pernah mengalami kesulitan memahami petunjuk tentang mikroprosesor nyata.
DarenW
2

Mungkin hanya saya, tetapi saya bekerja dengan baik dengan analogi. Jadi katakanlah Anda memiliki teman (fungsi / kelas) "Foo", yang ingin memiliki orang lain (fungsi / kelas yang berbeda), "Bar", menghubungi Anda untuk beberapa alasan. "Foo" bisa membawamu untuk pergi melihat "Bar", tapi itu tidak nyaman, menggerakkan semua makhluk (contoh) di sekitar. Namun, "Foo" dapat mengirim "Bar" nomor telepon Anda (pointer). Dengan begitu, di mana pun Anda berada, "Foo" tahu cara menghubungi Anda tanpa harus menemukan Anda.

Dan, katakanlah "Bar" memiliki kenalan, "Baz", yang juga ingin menghubungi Anda. Tetapi Anda melindungi nomor telepon Anda dan Anda tidak ingin semua orang memilikinya, "Baz" dapat memanggil "Bar" (telepon sebagai penunjuk), yang kemudian dapat meneruskan panggilan kepada Anda (penunjuk lain). Dan seterusnya dan terus ke bawah rantai teman "Baz" dan teman dari teman.

Hugo
sumber
2

Pointer jauh lebih masuk akal jika Anda telah mempelajari bahasa assembly dan / atau arsitektur komputer. Saya pikir jika saya mengajar kelas C, saya akan mulai dengan beberapa minggu arsitektur untuk menjelaskan model memori dan jenis instruksi yang sebenarnya dijalankan prosesor.

Barry Brown
sumber
Benar. Ketika Anda berurusan dengan register, dan memahami hal-hal seperti nilai langsung dan pengalamatan tidak langsung, seluruh konsep pointer adalah intuitif. Saya belajar 6502 perakitan dan kemudian 68K perakitan sebelum menulis baris C pertama saya, jadi pada saat saya diperkenalkan dengan pointer, saya melihat perakitan kompiler (menengah) dan persis seperti yang diharapkan.
Radian
2

"Aha!" momen datang dalam tutorial ini:

Tutorial tentang Pointer dan Array di C

Tepatnya, itu datang dalam bab ini: Bab 3: Pointer dan String

Untuk lebih tepatnya, itu datang dengan kalimat ini:

Parameter yang diteruskan ke puts () adalah sebuah pointer, yaitu nilai dari sebuah pointer (karena semua parameter dalam C dilewatkan oleh nilai), dan nilai sebuah pointer adalah alamat yang ditunjuknya, atau, secara sederhana, sebuah alamat .

Ketika saya membaca itu, awan membelah dan malaikat meniupkan terompet.

Karena, Anda tahu, setiap tutorial atau buku C yang saya baca sebelum yang menyatakan bahwa C dapat melewati nilai atau dengan referensi, kebohongan jahat. Yang benar adalah bahwa C selalu melewati nilai, tetapi kadang-kadang nilai yang lewat adalah alamat. Dalam metode ini, salinan dibuat dari alamat itu, seperti salinan yang akan dibuat dari int yang dilewatkan. Salinan tidak dibuat dari nilai yang ditunjukkan oleh pointer. Jadi dengan menggunakan pointer di dalam metode Anda dapat mengakses nilai asli dan mengubahnya.

Saya tidak pernah menjadi programmer C, tapi saya menjadi programmer. NET, dan objek dan referensi objek bekerja dengan cara yang sama; referensi ke objek dilewatkan oleh nilai (dan karenanya disalin), tetapi objek itu sendiri tidak disalin. Saya telah bekerja dengan banyak programmer yang tidak mengerti ini karena mereka tidak pernah belajar pointer.

Kyralessa
sumber
1

Caranya adalah dengan menjelaskan bahwa lokasi suatu benda dan benda itu sendiri tidak sama, seperti halnya gambar pipa bukan pipa . Ketika Anda memindahkan sesuatu, lokasinya berubah. Lokasi tetap dan beberapa hal lain dapat diletakkan di sana.

sal
sumber
1

Pointer adalah catatan tempel yang memberi tahu Anda di mana sesuatu yang berguna berada. Ini berisi lokasi benda itu dan memberi tahu Anda seberapa besar benda itu (dalam bahasa C, pokoknya). Jadi, penunjuk ganda seperti catatan tempel yang bertuliskan "Ada enam bungkus di lemari es". Anda harus benar-benar mendapatkan enam paket untuk mengetahui apakah itu Coke atau Budweiser.

philosodad
sumber
1

Diberi kode:

int v=42; // mendeklarasikan dan menginisialisasi variabel sederhana

int *p = &v; // membuat titik p ke variabel v

Berikut ini dapat dikatakan tentang kode di atas:

int * p // "int pointer p" ... ini adalah bagaimana Anda mendeklarasikan pointer ke variabel tipe int

*p // "ditunjukkan oleh p" ... itu adalah data yang menunjuk ke p, sama dengan v.

&v // "alamat variabel v" ... ini mewakili nilai literal untuk p

zener
sumber
1

http://cslibrary.stanford.edu/

Situs ini memiliki tutorial yang bagus untuk mempelajari petunjuk dan manajemen memori.

Saya akan menyarankan Anda untuk berjalan melalui dasar-dasar petunjuk, petunjuk dan memori yang diberikan di situs. Anda juga dapat melihat masalah daftar tertaut yang diberikan pada tautan untuk lebih memperkuat konsep penunjuk.

deovrat singh
sumber
1

Kunci untuk menjelaskan petunjuk adalah memastikan bahwa orang yang Anda jelaskan, sudah memiliki pemahaman tentang konsep memori. Meskipun akan lebih baik jika mereka benar-benar memahaminya level rendah, percaya bahwa memori ada sebagai array besar, dan memahami bahwa Anda dapat mengakses posisi apa pun dalam array dengan lokasi indeksnya sudah cukup.

Langkah selanjutnya, memiliki konsep melewati lokasi indeks daripada menyalin seluruh memori masuk akal bagi kebanyakan orang. Dan itu sudah cukup untuk membuat kebanyakan orang mengerti mengapa pointer berguna.

langkah terakhir untuk memahami pointer adalah menjelaskan bagaimana Anda dapat meneruskan sebagai parameter lokasi indeks memori untuk metode untuk menyimpan lokasi indeks untuk tempat semua data disimpan. Saya telah menemukan bahwa ini bisa menjadi langkah yang terlalu jauh bagi beberapa orang untuk mengatasinya.

Begitu seseorang telah memahami langkah-langkah dasar ini, langkahnya lurus ke depan bagi mereka untuk memahami bahwa Anda dapat menghubungkan pointer tanpa batas, selama Anda melacak berapa kali Anda perlu melihat alamat untuk menemukan objek data aktual.

Begitu seseorang telah memegang pointer, hal berikutnya yang harus mereka pegang dengan cepat adalah perbedaan antara tumpukan memori dan tumpukan memori, dan mengapa pointer ke tumpukan memori berbahaya ketika melewati di luar metode.

Michael Shaw
sumber
0

Saya ingat buku "C puzzle" atau sejenisnya, yang saya baca murni karena itu adalah salah satu dari sedikit buku terkait pemrograman / komputer yang tersedia di perpustakaan, pemahaman saya tentang C masih belum sempurna. Itu melemparkan C expresison pada Anda, dan meminta untuk menjelajahinya, semakin rumit.

Peterchen
sumber
0

Ketika saya di universitas, profesor saya memiliki beberapa slide powerpoint yang benar-benar rapi menggambarkan titik sebagai variabel yang terpisah dengan panah ke lokasi memori (diwakili seperti array) dan ketika kami melakukan Linked Lists, dia akan melakukannya langkah -dengan-langkah, menunjukkan ketika panah berubah, ketika pointer dereferenced dll ..., tidak ada cara orang tidak bisa memahaminya dalam beberapa menit. Konsep itu sendiri sangat mudah, tetapi melakukannya dengan benar atau menerapkannya dalam program praktis membutuhkan lebih banyak latihan.

chiurox
sumber
0

Sebelum saya melakukan itu, saya menjelaskan bahwa dalam pemrograman "semuanya menggunakan memori", dan alokasi variabel (statis) dalam memori. Saya juga akan menjelaskan apa alamat memori itu, dan hubungan antara ruang memori, alamat memori dan variabel.

Akhirnya, saya jelaskan bahwa ada tipe data dan variabel integer, tipe data string dan variabel ... dan seterusnya, hingga menjelaskan bahwa ada tipe data khusus yang menyimpan alamat memori, yang memiliki nilai kosong seperti 0 o "",, disebut null .

Dan, akhirnya, variabel yang dialokasikan secara dinamis melalui penggunaan pointer.

umlcat
sumber