>> [Bermain muzik]
>> DOUG LLOYD: Penunjuk, di sini kita berada.
Ini mungkin akan menjadi topik yang paling sukar
bahawa kita bercakap kira-kira dalam CS50.
Dan jika anda telah membaca apa-apa mengenai petunjuk
sebelum anda mungkin menjadi sedikit menakutkan pergi ke video ini.
Memang benar petunjuk yang membolehkan anda keupayaan
untuk mungkin skru sehingga cukup teruk apabila anda berada
bekerja dengan pembolehubah, dan data, dan menyebabkan program anda crash.
Tetapi mereka benar-benar benar-benar berguna dan mereka membenarkan kita cara yang benar-benar hebat
untuk lulus data kembali dan alik antara fungsi,
bahawa kita jika tidak dapat berbuat.
>> Dan supaya apa yang kita benar-benar mahu lakukan di sini adalah kereta api
anda mempunyai disiplin penunjuk yang baik, jadi yang boleh anda gunakan petunjuk berkesan
untuk membuat program-program anda yang lebih baik.
Seperti yang saya katakan petunjuk memberikan kita berbeza cara untuk lulus data antara fungsi.
Sekarang jika anda ingat dari video yang lebih awal, apabila
kita bercakap tentang skop berubah-ubah, yang saya sebutkan
bahawa semua data yang kita melepasi antara fungsi dalam C diluluskan oleh nilai.
Dan saya tidak mungkin telah digunakan yang jangka panjang, apa yang saya maksudkan di sana
adalah bahawa kita sedang dalam perjalanan salinan data.
Apabila kita lulus pembolehubah ke fungsi, kita sebenarnya tidak lulus pembolehubah
untuk majlis itu, bukan?
Kita lulus salinan bahawa data ke majlis itu.
Majlis tersebut melakukan apa yang ia akan dan ia mengira beberapa nilai,
dan mungkin kita menggunakan nilai yang apabila ia memberi kembali.
>> Terdapat satu pengecualian kepada peraturan ini lulus dengan nilai,
dan kami akan kembali kepada apa yang adalah sedikit kemudian di dalam video ini.
Jika kita menggunakan petunjuk dan bukannya menggunakan pembolehubah,
atau daripada menggunakan pembolehubah diri sendiri atau salinan pembolehubah,
kita kini boleh lulus pembolehubah sekitar antara fungsi dalam cara yang berbeza.
Ini bermakna bahawa jika kita membuat perubahan dalam satu fungsi,
perubahan yang benar-benar akan mengambil melaksanakan fungsi yang berbeza.
Sekali lagi, ini adalah sesuatu yang kita tidak boleh melakukannya sebelum ini,
dan jika anda pernah mencuba untuk menukar nilai dua pembolehubah dalam fungsi,
anda dapati masalah ini jenis menjalar, bukan?
>> Jika kita mahu menukar X dan Y, dan kami menyampaikannya kepada fungsi yang dipanggil swap,
dalam fungsi yang menukar pembolehubah melakukan nilai pertukaran.
Satu menjadi dua, dua menjadi satu, tetapi kita tidak benar-benar
mengubah apa-apa dalam asal fungsi, dalam pemanggil.
Kerana kita tidak boleh, kami hanya bekerja dengan salinan-salinannya.
Dengan petunjuk walaupun, kita boleh sebenarnya lulus X dan Y ke fungsi.
Fungsi yang boleh dilakukan sesuatu dengan mereka.
Dan nilai-nilai pembolehubah sebenarnya boleh berubah.
Supaya agak perubahan dalam keupayaan kita untuk bekerja dengan data.
>> Sebelum kita menyelam ke dalam petunjuk, saya fikir ia adalah bernilai
mengambil masa beberapa minit untuk kembali kepada asas di sini.
Dan kita lihat bagaimana kerja-kerja memori komputer
kerana kedua-dua mata pelajaran yang akan untuk benar-benar menjadi cukup saling berkaitan.
Seperti yang anda mungkin tahu, pada sistem komputer anda
anda mempunyai pemacu keras atau mungkin satu pemacu keadaan pepejal,
semacam lokasi penyimpanan fail.
Ia biasanya di suatu tempat di kejiranan 250 gigabait
untuk mungkin beberapa terabytes sekarang.
Dan ia adalah di mana semua anda fail akhirnya hidup,
walaupun komputer anda ditutup di luar, anda boleh hidupkannya semula
dan anda akan mendapati fail anda berada di sana sekali lagi apabila anda reboot sistem anda.
Tetapi pemacu cakera, seperti pemacu cakera keras, HDD, atau pemacu keadaan pepejal, SSD,
adalah ruang simpanan adil.
>> Kita tidak boleh benar-benar melakukan apa-apa dengan data yang ada dalam cakera keras,
atau dalam pemacu keadaan pepejal.
Dalam usaha untuk benar-benar mengubah data atau bergerak di sekitar,
kita perlu bergerak ke RAM, capaian ingatan rawak.
Sekarang RAM, anda mempunyai banyak kurang dalam komputer anda.
Anda mungkin mempunyai suatu tempat di kawasan kejiranan 512 megabait
jika anda mempunyai komputer yang lebih tua, kepada mungkin dua, empat, lapan, 16,
mungkin juga sedikit lanjut, gigabait RAM.
Jadi, itu jauh lebih kecil, tetapi itu di mana semua data yang tidak menentu wujud.
Itulah di mana kita boleh mengubah keadaan.
Tetapi apabila kita menghidupkan komputer kita di luar, semua data dalam RAM dimusnahkan.
>> Jadi itulah sebabnya kita perlu mempunyai cakera keras untuk lokasi yang lebih kekal daripada itu,
supaya ia wujud- ia akan menjadi benar-benar buruk jika setiap kali kita
bertukar komputer kita di luar, setiap fail dalam sistem kami telah dipadamkan.
Oleh itu, kita bekerja di dalam RAM.
Dan setiap kali kita bercakap tentang ingatan, cukup banyak, di CS50,
kita berbicara tentang RAM, bukan cakera keras.
>> Oleh itu, apabila kita bergerak sesuatu ke dalam ingatan, ia mengambil masa sehingga jumlah tertentu ruang.
Semua jenis data yang kita telah bekerja dengan
mengambil yang berbeza jumlah ruang dalam RAM.
Jadi setiap kali anda membuat integer berubah-ubah, empat bait memori
diketepikan dalam RAM supaya anda boleh bekerja dengan integer itu.
Anda boleh mengisytiharkan integer, mengubahnya, sediakan
kepada nilai 10 incremented demi satu, sebagainya dan sebagainya.
Semua yang perlu berlaku dalam RAM, dan anda mendapat empat bait
untuk bekerja dengan untuk setiap integer yang anda buat.
>> Setiap watak anda mewujudkan mendapat satu bait.
Itu hanya berapa banyak ruang yang yang diperlukan untuk menyimpan watak.
Setiap terapung, yang sebenar nombor, mendapat empat bait
melainkan jika ia adalah dua ketepatan titik terapung
nombor, yang membolehkan anda untuk mempunyai angka yang lebih tepat atau lebih
selepas titik perpuluhan tanpa kehilangan ketepatan,
yang mengambil masa sehingga lapan bait ingatan.
Roh meronta-ronta Long, bilangan bulat yang sangat besar, juga mengambil lapan bait ingatan.
Berapa banyak bait memori jangan rentetan mengambil?
Nah mari kita meletakkan pin dalam soalan yang buat masa ini, tetapi kita akan kembali kepadanya.
>> Jadi kembali kepada idea ini memori pelbagai besar sel-sel bait dapur.
Itu benar-benar semua itu, adalah hanya pelbagai besar sel-sel,
seperti mana-mana lokasi lain yang anda biasa dengan dan lihat,
kecuali setiap elemen adalah satu bait luas.
Dan seperti array, setiap elemen mempunyai alamat.
Setiap elemen array mempunyai indeks, dan kami
boleh menggunakan indeks bahawa untuk melakukan apa yang dipanggil capaian rawak pada array.
Kami tidak perlu bermula pada permulaan array,
melelar melalui setiap elemen tunggal itu,
untuk mencari apa yang kita cari.
Kami hanya boleh berkata, saya mahu untuk sampai ke Unsur-15 atau unsur ke-100.
Dan anda hanya boleh lulus dalam jumlah itu dan mendapatkan nilai yang anda cari.
>> Begitu juga setiap lokasi dalam ingatan mempunyai alamat.
Jadi ingatan anda mungkin melihat sesuatu seperti ini.
Berikut adalah sebahagian yang sangat kecil memori, ini adalah 20 bait ingatan.
20 bait pertama kerana saya menangani terdapat di bahagian bawah
0, 1, 2, 3, dan sebagainya pada semua jalan sehingga ke 19.
Dan apabila saya mengisytiharkan pembolehubah dan apabila saya mula bekerja dengan mereka,
sistem ini akan menetapkan mengetepikan sedikit ruang untuk saya
dalam ingatan ini untuk bekerja dengan pembolehubah saya.
Jadi saya mungkin berkata, char c sama dengan modal H. Dan apa yang akan berlaku?
Well sistem akan diperuntukkan untuk saya satu bait.
Dalam kes ini ia memilih bilangan bait empat, bait di alamat empat,
dan ia akan menyimpan H modal surat di sana untuk saya.
Jika saya kemudian berkata kelajuan int had sama dengan 65, ia adalah
akan mengetepikan empat bait memori untuk saya.
Dan ia akan jadikan orang-orang empat bait sebagai satu unit tunggal
kerana apa yang kita sedang berusaha dengan adalah integer di sini.
Dan ia akan menyimpan 65 di sana.
>> Kini sudah saya jenis memberitahu anda sedikit pembohongan,
betul, kerana kita tahu bahawa komputer bekerja dalam perduaan.
Mereka tidak faham semestinya apa yang H modal adalah
atau apa yang 65 adalah, mereka hanya memahami binari, sifar dan satu.
Dan sebagainya sebenarnya apa kita menyimpan di sana
tidak H huruf dan nombor 65, tetapi perwakilan perduaan
itu, yang kelihatan sedikit sesuatu seperti ini.
Dan khususnya dalam konteks pembolehubah integer,
ia tidak akan hanya meludah ke dalam, ia tidak akan menganggap ia sebagai satu empat
bait sebahagian semestinya, ia sebenarnya akan
untuk merawat ia sebagai satu ketulan empat bait, yang mungkin kelihatan seperti ini.
Dan walaupun ini tidak sepenuhnya benar sama ada,
kerana sesuatu yang dipanggil yang endianness, yang kita tidak
akan masuk ke dalam sekarang, tetapi jika anda ingin tahu tentang,
anda boleh membaca tentang sedikit dan endianness besar.
Tetapi demi hujah ini, demi video ini,
mari kita hanya menganggap bahawa, dalam Malah, berapa jumlah 65 akan
diwakili dalam memori pada setiap sistem,
walaupun ia tidak sepenuhnya benar.
>> Tetapi mari kita sebenarnya hanya mendapat menghilangkan semua binari sepenuhnya,
dan hanya berfikir tentang sebagai H dan 65, ia adalah lebih mudah
untuk berfikir mengenainya seperti bahawa sebagai seorang manusia.
Baiklah, jadi ia juga seolah-olah mungkin satu sedikit rawak yang I've- sistem saya
tidak memberi saya bytes 5, 6, 7, dan 8 untuk menyimpan integer.
Ada sebab untuk itu, juga, yang kami tidak akan masuk ke dalam sekarang, tetapi memadai
untuk mengatakan bahawa apa yang komputer lakukan di sini
mungkin satu langkah yang baik di pihaknya.
Untuk tidak memberi saya ingatan itulah semestinya belakang untuk kembali.
Walaupun ia akan melakukannya sekarang jika saya ingin mendapatkan tali lain,
dipanggil nama keluarga, dan saya mahu untuk meletakkan Lloyd di sana.
Saya akan perlu untuk memuatkan satu watak, setiap huruf itu
akan memerlukan satu watak, satu bait ingatan.
Jadi, jika saya boleh meletakkan Lloyd ke dalam pelbagai saya seperti ini saya cukup baik untuk pergi, bukan?
Apa yang hilang?
>> Ingatlah bahawa setiap rentetan kita bekerja dengan dalam C berakhir dengan garis miring sifar,
dan kita tidak boleh meninggalkan bahawa di sini, sama ada.
Kita perlu mengenepikan satu bait memori untuk memegang itu supaya kita
tahu bila rentetan kami telah berakhir.
Jadi sekali lagi perjanjian ini cara perkara-perkara
muncul dalam ingatan kekuatan menjadi sedikit rawak,
tetapi ia sebenarnya adalah bagaimana kebanyakan sistem direka.
Untuk beratur mereka dalam gandaan empat, atas sebab-sebab lagi
bahawa kita tidak perlu masuk ke dalam sekarang.
Tetapi ini, jadi memadai untuk mengatakan bahawa selepas tiga baris kod,
ini adalah apa memori mungkin kelihatan seperti.
Jika saya perlukan lokasi ingatan 4, 8, dan 12 untuk memegang data saya,
ini adalah apa yang ingatan saya mungkin kelihatan seperti.
>> Dan hanya terutamanya bengah di sini, apabila
kita berbicara tentang memori alamat kita biasanya
berbuat demikian dengan menggunakan tatatanda perenambelasan.
Jadi kenapa pula kita tidak menukar semua ini daripada perpuluhan kepada tatatanda perenambelasan
hanya kerana itulah umumnya bagaimana kita merujuk kepada ingatan.
Jadi, daripada menjadi 0 melalui 19, apa yang kita ada adalah sifar
x sifar melalui sifar x1 tiga.
Mereka adalah 20 bait memori yang kita telah atau kita melihat di dalam imej ini
di sini.
>> Jadi semua itu yang berkata, mari kita melangkah jauh dari memori untuk kali kedua
dan kembali kepada petunjuk.
Berikut adalah yang paling penting perkara yang perlu diingat
seperti yang kita mula bekerja dengan petunjuk.
Penunjuk A apa-apa lebih daripada satu alamat.
Saya akan katakan sekali lagi kerana itu yang penting,
penunjuk apa-apa lebih daripada satu alamat.
Penunjuk adalah alamat ke lokasi dalam ingatan di mana pembolehubah hidup.
Mengetahui bahawa ia menjadi mudah-mudahan sedikit lebih mudah untuk bekerja dengan mereka.
Satu lagi perkara yang saya suka lakukan adalah untuk mempunyai jenis
gambar rajah visual yang mewakili apa yang berlaku dengan pelbagai baris kod.
Dan kami akan melakukan ini pasangan kali dalam petunjuk,
dan apabila kita bercakap mengenai dinamik peruntukan ingatan juga.
Kerana saya berfikir bahawa gambar rajah ini boleh sangat membantu.
>> Jadi, jika saya berkata sebagai contoh, int k dalam kod saya, apa yang berlaku?
Baik apa yang pada dasarnya berlaku ialah Saya semakin diketepikan untuk saya ingatan,
tetapi saya tidak suka berfikir tentang hal seperti itu, saya
suka berfikir tentang hal itu seperti sebuah kotak.
Saya mempunyai kotak dan ia berwarna hijau kerana saya
boleh meletakkan bilangan bulat dalam kotak hijau.
Jika ia adalah watak yang saya mungkin mempunyai sebuah kotak biru.
Tetapi saya selalu berkata, jika saya mewujudkan kotak yang boleh menyimpan integer
kotak yang berwarna hijau.
Dan saya mengambil penanda kekal dan saya menulis k di sebelah itu.
Jadi saya mempunyai kotak yang dipanggil k, ke mana saya boleh meletakkan integer.
Oleh itu, apabila saya katakan int k, itu apa yang berlaku dalam kepala saya.
Jika saya katakan k sama dengan lima, apa yang saya buat?
Well, saya meletakkan lima dalam kotak, betul.
Ini adalah agak mudah, jika Aku berkata int k, membuat kotak yang dipanggil k.
Jika saya katakan k sama dengan 5, meletakkan lima ke dalam kotak.
Mudah-mudahan itu bukan terlalu banyak lonjakan.
Berikut adalah di mana perkara yang pergi sedikit menarik walaupun.
Jika saya katakan int * pk, baik walaupun saya tidak tahu apa ini semestinya bermaksud,
ia jelas mendapat sesuatu kaitan dengan bilangan bulat.
Jadi saya akan mewarnakan kotak hijau-ish,
Saya tahu ia mendapat sesuatu kaitan dengan integer,
tetapi ia bukan integer sendiri, kerana ia adalah satu bintang int.
Ada sesuatu yang sedikit berbeza mengenainya.
Begitu terlibat integer-kanak, tetapi jika tidak ia
tidak terlalu berbeza daripada apa yang kami katakan.
Ia kotak, yang mendapat label, ia memakai pk label,
dan ia mampu pegangan bintang int, apa sahaja mereka berada.
Mereka mempunyai sesuatu yang boleh dilakukan dengan bilangan bulat, dengan jelas.
Berikut adalah barisan terakhir walaupun.
Jika saya katakan pk = & k, wah, apa yang hanya berlaku, bukan?
Jadi nombor rawak ini, seolah-olah rawak nombor, akan dilemparkan ke dalam kotak di sana.
Segala yang ada, adalah pk mendapat alamat k.
Jadi, saya melekat di mana k hidup dalam ingatan, alamatnya, alamat bait itu.
Semua yang saya lakukan adalah saya katakan nilai yang apa yang saya akan
untuk diletakkan di dalam kotak dipanggil pk saya.
Dan kerana perkara-perkara ini petunjuk, dan kerana mencari
pada rentetan seperti sifar x lapan sifar c tujuh empat lapan
dua sifar mungkin tidak begitu bermakna.
Apabila kita biasanya menggambarkan petunjuk, kita benar-benar berbuat demikian kerana petunjuk.
Pk memberikan kita maklumat yang kita perlu mencari k dalam ingatan.
Jadi, pada asasnya pk mempunyai anak panah di dalamnya.
Dan jika kita hidup panjang anak panah itu, bayangkan
ia sesuatu yang anda boleh berjalan di atas, jika kita berjalan di sepanjang anak panah,
di hujung sangat anak panah itu, kami akan mencari lokasi dalam ingatan
di mana k hidup.
Dan itu benar-benar penting kerana sekali kita tahu di mana k yang hidup,
kita boleh mula bekerja dengan data yang bahagian dalam bahawa lokasi ingatan.
Walaupun kami mendapat pemudi yang sedikit lebih awal daripada diri kita sendiri buat masa ini.
>> Jadi apa penunjuk?
Penunjuk adalah satu item data yang nilai adalah alamat ingatan.
Itu ialah sifar x lapan barangan sifar berlaku, yang merupakan alamat ingatan.
Mereka itu adalah satu lokasi dalam ingatan.
Dan jenis penunjuk menerangkan kisah
data yang anda akan dapati di bahawa alamat ingatan.
Jadi ada bahagian kanan int bintang.
Jika saya ikut arah anak panah itu, ia akan membawa saya ke lokasi.
Dan lokasi itu, apa yang saya akan mendapati terdapat dalam contoh saya,
sebuah kotak berwarna hijau.
Ia adalah integer, itulah yang saya akan mencari jika saya pergi ke alamat tersebut.
Jenis data yang penunjuk menerangkan apa
anda akan dapati di bahawa alamat ingatan.
Jadi di sini adalah perkara yang benar-benar sejuk walaupun.
Penunjuk membolehkan kita untuk lulus pembolehubah antara fungsi.
Dan sebenarnya lulus pembolehubah dan tidak lulus salinan-salinannya.
Kerana jika kita tahu di mana dalam ingatan untuk mencari pembolehubah,
kita tidak perlu membuat salinan , kita hanya boleh pergi ke lokasi tersebut
dan bekerja dengan pembolehubah itu.
Jadi dalam petunjuk intipati jenis untuk membuat persekitaran komputer
lebih banyak seperti dunia sebenar, betul.
>> Jadi di sini adalah analogi.
Mari kita mengatakan bahawa saya mempunyai buku nota, betul, dan ia penuh dengan nota.
Dan saya mahu anda untuk mengemaskinikannya.
Anda di satu majlis yang kemas kini nota, betul.
Dengan cara yang kita telah kerja setakat ini, apa
berlaku ialah anda akan mengambil komputer riba saya, anda akan pergi ke kedai salinan,
anda akan membuat satu salinan Xerox daripada setiap halaman buku nota.
Anda akan meninggalkan notebook saya kembali di atas meja saya apabila anda selesai,
anda akan pergi dan garisan di atas perkara-perkara dalam saya buku nota yang sudah lapuk atau salah,
dan kemudian anda akan dapat kembali ke saya timbunan laman Xerox
iaitu replika buku nota saya dengan perubahan yang anda telah dibuat kepadanya.
Dan pada ketika itu, ia terpulang kepada saya sebagai fungsi panggilan, kerana pemanggil,
untuk membuat keputusan untuk mengambil nota dan mengintegrasikan mereka kembali ke dalam buku nota saya.
Jadi ada banyak langkah-langkah terlibat di sini, betul.
Seperti ia tidak akan menjadi lebih baik jika saya hanya berkata, hey, boleh anda
mengemas kini komputer riba saya untuk saya, menyerahkan engkau komputer riba saya,
dan anda mengambil barang-barang dan literal menyeberangi mereka keluar
dan mengemas kini nota saya dalam buku nota saya.
Dan kemudian memberi saya buku nota saya kembali.
Itulah jenis apa petunjuk membolehkan kita lakukan,
mereka membuat persekitaran ini banyak lebih seperti bagaimana kami beroperasi dalam realiti.
>> Baiklah demikian itulah yang penunjuk ini, mari kita bercakap
tentang bagaimana petunjuk bekerja di C, dan bagaimana kita boleh mula bekerja dengan mereka.
Jadi ada penunjuk yang sangat mudah dalam C dipanggil penunjuk nol.
Mata penunjuk null apa-apa.
Ini mungkin kelihatan seperti ia sebenarnya bukan satu perkara yang sangat berguna,
tetapi seperti yang kita akan melihat sedikit kemudian, hakikat
bahawa penunjuk null ini wujud sebenarnya memang boleh datang dengan mudah.
Dan setiap kali anda membuat penunjuk, dan anda tidak menetapkan immediately- nilai
contoh menetapkan nilai serta-merta
akan beberapa slaid kembali di mana saya berkata pk sama & k,
pk mendapat alamat k, sebagai kita akan melihat apa yang bermakna,
kita akan melihat bagaimana untuk kod yang shortly- jika kita tidak menetapkan nilai kepada sesuatu
bermakna serta-merta, anda perlu sentiasa
menetapkan penunjuk anda untuk menghala ke nol.
Anda perlu menetapkan ia untuk menunjukkan apa-apa.
>> Itu sangat berbeza daripada hanya meninggalkan nilai kerana ia adalah
dan kemudian mengisytiharkan penunjuk dan hanya andaian
ia batal kerana itulah jarang benar.
Oleh itu anda perlu sentiasa menetapkan nilai penunjuk
untuk menyeimbangkan jika anda tidak menetapkan nilai untuk sesuatu yang bermakna serta-merta.
Anda boleh menyemak sama ada nilai penunjuk ini adalah batal menggunakan operator kesamaan
(==), Seperti anda bandingkan mana-mana integer nilai-nilai atau nilai watak menggunakan (==)
juga.
Ia adalah satu jenis khas yang berterusan nilai yang boleh anda gunakan untuk menguji.
Sehingga adalah sangat mudah penunjuk, penunjuk null.
Cara lain untuk mewujudkan penunjuk adalah untuk mengeluarkan
alamat pembolehubah anda telah diwujudkan,
dan anda melakukan ini dengan menggunakan & operator pengeluaran alamat.
Yang kita telah melihat sebelum ini dalam contoh gambar rajah pertama yang saya menunjukkan.
Jadi, jika x ialah pembolehubah yang kita ada sudah mencipta jenis integer,
kemudian & x adalah penunjuk kepada integer.
& x ialah- ingat, & akan mengeluarkan alamat perkara yang di sebelah kanan.
Dan kerana penunjuk hanya alamat, daripada & x adalah penunjuk kepada integer
nilai yang adalah di mana dalam ingatan x nyawa.
Ia alamat x.
Jadi & x adalah alamat x.
Mari kita mengambil langkah ini satu lagi dan menyambung kepada sesuatu
Saya dirujuk kepada dalam video terlebih dahulu.
Jika arr adalah pelbagai beregu, maka & kurungan persegi arr i adalah penunjuk
kepada dua kali.
OKAY.
ARR kurungan persegi i, jika arr adalah pelbagai beregu,
kemudian arr kurungan persegi i adalah i-ke-elemen array itu,
dan & arr kurungan persegi i adalah di mana dalam memori i-ke-unsur daripada arr wujud.
>> Jadi apa implikasinya di sini?
Nama tatasusunan, implikasi daripada semua ini,
adalah bahawa nama pelbagai adalah sebenarnya sendiri penunjuk.
Anda telah bekerja dengan petunjuk selama ini
setiap kali anda telah menggunakan array.
Ingat dari contoh di kepada skop berubah-ubah,
di akhir video saya hadir contoh di mana kita mempunyai fungsi yang
dipanggil int set dan fungsi dipanggil lokasi yang ditetapkan.
Dan cabaran anda untuk menentukan sama ada atau tidak, atau apa yang
nilai-nilai yang kita dicetak akhir majlis itu,
pada akhir program utama.
>> Jika anda masih ingat daripada contoh yang atau jika anda telah menonton video itu,
anda tahu bahawa apabila anda-saat panggilan untuk int set berkesan tidak apa-apa.
Tetapi panggilan untuk menetapkan lokasi tidak.
Dan saya semacam dipoles begitu saja mengapa itulah yang berlaku pada masa itu.
Saya hanya berkata, baik ia array, ia khas, anda tahu, ada sebab-sebab.
Sebabnya ialah bahawa array ini nama adalah benar-benar hanya penunjuk,
dan ada ini khas persegi kurungan sintaks yang
membuat perkara yang lebih bagus untuk bekerja dengan.
Dan mereka menjadikan idea penunjuk banyak yang kurang menakutkan,
dan sebab mereka jenis daripada menyampaikan dengan cara itu.
Tetapi benar-benar tatasusunan hanya petunjuk.
Dan sebab itulah apabila kita membuat perubahan kepada array,
apabila kita meninggal array sebagai parameter fungsi atau sebagai hujah
ke fungsi, kandungan array sebenarnya berubah dalam kedua-dua CALLEE yang
dan pemanggil.
Yang bagi setiap jenis berubah-ubah yang kita lihat tidak berlaku.
Jadi itu hanya sesuatu yang perlu keberatan apabila anda bekerja dengan petunjuk,
ialah nama seorang lokasi sebenarnya penunjuk
kepada elemen pertama array itu.
>> OK jadi sekarang kita mempunyai semua fakta, mari kita terus pergi, betul.
Mengapa kita mengambil berat tentang di mana sesuatu yang hidup.
Well seperti saya katakan, ia agak berguna untuk mengetahui di mana sesuatu yang hidup
supaya anda boleh pergi ke sana dan mengubahnya.
Bekerja dengannya dan sebenarnya ada perkara yang anda
mahu lakukan untuk yang mengambil kesan berubah-ubah, dan tidak berkuat kuasa pada beberapa salinan.
Ini dipanggil dereferencing.
Kami pergi ke rujukan dan kita menukar nilai di sana.
Jadi, jika kita mempunyai penunjuk dan ia dipanggil pc, dan ia menjurus kepada watak,
maka kita boleh mengatakan pc * dan * pc adalah nama apa yang kita akan mencari jika kita pergi
ke pc alamat.
Apa yang kita akan dapati ada watak dan * pc adalah bagaimana kita merujuk kepada data pada itu
lokasi.
Oleh itu, kita boleh mengatakan sesuatu seperti * pc = D atau sesuatu seperti itu,
dan itu bererti bahawa apa sahaja adalah di alamat memori pc,
apa sahaja watak sebelum ini di sana, kini D, jika kita mengatakan * pc = D.
>> Jadi di sini kita pergi lagi dengan beberapa barangan C pelik, betul.
Oleh itu, kita telah lihat * sebelum ini sebagai entah bagaimana sebahagian daripada jenis data,
dan kini ia digunakan dalam konteks yang sedikit berbeza
untuk mengakses data pada lokasi.
Saya tahu ia sedikit mengelirukan dan yang sebenarnya sebahagian daripada keseluruhan ini
seperti, mengapa petunjuk mempunyai mitologi ini di sekeliling mereka sebagai yang begitu kompleks,
adalah jenis masalah sintaks, jujur.
Tetapi * digunakan dalam kedua-dua konteks, kedua-dua sebagai sebahagian daripada nama jenis,
dan kita akan melihat sedikit sesuatu kemudian yang lain, juga.
Dan sekarang adalah pengendali dereference.
Begitu seterusnya untuk rujukan, ia mengakses data
di lokasi penunjuk, dan membolehkan anda memanipulasi ia sesuka hati.
>> Sekarang ini adalah hampir sama dengan melawat jiran anda, betul.
Jika anda tahu apa yang anda jiran yang hidup, anda berada
tidak melepak dengan jiran anda.
Anda tahu anda berlaku untuk tahu di mana mereka tinggal,
tetapi itu tidak bermakna bahawa dengan kerana mempunyai pengetahuan yang
anda berinteraksi dengan mereka.
Jika anda ingin berinteraksi dengan mereka, anda perlu pergi ke rumah mereka,
anda perlu pergi ke mana mereka tinggal.
Dan apabila anda berbuat demikian, maka anda boleh berinteraksi
dengan mereka sama seperti yang anda akan mahu.
Begitu juga dengan pembolehubah, anda perlu pergi ke alamat mereka
jika anda mahu untuk berinteraksi mereka, anda tidak boleh hanya tahu alamat.
Dan cara anda pergi ke alamat ini digunakan *, pengendali dereference itu.
Apa yang anda fikir berlaku jika kita cuba dan dereference
penunjuk yang nilainya adalah batal?
Ingat bahawa null penunjuk menunjuk kepada apa-apa.
Jadi, jika anda cuba dan dereference apa-apa atau pergi ke apa-apa alamat,
apa yang anda fikir berlaku?
Segmentasi Baik jika anda fikirkan kesalahan, anda akan menjadi betul.
Jika anda cuba dan dereference penunjuk null,
anda mengalami segmentasi yang kesalahan. Tetapi tunggu,
saya tidak memberitahu anda, bahawa jika anda tidak akan
untuk menetapkan nilai anda anda penunjuk kepada sesuatu yang bermakna,
anda perlu bersedia untuk batal?
Yang saya lakukan dan benar-benar segmentasi kesalahan adalah jenis tingkah laku yang baik.
>> Pernahkah anda mengisytiharkan pembolehubah dan tidak diberikan nilai serta-merta?
Jadi, anda hanya mengatakan int x; anda tidak sebenarnya sediakan kepada apa-apa
dan kemudian kemudian di dalam kod anda, anda mencetak nilai x,
masih tidak mempunyai diberikan kepada apa-apa.
Kerap anda akan mendapat sifar, tetapi kadang-kadang anda
mungkin akan mendapat beberapa nombor rawak, dan anda tidak tahu dari mana datangnya.
Begitu juga perkara yang boleh berlaku dengan petunjuk.
Apabila anda mengisytiharkan penunjuk int * pk sebagai contoh,
dan anda tidak tetapkannya kepada nilai, anda mendapat empat bait untuk ingatan.
Apa sahaja yang empat bait memori sistem boleh
mendapati bahawa mempunyai nilai yang bermakna.
Dan mungkin ada sesuatu yang sudah ada yang
tidak lagi diperlukan oleh orang lain fungsi, jadi anda hanya perlu
apa sahaja data yang berada di sana.
>> Bagaimana jika anda cuba untuk melakukan dereference beberapa alamat yang anda don't- terdapat
sudah bait dan maklumat dalam di sana, yang kini dalam penunjuk anda.
Jika anda cuba dan dereference penunjuk bahawa, anda mungkin bermain-main dengan beberapa memori
bahawa anda tidak berniat main-main dengan itu semua.
Dan sebenarnya yang anda boleh lakukan sesuatu yang sangat dahsyat,
seperti memecahkan program lain, atau memecahkan fungsi yang lain,
atau melakukan sesuatu yang berniat jahat yang anda tidak berniat untuk melakukan sama sekali.
Dan itulah sebabnya mengapa ia sebenarnya adalah idea yang baik
untuk menetapkan petunjuk anda untuk batal jika anda tidak menetapkan mereka untuk sesuatu yang bermakna.
Ia mungkin lebih baik di akhir hari untuk program anda
crash maka untuk ia lakukan sesuatu yang skru sehingga
program lain atau fungsi yang lain.
Tingkah laku yang mungkin walaupun kurang sesuai daripada hanya terhempas.
Dan itulah sebabnya mengapa ia sebenarnya satu tabiat yang baik
untuk masuk ke dalam untuk menetapkan petunjuk anda untuk menyeimbangkan jika anda tidak menetapkan mereka
kepada nilai yang bermakna serta-merta, nilai yang anda tahu
dan bahawa anda boleh dengan selamat dereference itu.
>> Jadi mari kita kembali sekarang dan kita lihat di sintaks keseluruhan keadaan.
Jika saya katakan int * p ;, apa yang telah saya buat?
Apa yang saya lakukan adalah ini.
Saya tahu nilai p adalah alamat kerana semua petunjuk hanyalah
alamat.
Saya boleh dereference p menggunakan operator * itu.
Dalam konteks ini di sini, sekurang- bahagian ingat * adalah sebahagian daripada jenis.
Int * adalah jenis data.
Tetapi saya boleh dereference p menggunakan operator * itu,
dan jika saya berbuat demikian, jika saya pergi ke alamat itu, apa yang saya akan mencari di alamat itu?
Saya akan mencari integer.
Jadi int * p pada dasarnya berkata, p ialah alamat.
Saya boleh dereference p dan jika Saya lakukan, saya akan mencari integer
di lokasi itu ingatan.
>> OK jadi saya berkata terdapat satu lagi Perkara yang menjengkelkan dengan bintang
dan di sini adalah di mana yang Perkara yang menjengkelkan dengan bintang adalah.
Pernahkah anda cuba untuk mengisytiharkan beberapa pembolehubah dari jenis yang sama
pada baris yang sama kod?
Jadi untuk kali kedua, berpura-pura bahawa garisan, kod yang saya sebenarnya telah ada dalam hijau
tidak ada dan ia hanya berkata int x, y, z ;.
Apa yang akan dilakukan adalah sebenarnya mewujudkan tiga pembolehubah integer untuk anda,
satu dipanggil x, satu dipanggil y, dan satu dipanggil z.
Ia adalah satu cara untuk melakukannya tanpa perlu berpecah ke tiga baris.
>> Berikut adalah di mana bintang mendapatkan menjengkelkan lagi walaupun,
kerana * adalah sebenarnya sebahagian kedua-dua nama jenis dan bahagian
nama yang berubah-ubah.
Dan jadi jika saya katakan int * px, py, pz, apa yang saya benar-benar mendapatkan adalah penunjuk kepada integer
dipanggil px dan dua integer, py dan pz.
Dan itu mungkin tidak apa kita mahu, yang tidak baik.
>> Jadi jika saya mahu untuk membuat beberapa petunjuk pada baris yang sama, dari jenis yang sama,
dan bintang, apa yang saya benar-benar perlu lakukan adalah mengatakan int * pa, * pb, * pc.
Kini mempunyai hanya berkata dan kini memberitahu anda ini,
anda mungkin tidak akan melakukan ini.
Dan ia mungkin sesuatu yang baik secara jujur, kerana anda mungkin secara tidak sengaja
meninggalkan bintang, sesuatu seperti itu.
Ia mungkin yang terbaik untuk mungkin mengisytiharkan petunjuk pada baris individu,
tetapi ia hanya satu sama lain mereka sintaks menjengkelkan
perkara dengan bintang yang membuat petunjuk begitu sukar untuk bekerja dengan.
Kerana ia hanya sintaksis ini keadaan huru-hara, anda perlu bekerja melalui.
Dengan amalan ia benar-benar menjadi sifat kedua.
Saya masih melakukan kesilapan dengan ia masih selepas program selama 10 tahun,
jadi jangan kecewa jika sesuatu berlaku kepada anda, ia agak biasa jujur.
Ia benar-benar jenis kecacatan sintaksis itu.
>> OK jadi saya jenis berjanji bahawa kita akan mengkaji semula
konsep bagaimana besar adalah rentetan.
Nah jika saya memberitahu anda bahawa tali, kami telah benar-benar jenis
telah berbohong kepada anda sepanjang masa.
Tidak ada jenis data yang dikenali sebagai tali, dan sebenarnya saya
menyatakan hal ini dalam salah satu daripada kami video terawal pada jenis data,
tali itu adalah sejenis data yang telah dicipta untuk anda dalam CS50.h.
Anda perlu # include Cs50.h untuk menggunakannya.
>> Well tali adalah benar-benar hanya alias sesuatu
dipanggil char *, satu penunjuk kepada watak.
Baik petunjuk, ingat, hanya menangani.
Jadi apa saiz dalam bait rentetan?
Biasanya tidak empat atau lapan.
Dan sebab itu saya katakan empat atau lapan adalah kerana ia sebenarnya
bergantung kepada sistem, Jika anda menggunakan CS50 ide, char * adalah saiz char
* Adalah lapan, ia adalah satu sistem 64-bit.
Setiap alamat dalam ingatan adalah 64 bit panjang.
Jika anda menggunakan perkakas CS50 atau menggunakan mana-mana mesin 32-bit,
dan anda telah mendengar bahawa jangka 32-bit mesin, apakah mesin 32-bit?
Well ia hanya bermaksud bahawa setiap alamat dalam ingatan adalah 32 bit panjang.
Dan sebagainya 32 bit adalah empat bait.
Jadi char * adalah empat atau lapan bait bergantung pada sistem anda.
Dan sememangnya mana-mana jenis data, dan penunjuk kepada apa-apa data
menaip, kerana semua petunjuk hanyalah alamat, empat atau lapan bait.
Jadi mari kita melihat semula ini diagram dan mari kita membuat kesimpulan
video ini dengan sedikit senaman di sini.
Jadi di sini adalah rajah kita berhenti dengan pada awal-awal video.
Jadi apa yang berlaku sekarang jika saya mengatakan * pk = 35?
Jadi apa maknanya apabila saya berkata, * pk = 35?
Mengambil kedua.
* pk.
Dalam konteks sini, * adalah pengendali dereference.
Oleh itu, apabila dereference yang pengendali digunakan,
kita pergi ke alamat yang menunjuk kepada oleh pk, dan kita mengubah apa yang kita dapati.
Jadi * pk = 35 dengan berkesan adakah ini gambar.
Jadi ia pada dasarnya sintaksis sama dengan yang telah berkata k = 35.
>> Satu lagi.
Jika saya katakan int m, saya membuat pembolehubah baru yang dikenali sebagai m.
Kotak baru, ia adalah satu kotak hijau kerana ia akan mengadakan integer,
dan ia dilabel m.
Jika saya katakan m = 4, saya meletakkan integer ke dalam kotak itu.
Jika berkata pk = & m, bagaimana perubahan rajah ini?
Pk = & m, adakah anda masih ingat apa yang & Operator melakukan atau dipanggil?
Ingatlah bahawa & beberapa nama pembolehubah adalah alamat nama berubah-ubah.
Jadi apa yang kita katakan ialah pk mendapat alamat m.
Dan dengan berkesan apa yang berlaku di gambar rajah ialah PK mata tidak lagi
kepada k, tetapi mata untuk m.
>> Sekali lagi petunjuk yang sangat sukar untuk bekerja dengan
dan mereka mengambil banyak amalan, tetapi kerana
kemampuan mereka untuk membolehkan anda untuk lulus data antara fungsi
dan benar-benar mempunyai orang-orang perubahan berkuat kuasa,
mendapatkan kepala anda sekitar adalah benar-benar penting.
Ia mungkin adalah yang paling rumit topik yang kita bincangkan dalam CS50,
tetapi nilai yang anda mendapatkan daripada menggunakan petunjuk
jauh melebihi komplikasi yang datang dari pembelajaran mereka.
Oleh itu, saya ingin anda yang terbaik daripada nasib belajar tentang petunjuk.
Saya Doug Lloyd, ini adalah CS50.