>> [MUSIC PLAYING]
>> Doug LLOYD: Pointer, di sini kita.
Ini mungkin akan menjadi topik yang paling sulit
yang kita bicarakan di CS50.
Dan jika Anda sudah membaca apa-apa tentang pointer
sebelum Anda mungkin sedikit mengintimidasi masuk ke video ini.
Memang benar pointer mengijinkan Anda kemampuan
untuk mungkin mengacaukan cukup parah ketika Anda
bekerja dengan variabel, dan data, dan menyebabkan program anda crash.
Tapi mereka sebenarnya sangat berguna dan mereka memungkinkan kita cara yang hebat
untuk lulus data bolak- balik antara fungsi,
bahwa kita dinyatakan tidak dapat dilakukan.
>> Dan jadi apa kita benar-benar ingin lakukan di sini adalah kereta
Anda untuk memiliki disiplin pointer yang baik, sehingga Anda dapat menggunakan pointer secara efektif
untuk membuat program Anda yang jauh lebih baik.
Seperti yang saya katakan pointer memberi kita berbeda cara untuk melewatkan data antara fungsi.
Sekarang jika Anda ingat dari video sebelumnya, ketika
kami berbicara tentang lingkup variabel, saya sebutkan
bahwa semua data yang melewati antara kita fungsi dalam C dilewatkan oleh nilai.
Dan saya mungkin tidak digunakan yang Istilah, apa yang saya berarti ada
adalah bahwa kita melewati salinan data.
Ketika kami melewati sebuah variabel ke fungsi, kita tidak benar-benar melewati variabel
ke fungsi, kan?
Kami melewati salinan bahwa data ke fungsi.
Fungsi melakukan apa yang akan dan menghitung beberapa nilai,
dan mungkin kita menggunakan nilai yang ketika memberikan kembali.
>> Ada satu pengecualian untuk Aturan ini lewat nilai,
dan kami akan kembali ke apa yang adalah sedikit kemudian di dalam video ini.
Jika kita menggunakan pointer bukan menggunakan variabel,
atau bukan menggunakan variabel sendiri atau salinan dari variabel,
kita sekarang dapat melewati variabel sekitar antara fungsi dengan cara yang berbeda.
Ini berarti bahwa jika kita membuat perubahan dalam satu fungsi,
perubahan yang benar-benar akan mengambil efek dalam fungsi yang berbeda.
Sekali lagi, ini adalah sesuatu yang kita tidak bisa melakukan sebelumnya,
dan jika Anda pernah mencoba untuk menukar nilai dua variabel dalam suatu fungsi,
Anda telah memperhatikan masalah ini semacam merangkak naik, kan?
>> Jika kita ingin menukar X dan Y, dan kami melewati mereka untuk fungsi yang disebut swap,
dalam fungsi swap variabel melakukan nilai tukar.
Satu menjadi dua, dua menjadi satu, tapi kami tidak benar-benar
mengubah apa pun dalam bahasa aslinya fungsi, di pemanggil.
Karena kita tidak bisa, kami hanya bekerja dengan salinan dari mereka.
Dengan pointer meskipun, kita bisa benar-benar lulus X dan Y ke fungsi.
Fungsi yang dapat melakukan sesuatu dengan mereka.
Dan nilai-nilai variabel benar-benar dapat mengubah.
Jadi itu cukup perubahan kemampuan kita untuk bekerja dengan data.
>> Sebelum kita menyelam ke pointer, saya pikir itu layak
mengambil beberapa menit untuk kembali ke dasar di sini.
Dan kita lihat bagaimana karya memori komputer
karena dua mata pelajaran ini akan untuk benar-benar cukup saling terkait.
Seperti Anda mungkin tahu, pada sistem komputer Anda
Anda memiliki hard drive atau mungkin solid state drive,
semacam lokasi penyimpanan file.
Ini biasanya di suatu tempat di lingkungan 250 gigabyte
untuk mungkin beberapa terabyte sekarang.
Dan itu di mana semua Anda file akhirnya hidup,
bahkan ketika komputer Anda menutup off, Anda dapat mengubahnya kembali
dan Anda akan menemukan file Anda yang ada lagi ketika Anda reboot sistem anda.
Tapi disk drive, seperti hard disk drive, HDD, atau solid state drive, SSD,
adalah ruang penyimpanan hanya.
>> Kita tidak bisa benar-benar melakukan apa-apa dengan data yang ada di hard disk,
atau solid state drive.
Dalam rangka untuk benar-benar mengubah data atau bergerak di sekitar,
kita harus memindahkannya ke RAM, random access memory.
Sekarang RAM, Anda memiliki banyak kurang dari di komputer Anda.
Anda mungkin memiliki suatu tempat di lingkungan 512 megabyte
jika Anda memiliki komputer lama, untuk mungkin dua, empat, delapan, 16,
bahkan mungkin sedikit lebih, gigabyte RAM.
Jadi itu jauh lebih kecil, tapi itu di mana semua data volatile ada.
Di situlah kita bisa mengubah keadaan.
Tetapi ketika kita menyalakan komputer kita off, semua data di RAM hancur.
>> Jadi itu sebabnya kita perlu memiliki hard disk untuk lokasi yang lebih permanen itu,
sehingga exists- itu akan benar-benar buruk jika setiap kali kita
berbalik komputer kita off, setiap file dalam sistem kami dilenyapkan.
Jadi kita bekerja di dalam RAM.
Dan setiap kali kita berbicara tentang memori, cukup banyak, di CS50,
kita sedang berbicara tentang RAM, hard disk tidak.
>> Jadi ketika kita memindahkan barang-barang ke dalam memori, tidak memakan sejumlah ruang.
Semua jenis data yang kami telah bekerja dengan
mengambil yang berbeda jumlah ruang di RAM.
Jadi setiap kali Anda membuat sebuah integer variabel, empat byte memori
disisihkan dalam RAM sehingga Anda dapat bekerja dengan bilangan bulat itu.
Anda dapat mendeklarasikan integer, mengubahnya, menetapkan
untuk nilai 10 bertambah persatu, seterusnya dan seterusnya.
Semua yang perlu terjadi di RAM, dan Anda mendapatkan empat byte
untuk bekerja dengan untuk setiap integer yang Anda buat.
>> Setiap karakter Anda buat mendapat satu byte.
Itu hanya berapa banyak ruang adalah dibutuhkan untuk menyimpan karakter.
Setiap float, nyata nomor, mendapat empat byte
kecuali itu adalah ganda presisi floating point
nomor, yang memungkinkan Anda untuk memiliki lebih tepat atau lebih digit
setelah titik desimal tanpa kehilangan presisi,
yang mengambil delapan byte memori.
Rindu lama, bilangan bulat yang sangat besar, juga mengambil delapan byte memori.
Berapa banyak byte memori jangan string mengambil?
Nah mari kita menempatkan pin dalam pertanyaan yang untuk saat ini, tapi kami akan kembali ke sana.
>> Jadi kembali ke ide ini dari memori array besar sel byte berukuran.
Itu benar-benar semua itu, itu hanya array besar sel,
sama seperti array lain yang Anda akrab dengan dan melihat,
kecuali setiap elemen adalah satu byte lebar.
Dan seperti sebuah array, setiap elemen memiliki alamat.
Setiap elemen array memiliki indeks, dan kami
dapat menggunakan indeks yang melakukan disebut akses acak pada array.
Kami tidak perlu mulai dari awal array,
iterate melalui setiap elemen tunggal daripadanya,
untuk menemukan apa yang kita cari.
Kami hanya bisa mengatakan, saya ingin sampai ke Unsur 15 atau elemen 100.
Dan Anda hanya bisa lewat di nomor yang dan mendapatkan nilai yang Anda cari.
>> Demikian pula setiap lokasi dalam memori memiliki alamat.
Jadi memori Anda mungkin terlihat seperti ini.
Berikut adalah potongan yang sangat kecil dari memori, ini adalah 20 byte memori.
Pertama 20 byte karena saya alamat ada di bagian bawah
adalah 0, 1, 2, 3, dan sebagainya pada semua jalan sampai ke 19.
Dan ketika saya mendeklarasikan variabel dan ketika saya mulai bekerja dengan mereka,
sistem akan mengatur selain beberapa ruang untuk saya
dalam memori ini bekerja dengan variabel saya.
Jadi saya mungkin mengatakan, char c sama modal H. Dan apa yang akan terjadi?
Nah sistem ini akan disisihkan untuk saya satu byte.
Dalam hal ini memilih nomor byte empat, byte di alamat empat,
dan itu akan menyimpan H modal huruf di sana bagi saya.
Jika saya kemudian mengatakan kecepatan int batas sama 65, itu
akan menyisihkan empat byte memori untuk saya.
Dan itu akan memperlakukan mereka empat byte sebagai satu kesatuan
karena apa yang kita bekerja dengan adalah bilangan bulat di sini.
Dan itu akan menyimpan 65 di sana.
>> Sekarang sudah aku agak memberitahu Anda sedikit kebohongan,
benar, karena kita tahu bahwa komputer bekerja dalam biner.
Mereka tidak mengerti tentu apa H modal
atau apa 65 adalah, mereka hanya memahami biner, nol dan satu.
Dan sebenarnya apa kita menyimpan di sana
bukan huruf H dan nomor 65, melainkan representasi biner
daripadanya, yang terlihat sedikit sesuatu seperti ini.
Dan khususnya dalam konteks variabel integer,
itu tidak akan hanya meludah ke dalam, itu tidak akan memperlakukannya sebagai salah satu empat
byte potongan tentu, itu benar-benar akan
memperlakukannya sebagai empat satu potongan byte, yang mungkin terlihat seperti ini.
Dan bahkan ini tidak sepenuhnya benar baik,
karena sesuatu yang disebut sebuah endianness, yang kita tidak
akan masuk ke dalam sekarang, tapi jika Anda ingin tahu tentang,
Anda dapat membaca tentang sedikit dan endianness besar.
Tapi demi argumen ini, demi video ini,
mari kita berasumsi bahwa, dalam Bahkan, bagaimana jumlah 65 akan
direpresentasikan dalam memori pada setiap sistem,
meskipun tidak sepenuhnya benar.
>> Tapi mari kita sebenarnya hanya mendapatkan menyingkirkan semua biner seluruhnya,
dan hanya berpikir tentang dengan H dan 65, itu jauh lebih mudah
untuk berpikir tentang hal seperti bahwa sebagai manusia.
Baiklah, sehingga juga tampaknya mungkin sedikit acak yang I've- sistem saya
tidak memberi saya bytes 5, 6, 7, dan 8 untuk menyimpan integer.
Ada alasan untuk itu, juga, yang kita tidak akan masuk ke dalam sekarang, tapi cukup
untuk mengatakan bahwa apa yang komputer lakukan di sini
mungkin langkah yang baik pada bagian.
Untuk tidak memberikan saya memori itu tentu kembali ke belakang.
Meskipun akan melakukannya sekarang jika saya ingin mendapatkan string lain,
disebut nama, dan saya ingin untuk menempatkan Lloyd di sana.
Aku akan perlu untuk cocok satu karakter, setiap huruf dari itu
akan memerlukan satu karakter, satu byte memori.
Jadi jika saya bisa menempatkan Lloyd ke array saya seperti ini aku cukup baik untuk pergi, kan?
Apa yang hilang?
>> Ingat bahwa setiap string yang kita bekerja dengan di C berakhir dengan backslash nol,
dan kita tidak bisa menghilangkan itu di sini, baik.
Kita perlu untuk menyisihkan satu byte memori untuk menahan itu jadi kami
tahu kapan string kita telah berakhir.
Jadi sekali lagi pengaturan ini dari cara hal-hal
muncul dalam kekuatan memori sedikit acak,
tetapi sebenarnya adalah bagaimana kebanyakan sistem yang dirancang.
Garis mereka pada kelipatan empat, untuk alasan lagi
bahwa kita tidak perlu masuk ke dalam sekarang.
Tapi ini, sehingga cukup untuk mengatakan bahwa setelah tiga baris kode,
ini adalah apa memori mungkin terlihat seperti.
Jika saya perlu lokasi memori 4, 8, dan 12 untuk menyimpan data saya,
ini adalah apa ingatan saya mungkin terlihat seperti.
>> Dan hanya menjadi sangat bertele-tele di sini, ketika
kita sedang berbicara tentang memori alamat kita biasanya
melakukannya dengan menggunakan notasi heksadesimal.
Jadi kenapa tidak kita mengubah semua ini dari desimal ke notasi heksadesimal
hanya karena itu umumnya bagaimana kita mengacu pada memori.
Jadi bukannya 0 melalui 19, apa yang kita miliki adalah nol
x nol nol melalui x1 tiga.
Mereka adalah 20 byte memori yang kita telah atau kita sedang melihat di gambar ini
disini.
>> Jadi semua itu dikatakan, mari kita menjauh dari memori untuk kedua
dan kembali ke pointer.
Berikut adalah yang paling penting hal yang perlu diingat
seperti yang kita mulai bekerja dengan pointer.
Sebuah pointer ada lebih dari sebuah alamat.
Aku akan mengatakannya lagi karena itu yang penting,
pointer ada lebih dari sebuah alamat.
Pointer alamat untuk lokasi dalam memori di mana variabel hidup.
Mengetahui bahwa itu menjadi mudah-mudahan sedikit lebih mudah untuk bekerja dengan mereka.
Hal lain yang saya suka lakukan adalah untuk memiliki semacam
diagram visual yang mewakili apa terjadi dengan berbagai baris kode.
Dan kami akan melakukan ini beberapa kali di pointer,
dan ketika kita berbicara tentang dinamis alokasi memori juga.
Karena saya berpikir bahwa diagram ini dapat sangat membantu.
>> Jadi jika saya mengatakan misalnya, int k dalam kode saya, apa yang terjadi?
Nah apa yang pada dasarnya terjadi adalah Saya mendapatkan memori disisihkan untuk saya,
tapi aku bahkan tidak suka berpikir tentang hal seperti itu, saya
suka berpikir tentang hal itu seperti sebuah kotak.
Saya memiliki sebuah kotak dan itu berwarna hijau karena saya
dapat menempatkan bilangan bulat di kotak hijau.
Jika itu adalah karakter saya mungkin memiliki kotak biru.
Tapi saya selalu mengatakan, jika saya membuat kotak yang dapat menampung bilangan bulat
kotak yang berwarna hijau.
Dan aku mengambil spidol permanen dan saya menulis k di sisi itu.
Jadi saya memiliki kotak disebut k, di mana saya dapat menempatkan bilangan bulat.
Jadi ketika saya mengatakan int k, yang apa yang terjadi di kepala saya.
Jika saya mengatakan k sama dengan lima, apa yang saya lakukan?
Yah, aku menempatkan lima dalam kotak, yang tepat.
Ini cukup sederhana, jika Saya mengatakan int k, membuat kotak disebut k.
Jika saya mengatakan k sama dengan 5, menempatkan lima ke dalam kotak.
Mudah-mudahan itu tidak terlalu banyak lompatan.
Di sinilah hal-hal pergi sedikit menarik meskipun.
Jika saya mengatakan int * pk, baik bahkan jika saya tidak melakukan tahu apa ini tentu berarti,
itu jelas punya sesuatu hubungannya dengan integer.
Jadi aku akan mewarnai kotak ini hijau-ish,
Aku tahu itu punya sesuatu hubungannya dengan integer,
tapi itu bukan integer sendiri, karena itu adalah bintang int.
Ada sesuatu yang sedikit yang berbeda tentang hal itu.
Jadi integer yang terlibat, tapi selain itu
tidak terlalu berbeda dari apa yang kita bicarakan.
Ini sebuah kotak, yang punya label, itu mengenakan pk label,
dan itu mampu memegang bintang int, apa pun mereka adalah.
Mereka memiliki sesuatu untuk dilakukan dengan bilangan bulat, jelas.
Berikut baris terakhir sekalipun.
Jika saya mengatakan pk = & k, whoa, apa yang baru saja terjadi, kan?
Jadi nomor acak ini, tampaknya acak jumlah, akan dilemparkan ke dalam kotak ada.
Semua itu adalah, adalah pk mendapat alamat k.
Jadi aku menempel di mana k tinggal di memori, alamatnya, alamat byte nya.
Semua yang saya lakukan adalah saya katakan nilai itulah yang akan saya
untuk menempatkan dalam kotak saya disebut pk.
Dan karena hal-hal ini pointer, dan karena mencari
pada string seperti nol x delapan nol c tujuh empat delapan
dua nol mungkin tidak terlalu berarti.
Ketika kita umumnya memvisualisasikan pointer, kita benar-benar melakukannya sebagai pointer.
Pk memberi kita informasi kita perlu mencari k di memori.
Jadi pada dasarnya pk memiliki panah di dalamnya.
Dan jika kita berjalan panjang panah itu, bayangkan
itu sesuatu yang bisa berjalan di atas, jika kita berjalan sepanjang panah,
di bagian paling ujung panah itu, kita akan menemukan lokasi di memori
di mana k hidup.
Dan itu benar-benar penting karena setelah kita tahu di mana k hidup,
kita bisa mulai bekerja dengan data dalam lokasi memori.
Meskipun kita mendapatkan mungil sebuah menggigit depan diri kita sendiri untuk saat ini.
>> Jadi apa adalah pointer?
Sebuah pointer adalah item data yang Nilai adalah alamat memori.
Itu yang nol x delapan nol barang terjadi, itu adalah alamat memori.
Itu adalah lokasi di memori.
Dan jenis pointer menjelaskan jenis yang
data Anda akan menemukan di alamat memori.
Jadi ada int bintang bagian kanan.
Jika saya ikuti panah itu, itu akan membawa saya ke lokasi.
Dan lokasi itu, apa yang saya akan menemukan ada dalam contoh saya,
adalah kotak berwarna hijau.
Ini integer, itulah yang saya akan menemukan jika saya pergi ke alamat tersebut.
Tipe data dari pointer menjelaskan apa
Anda akan menemukan di alamat memori.
Jadi, inilah hal yang benar-benar keren meskipun.
Pointer memungkinkan kita untuk lulus variabel antara fungsi.
Dan benar-benar lulus variabel dan tidak lulus salinan dari mereka.
Karena jika kita tahu persis di mana dalam memori untuk menemukan variabel,
kita tidak perlu membuat salinan itu, kita hanya bisa pergi ke lokasi yang
dan bekerja dengan variabel itu.
Jadi pada intinya pointer semacam dari membuat lingkungan komputer
lebih banyak seperti dunia nyata, benar.
>> Jadi, inilah analogi.
Mari kita mengatakan bahwa saya memiliki notebook, benar, dan itu penuh dengan catatan.
Dan saya ingin Anda untuk memperbaruinya.
Anda fungsi yang update catatan, benar.
Dalam cara kita sudah bekerja sejauh ini, apa yang
terjadi adalah Anda akan mengambil notebook saya, Anda akan pergi ke toko salinan,
Anda akan membuat salinan Xerox setiap halaman notebook.
Anda akan meninggalkan notebook saya kembali di meja saya ketika Anda selesai,
Anda akan pergi dan mencoret hal di saya notebook yang kedaluwarsa atau salah,
dan kemudian Anda akan melewati kembali ke saya tumpukan halaman Xerox
yang merupakan replika dari notebook saya dengan perubahan yang Anda buat untuk itu.
Dan pada saat itu, terserah kepada saya sebagai fungsi panggilan, sebagai pemanggil,
memutuskan untuk mengambil catatan Anda dan mengintegrasikan mereka kembali ke notebook saya.
Jadi ada banyak langkah-langkah terlibat di sini, benar.
Seperti tidak akan lebih baik jika saya hanya mengatakan, hei, bisa Anda
memperbarui notebook saya untuk saya, tangan Anda notebook saya,
dan Anda mengambil hal-hal dan benar-benar menyeberang mereka
dan memperbarui catatan saya di notebook saya.
Dan kemudian memberi saya notebook saya kembali.
Itulah jenis apa pointer memungkinkan kita untuk melakukan,
mereka membuat lingkungan ini banyak lebih seperti bagaimana kami beroperasi dalam kenyataan.
>> Baiklah jadi itulah yang pointer, mari kita bicara
tentang bagaimana pointer bekerja di C, dan bagaimana kita bisa mulai bekerja dengan mereka.
Jadi ada pointer yang sangat sederhana di C disebut pointer null.
Pointer poin nol untuk apa-apa.
Hal ini mungkin tampak seperti itu sebenarnya bukan hal yang sangat berguna,
tapi seperti yang kita akan melihat sedikit nanti, kenyataan
bahwa pointer nol ini ada sebenarnya benar-benar dapat berguna.
Dan setiap kali Anda membuat pointer, dan Anda tidak menetapkan immediately- nilainya
contoh pengaturan nilainya segera
akan menjadi beberapa slide kembali di mana saya mengatakan pk sama & k,
pk mendapat alamat k, seperti kita akan melihat apa artinya,
kita akan melihat bagaimana kode yang shortly- jika kita tidak menetapkan nilai sesuatu
bermakna segera, Anda harus selalu
mengatur pointer untuk menunjuk ke null.
Anda harus mengaturnya untuk menunjuk ke apa-apa.
>> Itu sangat berbeda dari hanya meninggalkan nilai seperti itu
dan kemudian mendeklarasikan pointer dan hanya asumsi
itu nol karena itu jarang benar.
Jadi Anda harus selalu mengatur nilai pointer
null jika Anda tidak menetapkan nilai untuk sesuatu yang berarti segera.
Anda dapat memeriksa apakah nilai pointer adalah null menggunakan operator kesetaraan
(==), Sama seperti Anda membandingkan bilangan bulat apapun nilai-nilai atau nilai-nilai karakter menggunakan (==)
demikian juga.
Ini semacam khusus konstan nilai yang dapat Anda gunakan untuk menguji.
Jadi itu sangat sederhana pointer, pointer null.
Cara lain untuk membuat pointer adalah untuk mengekstrak
alamat variabel Anda sudah dibuat,
dan Anda melakukan ini dengan menggunakan & alamat Operator ekstraksi.
Yang telah kita lihat sebelumnya dalam diagram contoh pertama saya menunjukkan.
Jadi jika x adalah variabel yang kita sudah sudah dibuat dari tipe integer,
maka & x adalah pointer ke integer.
& x adalah- ingat, & akan mengekstrak alamat hal di sebelah kanan.
Dan karena pointer hanya alamat, dari & x adalah pointer ke integer
Nilai yang mana dalam memori x hidup.
Ini alamat x.
Jadi & x adalah alamat dari x.
Mari mengambil satu langkah lebih lanjut dan terhubung ke sesuatu
Saya singgung di video sebelumnya.
Jika arr adalah array dari ganda, maka & braket persegi arr i adalah pointer
untuk ganda.
OKE.
arr braket persegi i, jika arr adalah array dari ganda,
kemudian arr braket persegi i elemen ke-i dari array,
dan & arr braket persegi saya adalah di mana di memori elemen ke-i dari arr ada.
>> Jadi apa implikasinya di sini?
Sebuah nama array, implikasinya dari semua ini,
adalah bahwa nama array adalah sebenarnya itu sendiri pointer.
Anda telah bekerja dengan pointer sepanjang
setiap kali bahwa Anda telah menggunakan sebuah array.
Ingat dari contoh pada lingkup variabel,
dekat akhir video saya hadir contoh di mana kita memiliki fungsi
disebut set int dan fungsi yang disebut set array.
Dan tantangan Anda untuk menentukan apakah atau tidak, atau apa
nilai-nilai yang kita dicetak akhir fungsi,
pada akhir program utama.
>> Jika Anda ingat dari contoh yang atau jika Anda sudah menonton video,
Anda tahu bahwa ketika Anda-panggilan untuk set int efektif tidak apa-apa.
Tetapi panggilan untuk mengatur berbagai dilakukannya.
Dan aku semacam dipoles mengapa itu terjadi pada saat itu.
Aku hanya berkata, baik itu array, itu khusus, Anda tahu, ada alasan.
Alasannya adalah bahwa array Nama benar-benar hanya sebuah pointer,
dan ada ini khusus sintaks braket persegi yang
membuat hal-hal jauh lebih baik untuk bekerja dengan.
Dan mereka membuat ide pointer jauh lebih sedikit menakutkan,
dan itulah sebabnya mereka semacam dari yang disajikan dengan cara itu.
Tapi benar-benar array hanya pointer.
Dan itulah mengapa ketika kita membuat perubahan ke array,
ketika kami melewati sebuah array sebagai parameter ke fungsi atau sebagai argumen
ke fungsi, isi dari array benar-benar berubah di kedua callee
dan di pemanggil.
Yang untuk setiap jenis lain dari variabel yang kita lihat itu tidak terjadi.
Jadi itu hanya sesuatu yang perlu keberatan ketika Anda bekerja dengan pointer,
adalah bahwa nama sebuah array yang sebenarnya pointer
ke elemen pertama dari array itu.
>> OK jadi sekarang kita memiliki semua ini fakta, mari kita terus, benar.
Mengapa kita peduli di mana sesuatu yang hidup.
Yah seperti saya katakan, itu cukup berguna untuk mengetahui di mana sesuatu yang hidup
sehingga Anda dapat pergi ke sana dan mengubahnya.
Bekerja dengan itu dan benar-benar memiliki hal yang Anda
ingin lakukan untuk efek mengambil variabel, dan tidak berlaku pada beberapa salinan itu.
Ini disebut dereferencing.
Kami pergi ke referensi dan kita mengubah nilai di sana.
Jadi jika kita memiliki pointer dan itu disebut pc, dan itu menunjukkan karakter,
maka kita dapat mengatakan * pc dan pc * adalah nama apa yang akan kita temukan jika kita pergi
ke alamat pc.
Apa yang kita akan menemukan ada karakter dan * pc adalah bagaimana kita mengacu pada data pada saat itu
lokasi.
Jadi kita bisa mengatakan sesuatu seperti * pc = D atau sesuatu seperti itu,
dan itu berarti bahwa apa pun berada di alamat memori pc,
karakter apapun sebelumnya ada, sekarang D, jika kita mengatakan * pc = D.
>> Jadi di sini kita pergi lagi dengan beberapa hal C aneh, benar.
Jadi kita telah melihat * sebelumnya sebagai entah bagaimana bagian dari jenis data,
dan sekarang sedang digunakan dalam konteks yang sedikit berbeda
untuk mengakses data di lokasi.
Aku tahu itu sedikit membingungkan dan itu sebenarnya bagian dari keseluruhan ini
seperti, mengapa pointer memiliki mitologi ini sekitar mereka sebagai begitu kompleks,
adalah jenis masalah sintaks, jujur.
Tapi * digunakan baik dalam konteks, baik sebagai bagian dari nama jenis,
dan kita akan melihat sedikit kemudian sesuatu yang lain, juga.
Dan sekarang adalah dereference operator.
Jadi pergi ke referensi, ia mengakses data
di lokasi pointer, dan memungkinkan Anda untuk memanipulasi di akan.
>> Sekarang ini sangat mirip dengan mengunjungi tetangga Anda, benar.
Jika Anda tahu apa yang Anda tetangga tinggal, Anda
tidak bergaul dengan tetangga Anda.
Anda tahu Anda kebetulan tahu di mana mereka tinggal,
tapi itu tidak berarti bahwa dengan berdasarkan memiliki pengetahuan yang
Anda berinteraksi dengan mereka.
Jika Anda ingin berinteraksi dengan mereka, Anda harus pergi ke rumah mereka,
Anda harus pergi ke mana mereka tinggal.
Dan sekali Anda melakukannya, maka Anda dapat berinteraksi
dengan mereka sama seperti Anda ingin.
Dan sama dengan variabel, Anda perlu pergi ke alamat mereka
jika Anda ingin berinteraksi mereka, Anda tidak bisa hanya tahu alamat.
Dan cara Anda pergi ke alamat ini menggunakan *, operator dereference.
Apa yang Anda pikirkan terjadi jika kita mencoba dan dereference
pointer yang nilainya nol?
Ingat bahwa nol pointer menunjuk ke apa-apa.
Jadi jika Anda mencoba dan dereference tidak ada atau pergi ke alamat apa-apa,
bagaimana menurutmu yang terjadi?
Segmentasi Nah jika Anda menebak kesalahan, Anda akan benar.
Jika Anda mencoba dan dereference pointer null,
Anda menderita segmentasi sebuah kesalahan. Tapi tunggu,
tidak saya katakan, bahwa jika Anda tidak akan
untuk menetapkan nilai Anda dari Anda pointer ke sesuatu yang berarti,
Anda harus diatur ke nol?
Saya lakukan dan benar-benar segmentasi kesalahan adalah jenis perilaku yang baik.
>> Apakah Anda pernah menyatakan variabel dan tidak ditugaskan nilainya segera?
Jadi Anda hanya mengatakan int x; Anda tidak sebenarnya menetapkan apa-apa
dan kemudian di dalam kode Anda, Anda mencetak nilai x,
masih belum memiliki ditugaskan untuk apa-apa.
Sering Anda akan mendapatkan nol, tapi kadang-kadang Anda
mungkin mendapatkan beberapa nomor acak, dan Anda tidak tahu dari mana asalnya.
Demikian pula bisa hal terjadi dengan pointer.
Ketika Anda menyatakan pointer int * pk misalnya,
dan Anda tidak menetapkan ke nilai, Anda mendapatkan empat byte untuk memori.
Apapun empat byte memori sistem dapat
menemukan bahwa memiliki beberapa nilai yang berarti.
Dan mungkin ada sesuatu yang sudah ada yang
tidak lagi dibutuhkan oleh yang lain fungsi, sehingga Anda hanya perlu
Data apa pun yang ada.
>> Bagaimana jika Anda mencoba untuk melakukan dereference beberapa alamat yang Anda tidak- ada
sudah byte dan informasi di ada, yang sekarang dalam pointer Anda.
Jika Anda mencoba dan dereference pointer itu, Anda mungkin bermain-main dengan beberapa memori
bahwa Anda tidak berniat main-main dengan itu semua.
Dan bahkan Anda bisa melakukan sesuatu yang sangat dahsyat,
seperti istirahat program lain, atau merusak fungsi lain,
atau melakukan sesuatu yang berbahaya Anda tidak berniat untuk melakukan sama sekali.
Dan jadi itu sebabnya itu sebenarnya ide yang baik
untuk mengatur pointer Anda ke null jika Anda tidak menetapkan mereka untuk sesuatu yang berarti.
Ini mungkin lebih baik di akhir hari untuk program Anda
untuk kecelakaan maka untuk itu untuk melakukan sesuatu yang sekrup
program lain atau fungsi lain.
Perilaku yang mungkin bahkan kurang ideal daripada hanya menabrak.
Dan jadi itu sebabnya itu sebenarnya kebiasaan yang baik
untuk masuk ke untuk mengatur pointer Anda null jika Anda tidak menetapkan mereka
ke nilai yang bermakna segera, nilai yang Anda tahu
dan bahwa Anda dapat dengan aman dereference.
>> Jadi mari kita kembali sekarang dan melihat di sintaks keseluruhan situasi.
Jika saya mengatakan int * p ;, apa yang telah saya hanya dilakukan?
Apa yang saya lakukan adalah ini.
Saya tahu nilai p adalah alamat karena semua pointer hanya
alamat.
Aku bisa dereference p menggunakan operator *.
Dalam konteks ini di sini, di bagian paling atas ingat * adalah bagian dari jenis.
Int * adalah tipe data.
Tapi aku bisa dereference p menggunakan operator *,
dan jika saya melakukannya, jika saya pergi ke alamat tersebut, apa yang akan saya temukan di alamat itu?
Aku akan menemukan sebuah integer.
Jadi int * p pada dasarnya adalah mengatakan, p adalah alamat.
Aku bisa dereference p dan jika Saya lakukan, saya akan menemukan sebuah integer
di lokasi memori.
>> OK jadi saya mengatakan ada yang lain hal yang mengganggu dengan bintang
dan di sinilah yang hal yang mengganggu dengan bintang adalah.
Apakah Anda pernah mencoba untuk menyatakan beberapa variabel dari jenis yang sama
pada baris kode yang sama?
Jadi untuk kedua, berpura-pura bahwa garis, kode saya benar-benar telah ada di green
tidak ada dan itu hanya mengatakan int x, y, z ;.
Apa yang akan saya lakukan adalah benar-benar membuat tiga variabel integer untuk Anda,
satu yang disebut x, salah satu yang disebut y, dan satu disebut z.
Ini adalah cara untuk melakukannya tanpa harus membagi ke tiga baris.
>> Di sinilah bintang mendapatkan mengganggu lagi meskipun,
karena * sebenarnya bagian dari kedua nama jenis dan bagian
dari nama variabel.
Dan jika saya mengatakan int * px, py, pz, apa yang saya benar-benar mendapatkan adalah pointer ke integer
disebut px dan dua bilangan bulat, py dan pz.
Dan itu mungkin bukan apa yang kita inginkan, itu tidak baik.
>> Jadi jika saya ingin membuat beberapa pointer pada baris yang sama, dari jenis yang sama,
dan bintang, apa yang sebenarnya saya butuhkan lakukan adalah mengatakan int * pa, * pb, * pc.
Sekarang setelah hanya mengatakan bahwa dan sekarang mengatakan ini,
Anda mungkin tidak akan pernah melakukan hal ini.
Dan itu mungkin hal yang baik jujur, karena Anda mungkin secara tidak sengaja
menghilangkan bintang, sesuatu seperti itu.
Ini mungkin yang terbaik untuk mungkin menyatakan pointer pada garis individu,
tapi itu hanya salah satu dari mereka sintaks mengganggu
hal dengan bintang yang membuat pointer sehingga sulit untuk bekerja dengan.
Karena itu hanya sintaksis ini berantakan Anda harus bekerja melalui.
Dengan latihan yang dilakukannya benar-benar menjadi sifat kedua.
Aku masih melakukan kesalahan dengan itu masih setelah pemrograman selama 10 tahun,
jadi jangan marah jika sesuatu terjadi untuk Anda, itu cukup umum jujur.
Ini benar-benar jenis cacat sintaks.
>> OK jadi aku agak berjanji bahwa kita akan kembali
konsep seberapa besar adalah string.
Nah jika saya katakan bahwa String, kita sudah benar-benar jenis
telah berbohong kepada Anda sepanjang waktu.
Tidak ada tipe data yang disebut tali, dan sebenarnya saya
disebutkan ini di salah satu kami video paling awal pada jenis data,
string yang merupakan tipe data yang diciptakan untuk Anda di CS50.h.
Anda harus # include CS50.h untuk menggunakannya.
>> Nah string yang benar-benar hanya alias untuk sesuatu
disebut char *, sebuah pointer ke karakter.
Nah pointer, ingat, hanya alamat.
Jadi apa ukuran di byte string?
Baik itu empat atau delapan.
Dan alasan saya mengatakan empat atau delapan adalah karena sebenarnya
tergantung pada sistem, Jika Anda menggunakan CS50 ide, char * adalah ukuran char
* Delapan, itu sistem 64-bit.
Setiap alamat dalam memori adalah 64 bit panjang.
Jika Anda menggunakan alat CS50 atau menggunakan mesin 32-bit,
dan Anda telah mendengar bahwa istilah 32-bit mesin, apa adalah mesin 32-bit?
Baik itu hanya berarti bahwa setiap alamat dalam memori adalah 32 bit panjang.
Dan 32 bit adalah empat byte.
Jadi char * empat atau delapan byte tergantung pada sistem Anda.
Dan memang setiap jenis data, dan pointer ke data apapun
ketik, karena semua pointer hanya alamat, yang empat atau delapan byte.
Jadi mari kita kembali ini diagram dan mari kita simpulkan
video ini dengan latihan kecil di sini.
Jadi, inilah diagram kita tinggalkan dengan di awal video.
Jadi apa yang terjadi jika saya katakan * pk = 35?
Jadi apa artinya ketika saya mengatakan, * pk = 35?
Mengambil kedua.
* pk.
Dalam konteks di sini, adalah * dereference operator.
Jadi ketika dereference Operator yang digunakan,
kita pergi ke alamat yang ditunjuk oleh pk, dan kita mengubah apa yang kita temukan.
Jadi * pk = 35 efektif melakukan ini untuk gambar.
Jadi pada dasarnya sintaksis identik dengan dari yang mengatakan k = 35.
>> Satu lagi.
Jika saya mengatakan int m, saya membuat variabel baru yang disebut m.
Sebuah kotak baru, itu kotak hijau karena itu akan terus integer,
dan itu berlabel m.
Jika saya mengatakan m = 4, saya menempatkan bilangan bulat ke dalam kotak itu.
Jika katakanlah pk = & m, bagaimana perubahan diagram ini?
Pk = & m, apakah Anda ingat apa yang & Operator melakukan atau disebut?
Ingat bahwa & beberapa nama variabel adalah alamat dari nama variabel.
Jadi apa yang kita katakan adalah pk mendapat alamat m.
Dan secara efektif apa yang terjadi dengan diagram adalah bahwa pk poin tidak lagi
untuk k, tapi poin untuk m.
>> Lagi pointer sangat sulit untuk bekerja dengan
dan mereka mengambil banyak praktek, tetapi karena
kemampuan mereka untuk memungkinkan Anda untuk lulus data antara fungsi
dan benar-benar memiliki orang-orang perubahan berlaku,
mendapatkan kepala Anda sekitar benar-benar penting.
Mungkin adalah yang paling rumit topik kita bahas dalam CS50,
tetapi nilai yang Anda dapatkan dari menggunakan pointer
jauh melebihi komplikasi yang datang dari belajar mereka.
Jadi saya berharap yang terbaik dari keberuntungan belajar tentang pointer.
Aku Doug Lloyd, ini CS50.