[Powered by Google Translate] [Review] [Kuis 0]
>> [Lexi Ross, Tommy MacWilliam, Lucas Freitas, Joseph Ong] [Harvard University]
>> [Ini adalah CS50.] [CS50.TV]
>> Hei, semua orang.
Selamat datang di sesi review untuk Kuis 0, yang berlangsung Rabu ini.
Apa yang kita akan lakukan malam ini, aku dengan 3 TF lainnya,
dan bersama-sama kita akan pergi melalui review dari apa yang kita lakukan dalam kursus tersebut sejauh ini.
Ini tidak akan menjadi 100% yang komprehensif, tetapi harus memberikan Anda ide yang lebih baik
dari apa yang sudah Anda miliki ke bawah dan apa yang masih perlu untuk belajar sebelum hari Rabu.
Dan jangan ragu untuk mengangkat tangan Anda dengan pertanyaan-pertanyaan seperti yang kita akan bersama,
namun perlu diingat bahwa kita juga akan memiliki sedikit waktu di akhir-
jika kita melewati dengan beberapa menit untuk cadangan-untuk melakukan pertanyaan umum,
jadi ingatlah bahwa dalam pikiran, dan dengan demikian kita akan mulai pada awal dengan Minggu 0.
>> [Kuis 0 Review!] [Bagian 0] [Lexi Ross] Tapi sebelum kita melakukan itu mari kita bicara tentang
logistik kuis.
>> [Logistik] [Kuis berlangsung pada Rabu 10/10 sebagai pengganti kuliah]
>> [(Lihat http://cdn.cs50.net/2012/fall/quizzes/0/about0.pdf untuk rincian)] Hal ini pada hari Rabu, tanggal 10 Oktober.
>> Itu Rabu ini, dan jika Anda pergi ke URL ini di sini,
yang juga dapat diakses dari CS50.net-ada link ke sana-
Anda dapat melihat informasi tentang ke mana harus pergi berdasarkan
Anda nama belakang atau afiliasi sekolah serta
ia memberitahu tentang apa kuis akan menutupi dan jenis pertanyaan yang Anda akan mendapatkan.
Perlu diingat bahwa Anda juga akan memiliki kesempatan untuk meninjau untuk kuis dalam bagian,
sehingga TF Anda harus pergi lebih dari beberapa masalah praktek,
dan itu kesempatan lain yang baik untuk melihat di mana Anda masih perlu belajar untuk kuis.
Mari kita mulai dari awal dengan Bytes 'n' Bits.
Ingat sedikit hanya 0 atau 1,
dan byte adalah kumpulan dari 8 bit dari mereka.
Mari kita lihat ini koleksi bit di sini.
Kita harus bisa mengetahui berapa banyak bit ada.
Dimana kita menghitung ada hanya 8 dari mereka, delapan 0 atau 1 unit.
Dan karena ada 8 bit, itu 1 byte,
dan mari kita mengubahnya menjadi heksadesimal.
Heksadesimal adalah basis 16, dan itu cukup mudah untuk mengkonversi
nomor dalam biner, yang adalah apa itu, ke nomor di heksadesimal.
Semua yang kita lakukan adalah kita melihat kelompok 4,
dan kita mengkonversikannya ke digit heksadesimal yang sesuai.
Kita mulai dengan kelompok paling kanan dari 4, jadi 0011.
Itu akan menjadi salah satu 1 dan satu 2, sehingga bersama-sama yang membuat 3.
Dan kemudian mari kita lihat di blok lain 4.
1101. Itu akan menjadi salah satu 1, 4 satu, dan satu 8.
Bersama itu akan menjadi 13, yang membuat D.
Dan kita akan ingat bahwa dalam heksadesimal kita tidak hanya pergi 0 sampai 9.
Kami pergi 0 sampai F, jadi setelah 9, 10 berkorespondensi dengan A,
11 ke B, dan lain-lain di mana F adalah 15.
Berikut adalah 13 D a,
sehingga untuk mengubahnya menjadi desimal semua yang kita lakukan adalah kita benar-benar
memperlakukan setiap posisi sebagai kekuatan dari 2.
Itulah salah satu 1, 2 satu, nol 4s, 8s nol, satu 16, dan sebagainya,
dan itu agak sulit untuk menghitung di kepala Anda, tetapi jika kita pergi ke slide berikutnya
kita dapat melihat jawabannya.
>> Pada dasarnya kita akan melintasi dari kanan kembali ke kiri,
dan kita mengalikan setiap digit oleh kekuatan yang sesuai 2.
Dan ingat, untuk heksadesimal kami menunjukkan angka-angka dengan 0x di awal
jadi kita tidak bingung dengan angka desimal.
Melanjutkan, ini adalah Tabel ASCII,
dan apa yang kita gunakan ASCII untuk adalah untuk memetakan dari karakter nilai-nilai numerik.
Ingat dalam pset kriptografi kami membuat ekstensif menggunakan Tabel ASCII
untuk menggunakan berbagai metode kriptografi,
Caesar dan cipher Vigenère, untuk mengkonversi huruf yang berbeda
dalam string sesuai dengan kunci yang diberikan oleh pengguna.
Mari kita lihat sedikit matematika ASCII.
Melihat 'P' + 1, dalam bentuk karakter yang akan Q,
dan ingat bahwa ''5 ≠ 5.
Dan bagaimana tepatnya kita akan mengkonversi antara 2 bentuk?
Ini tidak benar-benar terlalu keras.
Dalam rangka untuk mendapatkan 5 kita mengurangi '0 '
karena ada 5 tempat antara '0 'dan '5'.
Dalam rangka untuk pergi ke arah lain kita hanya tambahkan 0 tersebut,
jadi semacam aritmatika biasa.
Hanya ingat bahwa ketika sesuatu memiliki tanda kutip itu karakter
dan dengan demikian sesuai dengan nilai dalam tabel ASCII.
Pindah ke lebih topik ilmu komputer umum.
Kami belajar apa algoritma dan bagaimana kita menggunakan pemrograman
untuk mengimplementasikan algoritma.
Beberapa contoh dari algoritma adalah sesuatu yang benar-benar sederhana seperti
memeriksa apakah suatu bilangan genap atau ganjil.
Untuk itu ingat kita mod nomor dengan 2 dan periksa apakah hasilnya adalah 0.
Jika demikian, itu bahkan. Jika tidak, itu aneh.
Dan itulah contoh algoritma benar-benar dasar.
>> Sedikit yang lebih terlibat adalah pencarian biner,
yang kita akan pergi ke nanti dalam sesi review.
Dan pemrograman adalah istilah yang kita gunakan untuk mengambil suatu algoritma
dan mengubahnya menjadi kode komputer dapat membaca.
2 contoh pemrograman Scratch,
yang adalah apa yang kita lakukan dalam Minggu 0.
Meskipun kita tidak benar-benar mengetikkan kode itu adalah cara menerapkan
algoritma ini, yang mencetak angka 1-10,
dan di sini kita melakukan hal yang sama dalam bahasa pemrograman C.
Ini adalah fungsional setara, hanya ditulis dalam berbagai bahasa atau sintaks.
Kami kemudian belajar tentang ekspresi boolean,
dan boolean adalah nilai yang benar atau salah,
dan di sini seringkali boolean ekspresi
masuk ke dalam kondisi, jadi jika (x ≤ 5),
well, kita sudah diatur x = 5, sehingga kondisi yang akan mengevaluasi benar.
Dan jika itu benar, apa pun kode di bawah kondisi
akan dievaluasi oleh komputer, sehingga string yang akan dicetak
ke output standar, dan kondisi jangka
mengacu pada apa pun yang di dalam kurung dari pernyataan jika.
Ingat semua operator.
Ingat && itu dan | | ketika kita sedang mencoba untuk menggabungkan 2 atau lebih kondisi,
== Tidak = 2 untuk memeriksa apakah hal yang sama.
Ingat bahwa = adalah untuk tugas sementara == adalah operator boolean.
≤, ≥ 2 dan kemudian akhir yang cukup jelas.
Sebuah tinjauan umum logika boolean sini.
Dan ekspresi boolean juga penting dalam loop,
yang kita akan pergi ke sekarang.
Kami belajar tentang 3 jenis loop sejauh CS50, untuk, sementara, dan dilakukan sementara.
Dan itu penting untuk mengetahui bahwa sementara untuk sebagian besar tujuan
kita benar-benar dapat menggunakan semua jenis lingkaran pada umumnya
ada beberapa jenis tujuan atau pola umum
dalam pemrograman yang secara khusus meminta salah satu loop
yang membuatnya paling efisien atau elegan untuk kode dengan cara itu.
Mari kita atas apa masing-masing loop cenderung digunakan untuk paling sering.
>> Dalam untuk loop kita umumnya sudah tahu berapa kali kita ingin iterate.
Itulah apa yang kita masukkan dalam kondisi.
Sebab, i = 0, i <10, misalnya.
Kita sudah tahu bahwa kami ingin melakukan sesuatu 10 kali.
Sekarang, untuk loop sementara, umumnya kita tidak selalu
tahu berapa kali kita ingin loop untuk menjalankan.
Tapi kita tahu semacam kondisi yang kita inginkan
selalu benar atau selalu salah.
Sebagai contoh, ketika diatur.
Mari kita mengatakan bahwa adalah variabel boolean.
Sementara itu benar kita ingin kode untuk mengevaluasi,
jadi sedikit lebih extensible, sedikit lebih umum daripada untuk loop,
tetapi setiap untuk loop juga dapat dikonversi ke loop sementara.
Akhirnya, lakukan sementara loop, yang mungkin paling sulit untuk memahami segera,
sering digunakan ketika kita ingin mengevaluasi kode pertama
sebelum kalinya kami memeriksa kondisi.
Contoh penggunaan umum untuk lakukan sementara loop
adalah ketika Anda ingin mendapatkan input pengguna, dan Anda tahu bahwa Anda ingin meminta pengguna
untuk input setidaknya sekali, tetapi jika mereka tidak memberikan masukan yang baik langsung
Anda ingin terus meminta mereka sampai mereka memberikan masukan yang baik.
Itulah penggunaan yang paling umum dari do while loop,
dan mari kita lihat struktur yang sebenarnya dari loop ini.
Mereka biasanya selalu cenderung mengikuti pola-pola ini.
>> Pada pengulangan untuk di dalam Anda memiliki 3 komponen:
inisialisasi, biasanya sesuatu seperti int i = 0 di mana i adalah meja,
kondisi, di mana kita ingin mengatakan menjalankan ini untuk loop selama kondisi ini masih memegang,
seperti saya <10, dan akhirnya, update, yang adalah bagaimana kita kenaikan
variabel counter pada setiap titik dalam lingkaran.
Suatu hal yang umum untuk melihat hanya ada i + +,
yang berarti kenaikan i oleh 1 setiap waktu.
Anda juga bisa melakukan sesuatu seperti i + = 2,
yang berarti menambah 2 sampai i setiap kali Anda pergi melalui loop.
Dan kemudian melakukan hal ini hanya mengacu pada kode yang benar-benar berjalan sebagai bagian dari loop.
Dan untuk beberapa saat loop, kali ini kita benar-benar memiliki inisialisasi luar loop,
jadi misalnya, katakanlah kita sedang berusaha untuk melakukan jenis yang sama dari lingkaran seperti yang saya baru saja dijelaskan.
Kami akan mengatakan int i = 0 sebelum loop dimulai.
Kemudian kita bisa mengatakan sementara i <10 melakukan ini,
sehingga blok yang sama kode seperti sebelumnya,
dan kali ini bagian dari pembaruan kode, misalnya, i + +,
benar-benar berjalan dalam lingkaran.
Dan akhirnya, untuk melakukan sementara, itu mirip dengan loop sementara,
tapi kita harus ingat bahwa kode akan mengevaluasi sekali
sebelum kondisi tersebut akan diperiksa, sehingga masuk akal lebih banyak
jika Anda melihat itu dalam urutan atas ke bawah.
Dalam lakukan sementara loop kode mengevaluasi sebelum Anda bahkan melihat kondisi sementara,
sedangkan while loop, ia akan mengecek terlebih dahulu.
Laporan dan variabel.
Ketika kita ingin membuat variabel baru pertama kita ingin menginisialisasi itu.
>> Misalnya, bar int menginisialisasi variabel bar,
tetapi tidak memberikan nilai, jadi apa adalah nilai bar sekarang?
Kita tidak tahu.
Bisa jadi beberapa nilai sampah yang sebelumnya disimpan dalam memori sana,
dan kami tidak ingin menggunakan variabel yang
sampai kita benar-benar memberikan nilai,
jadi kita mendeklarasikan sini.
Kemudian kita menginisialisasi itu menjadi 42 di bawah ini.
Sekarang, tentu saja, kita tahu ini dapat dilakukan pada satu baris, int bar = 42.
Tapi hanya untuk menghapus beberapa langkah yang terjadi,
deklarasi dan inisialisasi yang terjadi secara terpisah di sini.
Hal ini terjadi pada satu langkah, dan yang berikutnya, int baz = bar + 1,
pernyataan ini di bawah ini, bahwa baz bertahap, sehingga pada akhir blok kode ini
jika kita mencetak nilai baz akan 44
karena kita mendeklarasikan dan menginisialisasi menjadi 1 bar>,
dan kemudian kami kenaikan itu sekali lagi dengan + +.
Kami pergi sebentar ini cantik, tapi itu baik untuk memiliki seorang jenderal
memahami apa benang dan peristiwa.
Kami terutama melakukan ini di Scratch,
sehingga Anda bisa memikirkan benang sebagai urutan beberapa kode
berjalan pada waktu yang sama.
Dalam kenyataannya, mungkin tidak berjalan pada saat yang sama,
tapi semacam abstrak dapat kita pikirkan dengan cara itu.
>> Dalam Scratch, misalnya, kami memiliki beberapa sprite.
Ini bisa mengeksekusi kode yang berbeda pada waktu yang sama.
Satu bisa berjalan sementara yang lain mengatakan sesuatu
di bagian yang berbeda dari layar.
Acara lain adalah cara memisahkan logika
antara unsur-unsur yang berbeda dari kode Anda,
dan dalam Scratch kami mampu mensimulasikan peristiwa menggunakan Broadcast,
dan itu benar-benar Ketika saya Menerima, tidak Ketika Aku Mendengar,
tapi pada dasarnya itu adalah cara untuk mengirimkan informasi
dari satu sprite yang lain.
Sebagai contoh, Anda mungkin ingin mengirimkan permainan berakhir,
dan ketika sprite lain menerima permainan di atas,
akan meresponnya dengan cara tertentu.
Ini adalah model penting untuk memahami untuk pemrograman.
Hanya untuk pergi atas dasar Minggu 0, apa yang kita telah melebihi sejauh ini,
mari kita lihat program C sederhana.
Teks mungkin sedikit kecil dari sini, tapi aku akan pergi ke itu benar-benar cepat.
Kita termasuk file header 2 di, atas cs50.h dan stdio.h.
Kami kemudian mendefinisikan batas yang disebut konstan menjadi 100.
Kami kemudian menerapkan fungsi utama kami.
Karena kita tidak menggunakan argumen baris perintah di sini kita perlu menempatkan batal
sebagai argumen untuk utama.
Kita melihat di atas int main. Itulah jenis kembali, maka kembali 0 di bagian bawah.
Dan kita menggunakan CS50 fungsi perpustakaan mendapatkan int
untuk meminta pengguna untuk masukan, dan kami menyimpannya dalam variabel x,
jadi kita mendeklarasikan x di atas, dan kita menginisialisasi dengan x = GetInt.
>> Kami kemudian memeriksa untuk melihat apakah pengguna memberi kami masukan yang baik.
Jika itu LIMIT ≥ kami ingin mengembalikan kode kesalahan 1 dan mencetak pesan kesalahan.
Dan akhirnya, masukan jika pengguna telah memberi kita baik
kita akan persegi nomor dan mencetak hasil tersebut.
Hanya untuk memastikan bahwa mereka semua pulang hit
Anda dapat melihat label dari bagian yang berbeda dari kode di sini.
Saya sebutkan konstan, file header.
Oh, int x. Pastikan untuk mengingat itu adalah variabel lokal.
Yang kontras dari sebuah variabel global, yang akan kita bicarakan
sedikit kemudian dalam sesi review,
dan kami memanggil fungsi perpustakaan printf,
jadi jika kita tidak termasuk file header stdio.h
kita tidak akan bisa menelepon printf.
Dan saya percaya panah yang mendapat memotong di sini adalah menunjuk ke d%,
yang merupakan string format dalam printf.
Dikatakan mencetak variabel ini sebagai d nomor,%.
Dan itu adalah untuk Minggu 0.
Sekarang Lucas akan terus.
Hei, guys. Nama saya Lucas.
Saya seorang mahasiswa di rumah terbaik di kampus, Mather,
dan aku akan berbicara sedikit tentang Minggu 1 dan 2,1.
[Minggu 1 dan 2,1!] [Lucas Freitas]
Seperti Lexi mengatakan, ketika kita mulai menerjemahkan kode Anda dari Gores ke C
salah satu hal yang kita perhatikan adalah bahwa Anda tidak bisa hanya
menulis kode Anda dan menjalankannya menggunakan bendera hijau lagi.
Sebenarnya, Anda harus menggunakan beberapa langkah untuk membuat Anda program C
menjadi file eksekusi.
Pada dasarnya apa yang Anda lakukan ketika Anda sedang menulis sebuah program adalah bahwa
Anda menerjemahkan ide Anda ke dalam bahasa yang kompilator dapat mengerti,
jadi ketika Anda sedang menulis sebuah program dalam C
apa yang Anda lakukan adalah benar-benar menulis sesuatu yang kompiler Anda akan mengerti,
dan kemudian compiler akan menerjemahkan kode yang
menjadi sesuatu yang komputer Anda akan mengerti.
>> Dan hal ini, komputer Anda sebenarnya sangat bodoh.
Komputer Anda hanya dapat memahami 0s dan 1s,
jadi sebenarnya dalam komputer pertama orang biasanya diprogram
menggunakan 0s dan 1s, tapi sekarang tidak lagi, terima kasih Tuhan.
Kami tidak harus menghafal urutan 0s dan 1s untuk
untuk untuk loop atau while loop dan sebagainya.
Itulah mengapa kita memiliki sebuah kompiler.
Apa compiler yang dilakukan adalah pada dasarnya menerjemahkan kode C,
dalam kasus kami, dengan bahasa bahwa komputer Anda akan mengerti,
yang merupakan kode objek, dan compiler yang kita gunakan
disebut dentang, jadi ini sebenarnya adalah simbol untuk dentang.
Bila Anda memiliki program Anda, Anda harus melakukan 2 hal.
Pertama, Anda harus mengkompilasi program Anda, dan kemudian Anda akan menjalankan program Anda.
Untuk mengkompilasi program Anda, Anda memiliki banyak pilihan untuk melakukannya.
Yang pertama adalah melakukan program.c dentang
di mana program adalah nama program anda.
Dalam hal ini Anda dapat melihat mereka hanya mengatakan "Hei, mengkompilasi program saya."
Kau tidak mengatakan "Saya ingin nama ini untuk program saya" atau apa pun.
>> Pilihan kedua adalah memberikan nama untuk program anda.
Anda dapat mengatakan dentang-o dan kemudian nama yang Anda inginkan
file executable yang akan dinamakan sebagai dan kemudian program.c.
Dan Anda juga dapat melakukan membuat program, dan melihat bagaimana dalam 2 kasus pertama
Aku menaruh c,. Dan yang ketiga saya hanya memiliki program?
Ya, Anda benar-benar tidak perlu menempatkan c ketika Anda menggunakan make..
Jika compiler sebenarnya akan berteriak pada Anda.
Dan juga, saya tidak tahu apakah kalian ingat,
tapi banyak kali kita juga digunakan lcs50-atau-lm.
Itu disebut menghubungkan.
Itu hanya memberitahu compiler bahwa Anda akan menggunakan orang-orang perpustakaan di sana,
jadi jika Anda ingin menggunakan cs50.h Anda benar-benar harus mengetikkan
dentang program.c-lcs50.
Jika Anda tidak melakukan itu, compiler tidak akan tahu
bahwa Anda menggunakan fungsi-fungsi di cs50.h.
Dan ketika Anda ingin menjalankan program Anda, Anda memiliki 2 pilihan.
Jika Anda melakukan program.c dentang Anda tidak memberikan nama untuk program anda.
Anda harus menjalankannya dengan menggunakan / a.out..
A.out adalah nama standar yang dentang memberikan program Anda jika Anda tidak memberikan nama.
Jika tidak, Anda akan melakukan / program. Jika Anda memberi nama untuk program anda,
dan juga jika Anda memang membuat nama program yang program akan mendapatkan
sudah akan diprogram nama yang sama seperti file c.
Kemudian kita berbicara tentang tipe data dan data.
>> Pada dasarnya tipe data adalah hal yang sama seperti kotak-kotak kecil yang mereka gunakan
untuk menyimpan nilai-nilai, sehingga tipe data sebenarnya seperti Pokemons.
Mereka datang dalam berbagai ukuran dan jenis.
Saya tidak tahu apakah analogi yang masuk akal.
Ukuran data sebenarnya tergantung pada arsitektur mesin.
Semua ukuran data yang saya akan menunjukkan di sini
sebenarnya untuk mesin 32-bit, yang merupakan kasus alat kami,
tetapi jika Anda benar-benar coding Anda Mac atau Windows juga
Mungkin Anda akan memiliki mesin 64-bit,
jadi ingat bahwa ukuran data bahwa aku akan menunjukkan di sini
adalah untuk mesin 32-bit.
Yang pertama yang kita lihat adalah sebuah int,
yang cukup sederhana.
Anda menggunakan int untuk menyimpan integer.
Kami juga melihat karakter, char.
Jika Anda ingin menggunakan huruf atau simbol kecil Anda mungkin akan menggunakan char.
Char A memiliki 1 byte, yang berarti 8 bit, seperti kata Lexi.
Pada dasarnya kita memiliki Tabel ASCII yang memiliki 256
kemungkinan kombinasi dari 0s dan 1s,
dan kemudian ketika Anda mengetik sebuah char itu akan menerjemahkan
karakter yang Anda masukan nomor yang Anda miliki dalam tabel ASCII, seperti kata Lexi.
Kami juga memiliki float, yang kita gunakan untuk menyimpan angka desimal.
Jika Anda ingin memilih 3,14, misalnya, Anda akan menggunakan pelampung
atau ganda yang memiliki lebih presisi.
Sebuah float memiliki 4 byte.
Ganda A memiliki 8 byte, sehingga satu-satunya perbedaan adalah presisi.
Kami juga memiliki panjang yang digunakan untuk bilangan bulat,
dan Anda bisa melihat mesin 32-bit int dan panjang memiliki ukuran yang sama,
sehingga tidak benar-benar masuk akal untuk menggunakan panjang di mesin 32-bit.
>> Tapi jika Anda menggunakan mesin Mac dan 64-bit, sebenarnya memiliki ukuran panjang 8,
sehingga benar-benar tergantung pada arsitektur.
Untuk mesin 32-bit itu tidak masuk akal untuk menggunakan panjang benar-benar.
Dan kemudian lama, di sisi lain, memiliki 8 byte,
sehingga sangat baik jika Anda ingin memiliki sebuah integer lagi.
Dan akhirnya, kita memiliki string, yang sebenarnya adalah sebuah char *,
yang merupakan pointer ke char.
Ini sangat mudah untuk berpikir bahwa ukuran string akan menjadi seperti
jumlah karakter yang telah ada,
tapi sebenarnya char * sendiri
memiliki ukuran pointer ke char, yaitu 4 byte.
Ukuran char * adalah 4 byte.
Tidak masalah jika Anda memiliki sebuah kata kecil atau surat atau apa pun.
Ini akan menjadi 4 byte.
Kami juga belajar sedikit tentang pengecoran,
sehingga Anda dapat melihat, jika Anda memiliki, misalnya, sebuah program yang mengatakan
int x = 3 dan kemudian printf ("% d", x / 2)
apakah kalian tahu apa itu akan mencetak pada layar?
>> Seseorang >> [Siswa] 2?.
1. >> 1, yeah.
Ketika Anda melakukan 3/2 itu akan mendapatkan 1,5,
tapi karena kita menggunakan integer itu akan mengabaikan bagian desimal,
dan Anda akan memiliki 1.
Jika Anda tidak ingin hal itu terjadi apa yang dapat Anda lakukan, misalnya,
adalah mendeklarasikan pelampung y = x.
Maka x yang digunakan untuk menjadi 3 sekarang akan menjadi 3.000 di y.
Dan kemudian Anda dapat mencetak y / 2.
Sebenarnya, saya harus memiliki 2 a. di sana.
Ini akan melakukan 3.00/2.00,
dan Anda akan mendapatkan 1,5.
Dan kita memiliki f .2 hanya untuk meminta 2 unit desimal di bagian desimal.
Jika Anda memiliki .3 f itu akan telah benar-benar 1.500.
Jika itu 2 itu akan menjadi 1,50.
Kami juga punya kasus ini di sini.
Jika Anda melakukan float x = 3,14 x dan kemudian Anda printf
Anda akan mendapatkan 3,14.
Dan jika Anda melakukan x = int x,
yang berarti memperlakukan x sebagai int dan Anda mencetak x sekarang
Anda akan memiliki 3,00.
Apakah itu masuk akal?
Karena Anda pertama memperlakukan x sebagai integer, sehingga Anda mengabaikan bagian desimal,
dan kemudian Anda mencetak x.
Dan akhirnya, Anda juga dapat melakukan hal ini,
int x = 65, dan kemudian Anda mendeklarasikan char c = x,
dan kemudian jika Anda mencetak c Anda benar-benar akan mendapatkan
A, jadi pada dasarnya apa yang Anda lakukan di sini
adalah menerjemahkan bilangan bulat ke dalam karakter,
seperti Tabel ASCII tidak.
Kami juga berbicara tentang operator matematika.
Kebanyakan dari mereka adalah cukup sederhana, sehingga +, -, *, /,
dan juga kita berbicara tentang mod, yang merupakan sisa dari sebuah divisi dari 2 angka.
Jika Anda memiliki 10% 3, misalnya,
itu berarti membagi 10 dengan 3, dan apa sisanya?
Ini akan menjadi 1, sehingga benar-benar sangat berguna bagi banyak program.
Untuk Vigenère dan Caesar Aku cukup yakin bahwa semua dari kalian menggunakan mod.
Tentang operator matematika, sangat berhati-hati ketika menggabungkan * dan /.
>> Misalnya, jika Anda melakukan (3/2) * 2 apa yang Anda akan mendapatkan?
[Siswa] 2.
Ya, 2, karena 3/2 akan menjadi 1,5,
tapi karena Anda melakukan operasi antara 2 bilangan bulat
Anda benar-benar hanya akan mempertimbangkan 1,
dan kemudian 1 * 2 akan menjadi 2, jadi sangat, sangat berhati-hati
ketika melakukan aritmatika dengan bilangan bulat karena
Anda mungkin mendapatkan 2 = 3, dalam kasus itu.
Dan juga sangat berhati-hati didahulukan.
Anda biasanya harus menggunakan tanda kurung untuk memastikan bahwa Anda tahu apa yang Anda lakukan.
Beberapa cara pintas yang berguna, tentu saja, satu adalah i + + atau i + = 1
atau menggunakan + =.
Itu adalah hal yang sama seperti melakukan i = i + 1.
Anda juga dapat melakukan i - i atau - = 1,
yang merupakan hal yang sama seperti i = i -1,
sesuatu yang kalian gunakan banyak dalam untuk loop, setidaknya.
Juga, untuk *, jika Anda menggunakan * = dan jika Anda melakukannya, misalnya,
i * = 2 adalah hal yang sama dengan mengatakan i = i * 2,
dan hal yang sama untuk divisi.
Jika Anda melakukannya i / = 2 itu adalah hal yang sama seperti i = i / 2.
>> Sekarang tentang fungsi.
Kalian mengetahui bahwa fungsi strategi yang sangat baik untuk menyimpan kode
saat Anda sedang pemrograman, jadi jika Anda ingin melakukan tugas yang sama
dalam kode lagi dan lagi, mungkin Anda ingin menggunakan fungsi
hanya sehingga Anda tidak perlu copy dan paste kode berulang-ulang.
Sebenarnya, fungsi utama adalah, dan ketika saya menunjukkan format dari suatu fungsi
Anda akan melihat bahwa itu adalah cukup jelas.
Kami juga menggunakan fungsi dari beberapa perpustakaan,
Misalnya, printf, GetIn, yaitu dari perpustakaan CS50,
dan fungsi lain seperti toupper.
Semua fungsi-fungsi yang benar-benar diterapkan di perpustakaan lain,
dan ketika Anda meletakkan file-file tether di awal program Anda
Anda katakan bisa tolong beri saya kode untuk fungsi-fungsi
jadi saya tidak perlu menerapkannya sendiri?
Dan Anda juga dapat menulis fungsi sendiri, jadi ketika Anda memulai pemrograman
Anda menyadari bahwa perpustakaan tidak memiliki semua fungsi yang Anda butuhkan.
Untuk pset lalu, misalnya, kita menulis menggambar, berebut, dan lookup,
dan itu sangat, sangat penting untuk dapat menulis fungsi
karena mereka berguna, dan kami menggunakannya sepanjang waktu dalam pemrograman,
dan menghemat banyak kode.
Format fungsi yang satu ini.
Kami memiliki tipe kembali di awal. Apa jenis kembali?
Hanya saja ketika fungsi Anda akan kembali.
Jika Anda memiliki fungsi, misalnya, faktorial,
yang akan menghitung faktorial dari integer,
mungkin itu akan kembali integer juga.
Kemudian jenis kembali akan menjadi int.
Printf sebenarnya memiliki tipe void kembali
karena Anda tidak kembali apa-apa.
Kau hanya mencetak hal-hal ke layar
dan berhenti fungsi sesudahnya.
Kemudian Anda memiliki nama fungsi yang dapat Anda pilih.
Anda harus sedikit akal, seperti tidak memilih nama seperti xyz
atau seperti X2F.
Cobalah untuk membuat nama yang masuk akal.
>> Sebagai contoh, jika faktorial, katakanlah faktorial.
Jika itu adalah fungsi yang akan menggambar sesuatu, nama itu menarik.
Dan kemudian kita memiliki parameter, yang juga disebut argumen,
yang seperti sumber daya yang fungsi Anda membutuhkan
dari kode Anda untuk melakukan tugasnya.
Jika Anda ingin menghitung faktorial dari angka
Mungkin Anda harus memiliki nomor untuk menghitung faktorial.
Salah satu argumen yang Anda akan miliki adalah nomor sendiri.
Dan kemudian itu akan melakukan sesuatu dan mengembalikan nilai di akhir
kecuali jika fungsi void.
Mari kita lihat contoh.
Jika saya ingin menulis fungsi yang merangkum semua angka dalam sebuah array bilangan bulat,
pertama-tama, jenis kembali akan menjadi int
karena saya memiliki sebuah array bilangan bulat.
Dan kemudian aku akan memiliki nama fungsi seperti sumArray,
dan kemudian itu akan mengambil array itu sendiri, untuk nums int,
dan kemudian panjang dari array jadi saya tahu berapa banyak angka yang saya harus jumlah.
Lalu aku harus menginisialisasi sejumlah variabel yang disebut, misalnya, untuk 0,
dan setiap kali aku melihat sebuah elemen dalam array saya harus menambahkannya ke sum, jadi saya lakukan untuk loop.
Sama seperti Lexi mengatakan, Anda lakukan int i = 0, i <panjang dan i + +.
Dan untuk setiap elemen dalam array saya lakukan jumlah + = nums [i],
dan kemudian saya kembali jumlahnya, sehingga sangat sederhana, dan menghemat banyak kode
jika Anda menggunakan fungsi ini banyak kali.
Kemudian kami mengambil melihat kondisi.
Kami memiliki if, else, dan lain jika.
Mari kita lihat apa perbedaan antara mereka.
Lihatlah ini 2 kode. Apa perbedaan antara mereka?
Yang pertama telah-dasarnya kode ingin kau mengatakan
jika nomor adalah +, -, atau 0.
Yang pertama mengatakan jika> 0 maka itu positif.
Jika itu = ke 0 maka itu 0, dan jika <0 maka hasilnya negatif.
>> Dan yang lain lakukan if, else if, else.
Perbedaan antara keduanya adalah bahwa yang satu ini benar-benar akan
memeriksa apakah> 0, <0 atau = 0 tiga kali,
jadi jika Anda memiliki nomor 2, misalnya, itu akan datang ke sini dan mengatakan
if (x> 0), dan itu akan mengatakan ya, jadi saya mencetak positif.
Tapi meskipun aku tahu bahwa itu> 0 dan itu tidak akan menjadi 0 atau <0
Aku masih akan lakukan itu 0, apakah <0,
jadi aku benar-benar akan dalam ifs bahwa saya tidak perlu
karena saya sudah tahu bahwa itu tidak akan memenuhi salah satu kondisi.
Saya bisa menggunakan if, else if, else pernyataan.
Pada dasarnya mengatakan jika x = 0 Saya mencetak positif.
Jika tidak, aku akan juga menguji hal ini.
Jika itu 2 tidak aku akan melakukan hal ini.
Pada dasarnya jika saya memiliki x = 2 Anda akan mengatakan
if (x> 0), ya, jadi mencetak ini.
Sekarang saya tahu bahwa itu> 0 dan itu puas pertama jika
Aku bahkan tidak akan menjalankan kode ini.
Kode berjalan lebih cepat, sebenarnya, 3 kali lebih cepat jika Anda menggunakan ini.
Kami juga belajar tentang dan dan atau.
Aku tidak akan pergi melalui ini karena Lexi sudah berbicara tentang mereka.
Ini hanya && dan operator | |.
>> Satu-satunya hal saya akan katakan adalah berhati-hati ketika Anda memiliki 3 kondisi.
Gunakan tanda kurung karena itu sangat membingungkan ketika Anda memiliki kondisi
dan satu lagi atau satu lagi.
Gunakan tanda kurung hanya untuk memastikan bahwa kondisi Anda masuk akal
karena dalam kasus itu, misalnya, Anda dapat membayangkan bahwa
bisa jadi kondisi pertama dan satu atau yang lain
atau 2 kondisi gabungan dalam dan
atau yang ketiga, jadi berhati-hatilah.
Dan akhirnya, kami berbicara tentang switch.
Switch adalah sangat berguna ketika Anda memiliki variabel.
Mari kita mengatakan bahwa Anda memiliki variabel seperti n
yang bisa 0, 1, atau 2, dan untuk masing-masing kasus
Anda akan melakukan tugas.
Anda dapat mengatakan beralih variabel, dan itu menunjukkan bahwa
Nilai kemudian seperti nilai1 Aku akan melakukan hal ini,
dan kemudian saya putuskan, yang berarti aku tidak akan melihat salah satu kasus lain
karena kita sudah puas kasus
dan kemudian nilai2 dan sebagainya, dan saya juga dapat memiliki tombol default.
Itu berarti jika tidak memenuhi salah satu kasus yang saya punya
bahwa aku akan melakukan sesuatu yang lain, tapi itu opsional.
Itu semua untuk saya. Sekarang mari kita Tommy.
Baiklah, ini akan menjadi Minggu 3-ish.
Ini adalah beberapa topik yang kami akan meliputi, kripto, ruang lingkup, array, dan sebagainya.
Hanya kata cepat pada kripto. Kami tidak akan palu rumah ini.
>> Kami melakukan ini di pset 2, tapi untuk kuis pastikan Anda tahu bedanya
antara cipher Caesar dan cipher Vigenère,
bagaimana kedua dari mereka yang bekerja cipher dan bagaimana rasanya untuk mengenkripsi
dan mendekripsi teks yang menggunakan 2 cipher.
Ingat, cipher Caesar hanya berputar setiap karakter dengan jumlah yang sama,
pastikan Anda mod dengan jumlah huruf dalam alfabet.
Dan cipher Vigenère, di sisi lain, berputar setiap karakter
dengan jumlah yang berbeda, jadi daripada mengatakan
diputar setiap karakter dengan 3 Vigenère akan berputar setiap karakter
dengan jumlah yang berbeda tergantung pada kata kunci tertentu
di mana setiap huruf dalam kata kunci mewakili beberapa jumlah yang berbeda
untuk memutar teks jelas oleh.
Mari kita pertama berbicara tentang ruang lingkup variabel.
Ada 2 jenis variabel.
Kami memiliki variabel lokal, dan ini akan didefinisikan
luar utama atau di luar fungsi atau blok,
dan ini akan dapat diakses di mana saja dalam program Anda.
Jika Anda memiliki fungsi dan fungsi yang merupakan loop sementara
variabel global yang besar dapat diakses di mana-mana.
Sebuah variabel lokal, di sisi lain, adalah scoped ke tempat di mana ia didefinisikan.
>> Jika Anda memiliki fungsi di sini, misalnya, kita memiliki fungsi g,
dan dalam g ada variabel di sini disebut y,
dan itu berarti bahwa ini adalah variabel lokal.
Meskipun variabel ini disebut y
dan variabel ini disebut y ini 2 fungsi
tidak tahu apa variabel lokal masing-masing berada.
Di sisi lain, di sini kita katakan int x = 5,
dan ini adalah di luar lingkup fungsi apapun.
Ini adalah di luar lingkup utama, jadi ini adalah variabel global.
Itu berarti bahwa di dalam dari 2 fungsi ketika saya mengatakan x - atau x + +
Saya mengakses x sama dimana ini y dan y ini adalah variabel yang berbeda.
Itulah perbedaan antara variabel global dan variabel lokal.
Sejauh desain yang bersangkutan, kadang-kadang itu mungkin ide yang lebih baik
untuk menjaga variabel lokal setiap kali Anda mungkin bisa
karena memiliki banyak variabel global bisa benar-benar membingungkan.
Jika Anda memiliki banyak fungsi semua memodifikasi hal yang sama
Anda mungkin lupa bagaimana jika fungsi ini sengaja memodifikasi ini global,
dan fungsi lainnya tidak tahu tentang hal itu,
dan itu tidak bisa cukup membingungkan karena Anda mendapatkan lebih banyak kode.
Menjaga variabel lokal setiap kali Anda mungkin bisa
adalah desain hanya baik.
Array, ingat, hanya daftar elemen dari jenis yang sama.
Di dalam CI tidak bisa memiliki daftar seperti 1, 2,0, halo.
Kami hanya tidak bisa melakukan itu.
>> Ketika kita mendeklarasikan array di C semua elemen harus dari jenis yang sama.
Di sini saya memiliki sebuah array dari 3 bilangan bulat.
Di sini saya memiliki panjang array, tetapi jika aku hanya menyatakan dalam sintaks ini
di mana saya menentukan apa semua elemen yang saya tidak perlu secara teknis 3 ini.
Compiler cukup pintar untuk mengetahui seberapa besar array harus.
Sekarang ketika saya ingin mendapatkan atau menetapkan nilai dari array
ini adalah sintaks untuk melakukan itu.
Ini benar-benar akan mengubah elemen kedua dari array karena, ingat,
penomoran dimulai dari 0, bukan pada 1.
Jika saya ingin membaca nilai yang saya dapat mengatakan sesuatu seperti int x = array [1].
Atau jika saya ingin mengatur nilai tersebut, seperti yang saya lakukan di sini,
Saya dapat mengatakan array [1] = 4.
Waktu itu mengakses elemen dengan indeks mereka
atau posisi mereka atau di mana mereka berada dalam array,
dan daftar yang dimulai pada 0.
Kami juga dapat memiliki array dari array,
dan ini disebut array multi-dimensi.
Ketika kita memiliki array multi-dimensi
itu berarti kita dapat memiliki sesuatu seperti baris dan kolom,
dan ini adalah salah satu cara untuk memvisualisasikan ini atau berpikir tentang hal itu.
Ketika saya memiliki array multi-dimensi yang berarti aku akan mulai membutuhkan
lebih dari 1 indeks karena jika saya memiliki grid
hanya mengatakan apa baris anda berada di tidak memberi kami nomor.
Itu benar-benar hanya akan memberi kita daftar nomor.
Katakanlah saya punya array ini di sini.
Aku punya sebuah array disebut grid, dan saya katakan itu 2 baris dan 3 kolom,
dan jadi ini adalah salah satu cara untuk memvisualisasikan itu.
Ketika saya mengatakan saya ingin mendapatkan elemen pada [1] [2]
yang berarti bahwa karena ini adalah baris pertama dan kemudian kolom
Aku akan melompat ke baris 1 karena aku berkata 1.
>> Lalu aku akan datang ke sini ke kolom 2, dan aku akan mendapatkan nilai 6.
Masuk akal?
Multi-dimensi array, ingat, secara teknis hanya sebuah array dari array.
Kita dapat memiliki array dari array dari array.
Kita bisa terus, tapi benar-benar salah satu cara untuk berpikir tentang
bagaimana ini sedang ditata dan apa yang terjadi adalah untuk memvisualisasikan
dalam kotak seperti ini.
Ketika kami melewati array ke fungsi, mereka akan berperilaku
sedikit berbeda dari ketika kami melewati variabel reguler untuk fungsi
seperti lewat sebuah int atau float.
Ketika kita lulus dalam tipe int atau char atau salah satu data lain
kami hanya mengambil melihat apakah fungsi memodifikasi
nilai variabel bahwa perubahan tidak akan menyebarkan up
untuk fungsi panggilan.
Dengan array, di sisi lain, yang akan terjadi.
Jika saya lulus dalam array untuk beberapa fungsi dan fungsi yang mengubah beberapa unsur,
ketika saya datang kembali ke fungsi yang memanggilnya
array saya sekarang akan berbeda, dan kosa kata untuk itu
array adalah tersebut diteruskan oleh referensi, seperti yang akan kita lihat nanti.
Hal ini terkait dengan bagaimana kerja pointer, di mana jenis data dasar,
di sisi lain, yang disahkan oleh nilai.
>> Kita bisa memikirkan bahwa sebagai membuat salinan beberapa variabel dan kemudian melewati di copy.
Tidak peduli apa yang kita lakukan dengan variabel itu.
Pemanggilan fungsi tidak akan menyadari bahwa itu berubah.
Array hanya sedikit berbeda dalam hal itu.
Misalnya, seperti yang kita hanya melihat, utamanya hanyalah fungsi
yang dapat mengambil dalam 2 argumen.
Argumen pertama yang fungsi utamanya adalah argc, atau jumlah argumen,
dan argumen kedua disebut argv,
dan mereka adalah nilai yang sebenarnya dari argumen-argumen.
Katakanlah saya memiliki program yang disebut this.c,
dan saya katakan membuat ini, dan aku akan menjalankan ini pada baris perintah.
Sekarang untuk lulus dalam beberapa argumen untuk program saya disebut ini,
Saya bisa mengatakan sesuatu seperti / ini adalah cs 50..
Ini adalah apa yang kita bayangkan David harus dilakukan setiap hari di terminal.
Tapi sekarang di dalam fungsi utama dari program yang
memiliki nilai-nilai, sehingga argc adalah 4.
Ini mungkin sedikit membingungkan karena benar-benar kami hanya lewat di cs adalah 50.
Itu hanya 3.
Tapi ingat bahwa elemen pertama dari argv atau argumen pertama
adalah nama dari fungsi itu sendiri.
Jadi itu berarti bahwa kita memiliki 4 hal di sini,
dan elemen pertama akan menjadi / ini..
Dan ini akan diwakili sebagai string.
Kemudian elemen yang tersisa adalah apa yang kita mengetik setelah nama program.
Jadi hanya sebagai samping, seperti yang kita mungkin melihat di pset 2,
ingat bahwa string adalah 50 ≠ 50 integer.
Jadi kita tidak bisa mengatakan sesuatu seperti, 'int x = argv 3.'
>> Itu hanya tidak akan masuk akal, karena ini adalah string, dan ini adalah bilangan bulat.
Jadi jika Anda ingin mengkonversi antara 2 ini, ingat, kita akan
memiliki fungsi sihir yang disebut atoi.
Yang mengambil string dan mengembalikan integer diwakili dalam string tersebut.
Jadi itulah kesalahan mudah untuk membuat kuis,
hanya berpikir bahwa ini otomatis akan menjadi jenis yang tepat.
Tapi hanya tahu bahwa ini akan selalu string
bahkan jika string hanya berisi integer atau karakter atau pelampung.
Jadi sekarang mari kita bicara tentang waktu berjalan.
Ketika kita memiliki semua algoritma ini yang melakukan semua hal-hal gila,
itu menjadi benar-benar berguna untuk bertanya, "Berapa lama mereka ambil?"
Kami menyatakan bahwa dengan sesuatu yang disebut notasi asimtotik.
Jadi ini berarti bahwa - baik, katakanlah kita memberikan algoritma
beberapa masukan benar-benar, benar-benar besar.
Kami ingin bertanya, "Berapa lama itu akan berlangsung?
Berapa banyak langkah yang dibutuhkan untuk menjalankan algoritma kami
sebagai fungsi dari ukuran masukan? "
Jadi cara pertama kita dapat menggambarkan waktu dijalankan adalah dengan big O.
Dan ini adalah kasus terburuk waktu berjalan kami.
Jadi jika kita ingin mengurutkan array, dan kami memberikan algoritma kami array
yang ada di urutan ketika harus dalam urutan menaik,
itu akan menjadi kasus terburuk.
Ini adalah atas kami terikat dalam jangka waktu maksimal algoritma kami akan mengambil.
Di sisi lain, ini Ω akan menjelaskan kasus terbaik waktu berjalan.
Jadi, jika kita memberikan sebuah array yang sudah diurutkan dengan algoritma sorting,
berapa lama waktu yang dibutuhkan untuk semacam itu?
Dan ini, maka, menggambarkan batas bawah pada waktu berjalan.
Jadi di sini adalah beberapa kata-kata yang menggambarkan beberapa kali berjalan umum.
Ini adalah dalam urutan menaik.
Waktu tercepat berjalan kita miliki disebut konstan.
>> Itu berarti tidak peduli berapa banyak elemen yang kita berikan algoritma kami,
tidak peduli seberapa besar array kita adalah, menyortir itu
atau melakukan apa pun yang kita lakukan untuk array akan selalu mengambil jumlah waktu yang sama.
Jadi kita bisa menyatakan bahwa hanya dengan 1, yang merupakan konstanta.
Kami juga melihat pada waktu berjalan logaritmik.
Jadi sesuatu seperti pencarian biner adalah logaritmik,
di mana kita memotong masalah dalam setengah setiap kali
dan kemudian hal-hal yang hanya mendapatkan lebih tinggi dari sana.
Dan jika Anda pernah menulis sebuah O dari setiap algoritma faktorial,
Anda mungkin tidak harus mempertimbangkan ini sebagai pekerjaan anda.
Ketika kita bandingkan kali menjalankannya penting untuk diingat hal-hal ini.
Jadi jika saya memiliki algoritma yang O (n), dan orang lain
memiliki algoritma O (2n) ini sebenarnya asimtotik setara.
Jadi jika kita membayangkan n menjadi jumlah yang besar seperti sebelas miliar:
jadi ketika kita membandingkan sebelas miliar untuk sesuatu seperti sebelas miliar + 3,
tiba-tiba +3 itu tidak benar-benar membuat perbedaan besar lagi.
Itulah sebabnya kita akan mulai mempertimbangkan hal-hal untuk menjadi setara.
So hal-hal seperti ini konstanta sini, ada 2 x ini, atau menambahkan 3,
ini hanya konstanta, dan ini akan turun naik.
Jadi itulah mengapa semua 3 ini kali run adalah sama dengan mengatakan mereka O (n).
Demikian pula, jika kita memiliki 2 kali run lain, katakanlah O (n + 2n ² ³), kita dapat menambahkan
+ N, + 7, dan kemudian kita memiliki waktu berjalan itu hanya O (n ³).
lagi, ini adalah hal yang sama karena ini - ini adalah tidak sama.
Ini adalah hal yang sama, maaf. Jadi ini adalah sama karena
ini ³ n akan mendominasi ² 2n.
>> Apa yang tidak hal yang sama jika kita telah menjalankan kali seperti O (n ³) dan O (n ²)
karena ini ³ n jauh lebih besar daripada ini ² n.
Jadi jika kita memiliki eksponen, tiba-tiba ini mulai peduli,
tetapi ketika kita hanya berurusan dengan faktor-faktor seperti kita di sini,
maka itu tidak akan menjadi masalah karena mereka hanya akan drop out.
Mari kita lihat beberapa algoritma yang telah kita lihat sejauh ini
dan berbicara tentang waktu berjalan mereka.
Cara pertama mencari nomor dalam daftar, yang kita lihat, adalah pencarian linear.
Dan pelaksanaan pencarian linear adalah super mudah.
Kami hanya memiliki daftar, dan kita akan melihat setiap elemen dalam daftar
sampai kita menemukan nomor yang kita cari.
Jadi itu berarti bahwa dalam kasus terburuk, ini O (n).
Dan kasus terburuk di sini bisa jika elemen adalah
elemen terakhir, kemudian menggunakan pencarian linear kita harus melihat setiap elemen tunggal
hingga sampai yang terakhir untuk mengetahui bahwa itu sebenarnya dalam daftar.
Kita tidak bisa hanya menyerah di tengah jalan dan berkata, "Ini mungkin tidak ada."
Dengan pencarian linear kita harus melihat semuanya.
Waktu berjalan kasus terbaik, di sisi lain, adalah konstan
karena dalam kasus terbaik elemen yang kita cari adalah hanya yang pertama dalam daftar.
Jadi itu akan membawa kita tepat 1 langkah, tidak peduli seberapa besar daftar ini
jika kita mencari elemen pertama setiap kali.
>> Jadi, ketika Anda mencari, ingat, itu tidak mengharuskan daftar kami akan diurutkan.
Karena kita hanya akan melihat lebih setiap elemen tunggal, dan itu tidak terlalu penting
rangka apa unsur-unsur yang masuk
Sebuah algoritma pencarian yang lebih cerdas adalah sesuatu seperti pencarian biner.
Ingat, pelaksanaan pencarian biner adalah ketika Anda akan
terus mencari di tengah daftar.
Dan karena kita sedang melihat tengah, kami mengharuskan daftar diurutkan
atau kita tidak tahu di mana tengah adalah, dan kita harus melihat lebih
seluruh daftar untuk menemukan itu, dan kemudian pada saat itu kami hanya membuang-buang waktu.
Jadi jika kita memiliki daftar diurutkan dan kami menemukan tengah, kita akan membandingkan tengah
ke elemen yang kita cari.
Jika terlalu tinggi, maka kita bisa melupakan kanan setengah
karena kita tahu bahwa jika elemen kita sudah terlalu tinggi
dan segala sesuatu di sebelah kanan elemen ini bahkan lebih tinggi,
maka kita tidak perlu melihat ada lagi.
Dimana di sisi lain, jika elemen kami terlalu rendah,
kita tahu semuanya ke kiri elemen yang juga terlalu rendah,
sehingga tidak benar-benar masuk akal untuk melihat di sana, baik.
Dengan cara ini, dengan setiap langkah dan setiap kali kita melihat pada titik tengah dari daftar,
kita akan memotong masalah kita di setengah karena tiba-tiba kita tahu
sejumlah angka yang tidak bisa menjadi orang yang kita cari.
>> Dalam pseudocode ini akan terlihat seperti ini,
dan karena kita sedang memotong daftar di setengah setiap saat,
kami terburuk melompat run time dari linier logaritmik.
Begitu tiba-tiba kita memiliki log-in langkah-langkah untuk menemukan elemen dalam daftar.
Waktu berjalan kasus terbaik, meskipun, masih konstan
karena sekarang, mari kita hanya mengatakan bahwa elemen yang kita cari adalah
selalu tengah tepat dari daftar asli.
Jadi kita dapat tumbuh daftar kami sebesar seperti yang kita inginkan, tapi jika elemen yang kita cari adalah di tengah,
maka itu hanya akan membawa kita 1 langkah.
Jadi itulah sebabnya kami O (log n) dan Ω (1) atau konstan.
Mari kita benar-benar menjalankan pencarian biner pada daftar ini.
Jadi mari kita mengatakan bahwa kita sedang mencari elemen 164.
Hal pertama yang akan kita lakukan adalah menemukan titik tengah dari daftar ini.
Kebetulan bahwa titik tengah akan jatuh antara 2 angka,
jadi mari kita katakan sewenang-wenang, setiap kali titik tengah jatuh antara 2 angka,
mari kita mengumpulkan.
Kami hanya perlu memastikan bahwa kita melakukan hal ini setiap langkah dari jalan.
Jadi kita akan mengumpulkan, dan kita akan mengatakan bahwa 161 adalah tengah daftar kami.
Jadi 161 <164, dan setiap elemen di sebelah kiri dari 161
juga <164, jadi kita tahu bahwa itu tidak akan membantu kami sama sekali
untuk mulai mencari ke sini karena elemen yang kita cari tidak bisa berada di sana.
Jadi apa yang bisa kita lakukan adalah kita hanya bisa melupakan bahwa kiri setengah seluruh daftar,
dan sekarang hanya mempertimbangkan dari kanan dan seterusnya 161.
>> Jadi sekali lagi, ini adalah titik tengah, mari kita hanya mengumpulkan.
Sekarang 175 terlalu besar.
Jadi kita tahu itu tidak akan membantu kami mencari di sini atau di sini,
jadi kami hanya bisa membuang itu pergi, dan akhirnya kita akan memukul 164.
Setiap pertanyaan pada pencarian biner?
Mari kita beralih dari mencari melalui daftar yang sudah diurutkan
untuk benar-benar mengambil daftar nomor dalam urutan apapun
dan membuat daftar itu dalam urutan menaik.
Algoritma pertama kita melihat disebut bubble sort.
Dan ini akan menjadi lebih sederhana dari algoritma yang kita lihat.
Bubble sort mengatakan bahwa bila ada 2 unsur dalam daftar adalah keluar dari tempat,
berarti ada jumlah yang lebih tinggi di sebelah kiri angka yang lebih rendah,
maka kita akan swap mereka, karena itu berarti bahwa daftar akan
"Lebih diurutkan" daripada sebelumnya.
Dan kami hanya akan melanjutkan proses ini lagi dan lagi dan lagi
sampai akhirnya jenis unsur gelembung ke lokasi yang benar dan kami memiliki daftar diurutkan.
>> Waktu run ini akan menjadi O (n ²). Kenapa?
Nah, karena dalam kasus terburuk, kita akan mengambil setiap elemen, dan
kita akan berakhir membandingkannya dengan setiap elemen lain dalam daftar.
Tapi dalam kasus terbaik, kami memiliki daftar yang sudah diurutkan, gelembung semacam ini
hanya akan pergi melalui sekali, katakan "Tidak. Aku tidak melakukan swap, jadi saya sudah selesai."
Jadi kami memiliki waktu terbaik-kasus menjalankan Ω (n).
Mari kita jalankan bubble sort pada daftar.
Atau pertama, mari kita lihat pseudocode beberapa benar-benar cepat.
Kami ingin mengatakan kita ingin melacak, dalam setiap iterasi dari loop,
melacak apakah atau tidak kita mengubah setiap elemen.
Jadi alasan untuk itu adalah, kita akan berhenti ketika kita tidak bertukar setiap elemen.
Jadi pada awal loop kita belum bertukar apa-apa, jadi kita akan mengatakan bahwa itu palsu.
Sekarang, kita akan pergi melalui daftar dan bandingkan elemen ke elemen i i + 1
dan jika itu adalah kasus bahwa ada sejumlah besar di sebelah kiri sejumlah kecil,
maka kita hanya akan swap mereka.
>> Dan kemudian kita akan ingat bahwa kita bertukar elemen.
Itu berarti bahwa kita harus pergi melalui daftar setidaknya 1 lebih banyak waktu
karena kondisi di mana kami berhenti adalah ketika seluruh daftar sudah diurutkan,
artinya kita tidak membuat swap.
Jadi itulah sebabnya kondisi kita di sini adalah 'sementara beberapa elemen telah bertukar. "
Jadi sekarang mari kita lihat ini berjalan pada daftar.
Saya memiliki daftar 5,0,1,6,4.
Bubble sort akan mulai sepanjang jalan di sebelah kiri, dan itu akan membandingkan
elemen i, jadi 0 sampai i + 1, yang merupakan elemen 1.
Ini akan mengatakan, baik 5> 0, tapi sekarang 5 adalah ke kiri,
jadi saya perlu untuk menukar 5 dan 0.
Ketika saya swap mereka, tiba-tiba saya mendapatkan daftar yang berbeda.
Sekarang 5> 1, sehingga kita akan swap mereka.
5 tidak> 6, jadi kita tidak perlu melakukan apa-apa di sini.
Tapi 6> 4, jadi kita perlu untuk swap.
Sekali lagi, kita perlu untuk menjalankan melalui seluruh daftar untuk akhirnya menemukan
bahwa ini adalah rusak, kita swap mereka,
dan pada saat ini kita perlu menjalankan melalui daftar waktu 1 lebih
untuk memastikan bahwa semuanya dalam rangka, dan saat ini semacam titik gelembung telah selesai.
Sebuah algoritma yang berbeda untuk mengambil beberapa elemen dan menyortir mereka adalah semacam seleksi.
Ide di balik semacam seleksi adalah bahwa kita akan membangun sebagian diurutkan dari daftar
1 elemen pada suatu waktu.
>> Dan cara kita akan melakukan itu adalah dengan membangun segmen kiri dari daftar.
Dan pada dasarnya, setiap - pada setiap langkah, kita akan mengambil elemen terkecil kami telah meninggalkan
yang belum diurutkan belum, dan kita akan memindahkannya ke dalam segmen diurutkan.
Itu berarti kita perlu untuk terus menemukan elemen minimum unsorted
dan kemudian mengambil elemen minimum dan swap dengan apapun
kiri-sebagian elemen yang tidak diurutkan.
Waktu berjalan ini akan menjadi O (n ²) karena dalam kasus terburuk
kita perlu membandingkan setiap elemen tunggal untuk setiap elemen lain.
Karena kita katakan bahwa jika kita mulai dari kiri setengah dari daftar, kita perlu
untuk pergi melalui segmen seluruh hak untuk menemukan elemen terkecil.
Dan kemudian, sekali lagi, kita harus pergi ke segmen seluruh hak dan
terus selama itu berulang-ulang.
Itu akan menjadi n ². Kita akan membutuhkan untuk di dalam lingkaran lain untuk loop
yang menunjukkan ² n.
Dalam pemikiran kasus terbaik, katakanlah kita memberikan sebuah daftar yang sudah disortir;
kita benar-benar tidak melakukan lebih baik daripada ² n.
Karena semacam seleksi tidak memiliki cara untuk mengetahui bahwa
elemen minimum adalah hanya yang saya kebetulan melihat.
Ini masih perlu untuk memastikan bahwa ini sebenarnya minimum.
>> Dan satu-satunya cara untuk memastikan bahwa itu minimum, menggunakan algoritma ini,
adalah dengan melihat setiap elemen tunggal lagi.
Jadi benar-benar, jika Anda memberikan itu - jika Anda memberikan semacam seleksi daftar yang sudah diurutkan,
itu tidak akan melakukan lebih baik daripada memberikan sebuah daftar yang tidak diurutkan belum.
By the way, jika hal itu terjadi menjadi kasus bahwa ada sesuatu yang O (sesuatu)
dan omega dari sesuatu, kita hanya bisa mengatakan lebih ringkas bahwa itu θ sesuatu.
Jadi jika Anda melihat yang muncul di mana saja, itulah yang hanya berarti.
>> Jika ada sesuatu yang theta dari n ², keduanya O besar (n ²) dan Ω (n ²).
Sehingga kasus terbaik dan kasus terburuk, itu tidak membuat perbedaan,
algoritma akan melakukan hal yang sama setiap waktu.
Jadi ini adalah apa pseudocode untuk semacam seleksi bisa terlihat seperti.
Kita pada dasarnya akan mengatakan bahwa saya ingin iterate atas daftar
dari kiri ke kanan, dan pada setiap iterasi dari loop, aku akan pindah
elemen minimum dalam bagian ini diurutkan dari daftar.
Dan setelah saya memindahkan sesuatu di sana, saya tidak pernah perlu melihat unsur itu lagi.
Karena begitu saya swap elemen ke segmen kiri dari daftar, itu diurutkan
karena kita melakukan segala sesuatu dalam urutan dengan menggunakan minimum.
Jadi kami berkata, oke, kita berada di posisi saya, dan kita perlu melihat semua elemen
di sebelah kanan saya untuk menemukan minimum.
Jadi itu berarti kita ingin melihat dari i + 1 ke akhir daftar.
Dan sekarang, jika elemen yang kita sedang melihat kurang dari minimum kami sejauh ini,
yang, ingat, kita mulai off minimal untuk hanya menjadi
apapun elemen kita saat ini di, saya akan menganggap itu minimum.
Jika saya menemukan sebuah elemen yang lebih kecil dari itu, maka aku akan mengatakan, oke,
baik, saya telah menemukan minimal baru.
Aku akan mengingat di mana minimum itu.
>> Jadi sekarang, setelah aku sudah melalui segmen unsorted yang tepat,
Saya dapat mengatakan aku akan menukar elemen minimum dengan elemen yang ada di posisi saya.
Itu akan membangun daftar saya, saya bagian dari daftar diurutkan dari kiri ke kanan,
dan kita tidak merasa perlu untuk melihat elemen lagi setelah itu di bagian itu.
Setelah kami bertukar.
Jadi mari kita jalankan semacam pilihan pada daftar ini.
Elemen biru di sini akan menjadi i, dan unsur warna merah akan menjadi elemen minimal.
Jadi saya mulai sepanjang jalan di sebelah kiri dari daftar, sehingga pada 5.
Sekarang kita perlu menemukan elemen unsorted minimum.
Jadi kita katakan 0 <5, sehingga 0 adalah minimum baru saya.
>> Tapi aku tidak bisa berhenti di situ, karena meskipun kita dapat mengenali bahwa 0 adalah yang terkecil,
kita perlu berjalan melalui setiap elemen lain dari daftar untuk memastikan.
Jadi 1 lebih besar, lebih besar 6, 4 lebih besar.
Itu berarti bahwa setelah melihat semua elemen, saya sudah bertekad 0 adalah yang terkecil.
Jadi aku akan menukar 5 dan 0.
Setelah saya swap itu, aku akan mendapatkan daftar baru, dan saya tahu bahwa saya tidak perlu melihat bahwa 0 lagi
karena sekali saya sudah bertukar, saya sudah diurutkan dan kami sudah selesai.
Sekarang kebetulan bahwa elemen biru lagi 5,
dan kita perlu melihat 1, 6 dan 4 untuk menentukan bahwa 1
adalah elemen minimum terkecil, jadi kita akan swap 1 dan 5.
Sekali lagi, kita perlu melihat - membandingkan 5 ke 6 dan 4,
dan kita akan menukar 4 dan 5, dan akhirnya, bandingkan
mereka 2 angka dan swap mereka sampai kita mendapatkan daftar kami diurutkan.
Setiap pertanyaan tentang selection sort?
Oke. Mari kita pindah ke topik terakhir di sini, dan itu adalah rekursi.
>> Rekursi, ingat, ini hal meta-benar di mana fungsi
berulang kali menyebut dirinya.
Jadi di beberapa titik, sementara fungsinya kita berulang kali menyebut dirinya,
perlu ada beberapa titik di mana kita berhenti memanggil diri kita sendiri.
Karena jika kita tidak melakukan itu, maka kita hanya akan terus melakukan hal ini selamanya,
dan program kami hanya tidak akan mengakhiri.
Kami menyebutnya kondisi ini kasus dasar.
Dan kasus dasar mengatakan, daripada memanggil fungsi lagi,
Aku hanya akan kembali beberapa nilai.
Jadi setelah kami telah kembali nilai, kami telah berhenti memanggil diri kita sendiri,
dan sisanya dari panggilan yang kita buat sejauh ini juga dapat kembali.
Kebalikan dari kasus dasar adalah kasus rekursif.
Dan ini adalah ketika kita ingin membuat panggilan lain untuk fungsi yang kita saat ini masuk
Dan kita mungkin, meskipun tidak selalu, ingin menggunakan argumen yang berbeda.
>> Jadi jika kita memiliki fungsi yang disebut f, dan f hanya disebut mengambil 1 argumen,
dan kami hanya terus menelepon f (1), f (1), f (1), dan itu hanya terjadi bahwa
argumen 1 jatuh ke dalam kasus rekursif, kita masih tidak akan pernah berhenti.
Bahkan jika kita memiliki kasus dasar, kita perlu memastikan bahwa pada akhirnya kita akan memukul kasus dasar.
Kami tidak terus tinggal dalam hal ini rekursif.
Umumnya, ketika kita menyebut diri kita, kita mungkin akan memiliki argumen yang berbeda setiap kali.
Berikut ini adalah fungsi rekursif benar-benar sederhana.
Jadi ini akan menghitung faktorial dari angka.
Up atas sini kita memiliki kasus dasar kami.
Dalam hal bahwa n ≤ 1, kita tidak akan memanggil faktorial lagi.
Kita akan berhenti, kami hanya akan mengembalikan nilai tertentu.
Jika hal ini tidak benar, maka kita akan memukul kasus rekursif kami.
Perhatikan di sini bahwa kita tidak hanya memanggil faktorial (n), karena itu tidak akan sangat membantu.
Kita akan memanggil faktorial sesuatu yang lain.
>> Dan sehingga Anda dapat melihat, pada akhirnya jika kita melewati sesuatu faktorial (5) atau,
kita akan memanggil faktorial (4) dan seterusnya, dan akhirnya kita akan memukul ini kasus dasar.
Jadi ini terlihat baik. Mari kita lihat apa yang terjadi ketika kita benar-benar menjalankan ini.
Ini adalah stack, dan mari kita mengatakan bahwa utama akan memanggil fungsi ini dengan argumen (4).
Jadi sekali faktorial melihat dan = 4, faktorial akan memanggil dirinya sendiri.
Sekarang, tiba-tiba, kami memiliki faktorial (3).
Jadi fungsi-fungsi ini akan terus tumbuh sampai akhirnya kita memukul kasus dasar kami.
Pada titik ini, nilai pengembalian ini adalah kembali (nx nilai kembali dari ini),
nilai pengembalian ini adalah nx nilai pengembalian ini.
Akhirnya kita perlu untuk memukul beberapa nomor.
Di atas sini, kita katakan kembali 1.
Itu berarti bahwa sekali kita kembali jumlah tersebut, kita dapat pop ini dari tumpukan.
Jadi ini faktorial (1) dilakukan.
Ketika kembali 1, ini (1) faktorial kembali, ini kembali ke 1.
Nilai kembali dari ini, ingat, adalah nx nilai pengembalian ini.
Begitu tiba-tiba, orang ini tahu bahwa saya ingin kembali 2.
>> Jadi ingat, mengembalikan nilai ini hanya nx nilai kembali di sini.
Jadi sekarang kita dapat mengatakan 3 x 2, dan akhirnya, di sini kita dapat mengatakan
ini hanya akan menjadi 4 x 3 x 2.
Dan sekali ini kembali, kami turun ke dalam bilangan bulat tunggal utama.
Setiap pertanyaan tentang rekursi?
Baiklah. Jadi ada lebih banyak waktu untuk pertanyaan-pertanyaan di akhir,
tapi sekarang Yusuf akan mencakup topik yang tersisa.
>> [Joseph Ong] Baiklah. Jadi sekarang kita bicarakan recursions,
mari kita bicara sedikit tentang apa menggabungkan semacam ini.
Merge sort pada dasarnya cara lain untuk menyortir daftar nomor.
Dan cara kerjanya adalah, dengan gabungan semacam Anda memiliki daftar, dan apa yang kita lakukan adalah
kita katakan, mari kita membagi ini menjadi 2 bagian.
Pertama-tama kita akan menjalankan menggabungkan semacam lagi di kiri setengah,
maka kita akan jalankan menggabungkan semacam di kanan setengah,
dan yang memberi kita sekarang 2 bagian yang diurutkan, dan sekarang kita akan menggabungkan mereka bersama-sama bagian.
Ini agak sulit untuk melihat tanpa contoh, jadi kita akan pergi melalui gerakan dan melihat apa yang terjadi.
Jadi Anda mulai dengan daftar ini, kami membagi menjadi 2 bagian.
Kami menjalankan menggabungkan semacam di kiri setengah pertama.
Jadi itulah kiri setengah, dan sekarang kita menjalankan mereka melalui daftar ini lagi
yang akan dilewatkan ke semacam gabungan, dan kemudian kita melihat, sekali lagi,
di sisi kiri dari daftar ini dan kami jalankan menggabungkan semacam di atasnya.
Sekarang, kita turun ke daftar nomor 2,
dan sekarang kiri setengah hanya 1 elemen yang panjang, dan kita tidak bisa
membagi daftar yang hanya 1 elemen menjadi setengah, jadi kami hanya mengatakan, setelah kami memiliki 50,
yang hanya 1 elemen, itu sudah diurutkan.
>> Setelah kami selesai dengan itu, kita dapat melihat bahwa kita bisa
pindah ke kanan setengah dari daftar ini,
dan 3 juga diurutkan, dan jadi sekarang bahwa kedua bagian dari daftar ini diurutkan
kita bisa bergabung dengan angka-angka ini kembali bersama-sama.
Jadi kita melihat 50 dan 3, 3 lebih kecil dari 50, sehingga masuk terlebih dulu dan kemudian 50 masuk
Sekarang, itu dilakukan, kita kembali ke daftar itu dan semacam itu setengah benar.
42 adalah nomor itu sendiri, jadi sudah diurutkan.
Jadi sekarang kita membandingkan 2 dan 3 lebih kecil dari 42, sehingga akan dimasukkan ke dalam pertama,
sekarang 42 akan dimasukkan ke dalam, dan 50 akan meletakkan masuk
Sekarang, itu diurutkan, kita pergi semua jalan kembali ke atas, 1.337 dan 15.
Nah, sekarang kita melihat kiri setengah dari daftar ini, 1.337 adalah dengan sendirinya sehingga yang diurutkan dan sama dengan 15.
Jadi sekarang kita menggabungkan 2 angka untuk menyortir daftar itu asli, 15 <1337,
sehingga masuk terlebih dulu, kemudian berjalan masuk 1.337
Dan sekarang kita diurutkan kedua bagian dari daftar asli di bagian atas.
Dan semua yang harus kita lakukan adalah menggabungkan.
Kami melihat 2 angka pertama dari daftar ini, 3 <15, sehingga masuk ke array semacam pertama.
15 <42, sehingga berjalan masuk Sekarang, 42 <1337, yang berlangsung masuk
50 <1337, begitu seterusnya masuk Dan perhatikan bahwa kami hanya mengambil 2 nomor dari daftar ini.
Jadi kita tidak hanya bergantian antara 2 daftar.
Kita hanya melihat awal, dan kami mengambil elemen
yang lebih kecil dan kemudian memasukkannya ke dalam array kita.
Sekarang kita sudah digabung semua bagian dan kami sudah selesai.
>> Setiap pertanyaan tentang merge sort? Ya?
[Mahasiswa] Jika membelah diri menjadi kelompok-kelompok yang berbeda, mengapa mereka tidak hanya membagi sekali
dan Anda memiliki 3 dan 2 dalam kelompok? [Sisa dimengerti pertanyaan]
Alasan - jadi pertanyaannya adalah, mengapa kita tidak bisa hanya menggabungkan mereka pada langkah pertama setelah kita memilikinya?
Alasan kami bisa melakukan hal ini, mulai dari yang paling kiri elemen dari kedua belah pihak,
dan kemudian mengambil yang lebih kecil dan memasukkannya ke dalam, adalah bahwa kita tahu bahwa
daftar individu dalam perintah diurutkan.
Jadi jika saya sedang melihat kiri-paling elemen kedua bagian,
Saya tahu mereka akan menjadi unsur terkecil dari daftar tersebut.
Jadi saya bisa menempatkan mereka ke tempat elemen terkecil dari daftar ini besar.
Di sisi lain, jika saya melihat orang-orang 2 daftar di tingkat kedua di sana,
50, 3, 42, 1.337 dan 15, mereka tidak diurutkan.
Jadi jika saya melihat 50 dan 1337, aku akan dimasukkan ke dalam daftar 50 saya pertama.
Tapi itu tidak benar-benar masuk akal, karena 3 adalah elemen terkecil dari semua orang.
Jadi satu-satunya alasan yang bisa kita lakukan langkah ini adalah karena menggabungkan daftar kami sudah diurutkan.
Itulah sebabnya kita harus turun sampai ke bawah
karena ketika kita hanya memiliki satu nomor, Anda tahu bahwa satu nomor
dalam dan dari dirinya sendiri sudah daftar diurutkan.
>> Ada pertanyaan? Tidak ada?
Kompleksitas? Nah, Anda bisa melihat bahwa di setiap langkah ada nomor akhir,
dan kita dapat membagi daftar dalam log setengah n kali,
yang mana kita mendapatkan ini log n x n kompleksitas.
Dan Anda akan melihat kasus terbaik untuk gabungan semacam adalah n log n, dan kebetulan
bahwa kasus terburuk, atau Ω di sana, juga n log n.
Sesuatu yang perlu diingat.
Bergerak pada, mari kita pergi ke beberapa file dasar super I / O.
Jika Anda melihat Scramble, Anda akan melihat kami memiliki semacam sistem
di mana Anda bisa menulis ke file log jika Anda membaca kode.
Mari kita lihat bagaimana Anda bisa melakukan itu.
Nah, kita memiliki fprintf, yang dapat Anda pikirkan hanya sebagai printf,
tapi hanya mencetak ke file bukan, dan karenanya f di awal.
Ini semacam kode di sini, apa yang dilakukannya adalah, karena Anda mungkin telah melihat di Scramble,
ia pergi melalui 2-dimensi pencetakan array Anda keluar baris demi baris apa jumlahnya.
Dalam kasus ini, printf mencetak ke terminal Anda atau apa yang kita sebut output standar bagian.
>> Dan sekarang, dalam hal ini, yang harus kita lakukan adalah mengganti printf dengan fprintf,
ceritakan apa file yang ingin Anda cetak, dan dalam hal ini hanya mencetaknya ke file yang
bukannya mencetak keluar ke terminal Anda.
Nah, maka itu menimbulkan pertanyaan: mana kita mendapatkan semacam file dari, kan?
Kami melewati masuk ke ini fuction fprintf tapi kami tidak tahu dari mana asalnya.
Nah, di awal kode, apa yang kita miliki adalah serangkaian kode ini di sini,
yang pada dasarnya mengatakan bahwa terbuka file log.txt panggilan.
Apa yang kita lakukan setelah itu adalah kita harus memastikan bahwa file tersebut benar-benar dibuka berhasil.
Jadi mungkin gagal karena beberapa alasan, Anda tidak memiliki cukup ruang pada komputer Anda, misalnya.
Jadi selalu penting sebelum Anda melakukan operasi dengan file
bahwa kita memeriksa apakah file yang dibuka dengan sukses.
Jadi apa bahwa, itu argumen fopen, juga, kita dapat membuka file dalam banyak cara.
Apa yang dapat kita lakukan adalah, kita bisa lulus w, yang berarti menimpa file jika sudah keluar,
Kami dapat melewati suatu, yang mereka tambahkan ke akhir file bukan utama itu,
atau kita dapat menentukan r, yang berarti, mari kita buka file sebagai read-only.
Jadi jika program mencoba untuk membuat perubahan pada file tersebut,
berteriak pada mereka dan jangan biarkan mereka melakukannya.
Akhirnya, setelah kami selesai dengan file tersebut, selesai melakukan operasi di atasnya,
kita perlu memastikan bahwa kita menutup file.
Dan sehingga pada akhir program Anda, Anda akan melewati mereka lagi
file ini yang dibuka, dan hanya menutupnya.
Jadi ini adalah sesuatu yang penting bahwa Anda harus memastikan Anda lakukan.
Jadi ingat Anda dapat membuka file, maka Anda dapat menulis ke file tersebut,
melakukan operasi dalam file, tapi kemudian Anda harus menutup file di akhir.
>> Setiap pertanyaan pada file dasar I / O? Ya?
[Pertanyaan Mahasiswa, dipahami]
Di sini. Pertanyaannya adalah, dari mana file ini log.txt muncul?
Nah, jika Anda hanya memberikan log.txt, itu menciptakan dalam direktori yang sama dengan eksekusi.
Jadi jika kau - >> [pertanyaan Mahasiswa, dipahami]
Ya. Dalam folder yang sama, atau dalam direktori yang sama, seperti yang Anda menyebutnya.
Sekarang memori, tumpukan, dan tumpukan.
Jadi bagaimana memori diletakkan di komputer?
Nah, Anda bisa membayangkan memori sebagai semacam ini blok di sini.
Dan dalam memori kita memiliki apa yang disebut tumpukan terjebak di sana, dan tumpukan yang ada di bawah sana.
Dan tumpukan tumbuh ke bawah dan tumpukan tumbuh ke atas.
Sehingga Tommy disebutkan - oh, baik, dan kita memiliki 4 segmen lain yang saya akan mendapatkan dalam satu detik -
Seperti Tommy mengatakan sebelumnya, Anda tahu bagaimana fungsi nya menyebut diri mereka dan memanggil satu sama lain?
Mereka membangun semacam ini stack frame.
Nah, jika panggilan utama foo, foo akan dimasukkan pada stack.
Foo panggilan bar, bar ini bisa diletakkan di stack, dan yang akan diletakkan di tumpukan setelah.
Dan saat mereka kembali, mereka masing-masing bisa diambil dari tumpukan.
Apa masing-masing lokasi dan memori terus?
Nah, bagian atas, yang merupakan segmen teks, berisi program itu sendiri.
Jadi kode mesin, yang ada di sana, setelah Anda mengkompilasi program Anda.
Selanjutnya, setiap diinisialisasi variabel global.
>> Jadi Anda memiliki variabel global dalam program Anda, dan Anda berkata seperti, a = 5,
yang akan dimasukkan ke dalam segmen itu, dan tepat di bawah itu,
Anda memiliki data global uninitialized, yang hanya int a,
tapi Anda tidak mengatakan itu sama dengan apa pun.
Sadarilah ini adalah variabel global, sehingga mereka berada di luar dari utama.
Jadi ini berarti setiap variabel global yang dideklarasikan tetapi tidak diinisialisasi.
Jadi apa yang ada di tumpukan? Memori yang dialokasikan dengan menggunakan malloc, yang akan kita sampai ke dalam sedikit.
Dan akhirnya, dengan tumpukan Anda memiliki variabel lokal
dan setiap fungsi yang Anda sebut dalam salah satu parameter mereka.
Hal terakhir, Anda tidak benar-benar harus tahu apa variabel lingkungan lakukan,
tapi setiap kali Anda menjalankan program, ada sesuatu yang terkait, seperti
ini adalah nama pengguna dari orang yang menjalankan program tersebut.
Dan itu akan menjadi semacam di bagian bawah.
Dalam hal alamat memori, yaitu nilai-nilai heksadesimal,
nilai-nilai pada awal atas pada 0, dan mereka pergi semua jalan ke bawah.
Dalam hal ini, jika Anda berada di sistem 32-bit,
alamat di bagian bawah akan menjadi 0x, diikuti oleh af, karena itulah 32 bit,
yang merupakan 8 byte, dan dalam hal ini 8 byte sesuai dengan 8 digit heksadesimal.
Jadi di sini Anda akan memiliki, seperti, 0xffffff, dan di sana Anda akan memiliki 0.
Jadi apa pointer? Beberapa dari Anda mungkin telah membahas hal ini dalam bagian sebelumnya.
tapi kami pergi lebih dari itu dalam kuliah, sehingga pointer hanyalah sebuah tipe data
yang toko, bukan semacam nilai seperti 50, menyimpan alamat dari beberapa lokasi di memori.
Seperti memori yang [dipahami].
Jadi dalam hal ini, apa yang telah kita adalah, kita memiliki pointer ke integer atau int *,
dan berisi alamat heksadesimal dari 0xDEADBEEF.
>> Jadi apa yang kita miliki adalah, sekarang, poin pointer ini di beberapa lokasi di memori,
dan itu hanya, nilai 50 adalah di lokasi memori.
Pada beberapa sistem 32-bit, pada semua sistem 32-bit, pointer mengambil bit 32 atau 4 byte.
Tapi, misalnya, pada sistem 64-bit, pointer adalah 64 bit.
Jadi itu adalah sesuatu yang Anda akan ingin diingat.
Jadi pada sistem akhir-bit, pointer adalah bit akhir panjang.
Pointer adalah semacam sulit untuk mencerna tanpa hal-hal ekstra,
jadi mari kita pergi melalui contoh alokasi memori dinamis.
Apa alokasi memori dinamis lakukan untuk Anda, atau apa yang kita sebut malloc,
itu memungkinkan Anda mengalokasikan semacam data di luar himpunan.
Jadi data ini adalah semacam lebih permanen untuk durasi program.
Karena seperti yang Anda tahu, jika Anda mendeklarasikan x dalam fungsi, dan yang mengembalikan fungsi,
Anda tidak lagi memiliki akses ke data yang tersimpan dalam x.
Apa pointer mari kita lakukan adalah mereka Mari kita menyimpan nilai-nilai memori atau toko
dalam segmen yang berbeda dari memori, yaitu heap.
Sekarang setelah kami kembali keluar dari fungsi, asalkan kita memiliki pointer
ke lokasi di memori, maka apa yang dapat kita lakukan adalah kita hanya dapat melihat nilai-nilai di sana.
Mari kita lihat contoh: Ini adalah tata letak memori kami lagi.
Dan kami memiliki fungsi ini, utama.
Apa yang dilakukannya adalah - oke, begitu sederhana, benar -? Int x = 5, itu hanya sebuah variabel pada stack di main.
>> Di sisi lain, sekarang kita mendeklarasikan pointer yang memanggil giveMeThreeInts fungsi.
Dan jadi sekarang kita masuk ke fungsi ini dan kami membuat stack frame baru untuk itu.
Namun, dalam stack frame, kita mendeklarasikan int * temp,
yang pada mallocs 3 bilangan bulat bagi kita.
Jadi ukuran int akan memberi kita berapa banyak byte int ini,
dan malloc memberi kita bahwa banyak byte ruang di heap.
Jadi dalam hal ini, kami telah menciptakan ruang yang cukup untuk 3 bilangan bulat,
dan tumpukan adalah cara di atas sana, itulah sebabnya saya sudah ditarik itu lebih tinggi.
Setelah kita selesai, kita kembali ke sini, Anda hanya perlu 3 ints kembali,
dan ia mengembalikan alamat, dalam hal ini lebih di mana memori yang.
Dan kami menetapkan pointer = switch, dan di sana kami hanya memiliki pointer lain.
Tapi apa yang mengembalikan fungsi ditumpuk di sini dan menghilang.
Jadi suhu menghilang, tapi kami masih mempertahankan alamat di mana
3 bilangan bulat mereka berada di dalam induk.
Jadi dalam set ini, pointer scoped lokal untuk frame ditumpuk,
tapi memori yang mereka lihat adalah di heap.
>> Apakah itu masuk akal?
[Siswa] Bisakah Anda mengulanginya? >> [Yusuf] Ya.
Jadi jika saya kembali hanya sedikit, Anda melihat bahwa suhu dialokasikan
beberapa memori di heap sana.
Jadi, ketika fungsi ini, giveMeThreeInts kembali, ini tumpukan sini akan menghilang.
Dan dengan itu salah satu variabel, dalam hal ini, ini pointer yang dialokasikan dalam bingkai ditumpuk.
Itu akan menghilang, tapi karena kami kembali suhu
dan kami mengatur pointer = temp, pointer yang sekarang akan menunjukkan memori yang sama dari lokasi sebagai temp.
Jadi sekarang, meskipun kita kehilangan temp, itu pointer lokal,
kita masih mempertahankan alamat memori dari apa itu menunjuk ke dalam variabel pointer itu.
Pertanyaan? Itu bisa menjadi semacam topik membingungkan jika Anda tidak pergi lebih dari itu dalam bagian.
Kita bisa, TF Anda pasti akan pergi di atasnya dan tentu saja kita dapat menjawab pertanyaan
pada akhir sesi review untuk ini.
Tapi ini adalah semacam topik yang kompleks, dan saya memiliki lebih banyak contoh yang akan muncul
yang akan membantu menjelaskan apa pointer sebenarnya.
>> Dalam hal ini, pointer setara dengan array,
jadi saya hanya bisa menggunakan pointer ini sebagai hal yang sama sebagai array int.
Jadi aku pengindeksan ke 0, dan mengubah integer pertama 1,
mengubah integer kedua 2, dan 3 untuk bilangan bulat 3.
Jadi lebih pada pointer. Nah, mengingat Binky.
Dalam hal ini kami telah dialokasikan pointer, atau kita menyatakan pointer,
tapi awalnya, ketika saya hanya menyatakan pointer, itu tidak menunjuk ke mana saja di memori.
Ini nilai sampah hanya di dalamnya.
Jadi saya tidak tahu di mana pointer ini menunjuk ke.
Ini memiliki alamat yang hanya diisi dengan 0 dan 1 yang mana itu awalnya diumumkan.
Saya tidak bisa melakukan apa-apa dengan ini sampai saya sebut malloc di atasnya
dan kemudian memberi saya sedikit ruang di tumpukan mana saya dapat menempatkan nilai-nilai di dalamnya.
Kemudian lagi, saya tidak tahu apa yang ada di dalam memori ini.
Jadi hal pertama yang saya lakukan adalah memeriksa apakah sistem tersebut memiliki cukup memori
untuk memberikan kembali 1 integer di tempat pertama, itulah sebabnya aku melakukan ini cek.
Jika pointer adalah null, yang berarti bahwa ia tidak memiliki cukup ruang atau beberapa error lain terjadi,
jadi saya harus keluar dari program saya.
Tapi jika hal itu berhasil, sekarang saya dapat menggunakan pointer yang
dan apa pointer * dilakukannya itu berikut di mana alamat adalah
ke mana nilai yang, dan set itu sama dengan 1.
Jadi di sini, kita memeriksa apakah memori yang ada.
>> Setelah Anda tahu itu ada, Anda dapat dimasukkan ke dalamnya
apa nilai yang Anda inginkan untuk dimasukkan ke dalamnya, dalam hal ini 1.
Setelah kita sudah selesai dengan hal itu, Anda perlu membebaskan bahwa pointer
karena kita harus kembali ke sistem yang memori yang Anda minta di tempat pertama.
Karena komputer tidak tahu kapan kita sudah selesai dengan itu.
Dalam kasus ini kita secara eksplisit mengatakan, oke, kita sudah selesai dengan memori itu.
Jika beberapa proses lain membutuhkannya, beberapa program lain membutuhkannya, merasa bebas untuk pergi ke depan dan mengambilnya.
Apa yang kita juga bisa lakukan adalah kita hanya bisa mendapatkan alamat dari variabel lokal di set.
Jadi x int adalah dalam bingkai ditumpuk utama.
Dan ketika kita menggunakan ampersand ini, ini dan operator, apa yang dilakukannya adalah
dibutuhkan x, dan x adalah hanya beberapa data dalam memori, tetapi memiliki alamat.
Itu terletak di suatu tempat. Jadi dengan menelepon & x, apa ini tidak akan memberikan kami alamat dari x.
Dengan melakukan hal ini, kami membuat titik pointer ke mana x adalah dalam memori.
Sekarang kita hanya sesuatu seperti * x, kita akan mendapatkan 5 kembali.
Bintang ini disebut dereferencing itu.
Anda mengikuti alamat dan Anda mendapatkan nilai itu disimpan di sana.
>> Ada pertanyaan? Ya?
[Siswa] Jika Anda tidak melakukan hal-3 runcing, apakah itu masih mengkompilasi?
Ya. Jika Anda tidak melakukan hal-3 pointer, itu masih akan mengkompilasi,
tapi aku akan menunjukkan kepada Anda apa yang terjadi dalam hitungan detik, dan tanpa melakukan itu,
itulah yang kita sebut kebocoran memori. Kau tidak memberikan sistem
kembali memori, sehingga setelah beberapa saat program ini akan menumpuk
memori bahwa itu tidak menggunakan, dan tidak ada lagi yang bisa menggunakannya.
Jika Anda pernah melihat Firefox dengan 1,5 juta kilobyte pada komputer Anda,
di task manager, itulah apa yang terjadi.
Anda memiliki kebocoran memori dalam program yang mereka tidak menangani.
Jadi bagaimana pointer bekerja aritmatika?
Nah, aritmatika pointer adalah semacam pengindeksan sejenisnya ke array.
Dalam hal ini, saya memiliki pointer, dan apa yang saya lakukan adalah saya membuat titik pointer ke elemen pertama
dari array 3 bilangan bulat bahwa saya telah dialokasikan.
Jadi sekarang apa yang saya lakukan, pointer bintang hanya mengubah elemen pertama dalam daftar.
Bintang pointer +1 poin di sini.
Jadi pointer adalah di sini, pointer +1 ada di sini, pointer +2 ada di sini.
>> Jadi hanya menambahkan 1 adalah hal yang sama seperti bergerak sepanjang array ini.
Apa yang kita lakukan adalah, ketika kita melakukan pointer +1 Anda mendapatkan alamat di sini,
dan dalam rangka untuk mendapatkan nilai di sini, Anda menempatkan sebuah bintang dalam dari seluruh ekspresi
untuk dereference itu.
Jadi, dalam hal ini, saya menetapkan lokasi pertama dalam array ini untuk 1,
kedua lokasi ke 2, dan lokasi ketiga 3.
Lalu apa yang saya lakukan di sini adalah aku mencetak pointer kami +1,
yang hanya memberi saya 2.
Sekarang aku incrementing pointer, sehingga pointer sama dengan pointer +1,
yang bergerak ke depan.
Dan jadi sekarang jika saya mencetak pointer +1, pointer +1 sekarang 3,
yang dalam hal ini mencetak keluar 3.
Dan untuk sesuatu yang gratis, pointer yang saya berikan
harus menunjuk pada awal dari array yang aku pulang dari malloc.
Jadi, dalam hal ini, jika saya menelepon 3 di sini, ini tidak akan benar,
karena itu di tengah-tengah array.
Saya harus mengurangi untuk sampai ke lokasi asli
tempat pertama awal sebelum saya bisa membebaskannya.
Jadi, inilah contoh yang lebih terlibat.
Dalam kasus ini, kita mengalokasikan 7 karakter dalam array karakter.
>> Dan dalam hal ini apa yang kita lakukan adalah kita perulangan selama 6 pertama mereka,
dan kami sedang menyiapkan mereka untuk Z.
Jadi, untuk int i = 0, i> 6, i + +,
Jadi, pointer + saya hanya akan memberi kita, dalam hal ini,
pointer, pointer +1, +2 pointer, pointer +3, dan seterusnya dan sebagainya dalam lingkaran.
Apa yang akan lakukan adalah mendapat alamat itu, dereferences untuk mendapatkan nilai,
dan perubahan yang nilai ke Z.
Kemudian pada akhirnya ingat ini adalah string, kan?
Semua string harus berakhir dengan karakter terminating null.
Jadi, apa yang saya lakukan adalah di pointer 6 Aku meletakkan karakter null terminator masuk
Dan sekarang apa yang saya lakukan di sini pada dasarnya adalah menerapkan printf untuk string, kan?
>> Jadi, kapan printf sekarang ketika itu mencapai akhir dari string?
Ketika hits karakter terminating null.
Jadi, dalam hal ini, poin pointer asli saya ke awal array ini.
Saya mencetak karakter pertama keluar. Aku bergerak lebih dari satu.
Saya mencetak karakter yang keluar. Saya memindahkannya di atas.
Dan saya terus melakukan hal ini sampai aku mencapai akhir.
Dan sekarang pointer * akhir akan dereference ini dan mendapatkan karakter terminating nol kembali.
Dan jadi loop sementara saya berjalan hanya jika nilai yang tidak mengakhiri karakter null.
Jadi, sekarang aku keluar dari lingkaran ini.
Dan jadi jika saya kurangi 6 dari pointer ini,
Saya kembali semua jalan ke awal.
Ingat, aku melakukan ini karena saya harus pergi ke awal untuk membebaskan itu.
>> Jadi, saya tahu itu banyak. Apakah ada pertanyaan?
Tolong, ya?
[Mahasiswa dapat dipahami pertanyaan]
Dapatkah Anda mengatakan bahwa keras? Maaf.
[Mahasiswa] Pada slide terakhir tepat sebelum Anda membebaskan pointer,
mana yang Anda benar-benar mengubah nilai pointer?
[Yusuf] Jadi, di sini. >> [Siswa] Oh, oke.
[Yusuf] Jadi, saya memiliki pointer dikurangi minus, tepat,
yang bergerak hal kembali satu, dan kemudian aku membebaskan itu,
karena pointer ini harus menunjuk ke awal array.
[Mahasiswa] Tapi itu tidak akan diperlukan telah Anda berhenti setelah baris itu.
[Yusuf] Jadi, jika saya telah berhenti setelah ini, ini akan dianggap sebagai kebocoran memori,
karena saya tidak menjalankan gratis.
[Mahasiswa] I [dipahami] setelah tiga baris pertama di mana Anda memiliki pointer +1 [dipahami].
[Joseph] Uh-huh. Jadi, apa ada pertanyaan?
Maaf. Tidak, tidak. Pergi, pergi, silakan.
[Mahasiswa] Jadi, Anda tidak mengubah nilai pointer.
Anda tidak akan harus melakukan pointer dikurangi minus.
[Yusuf] Ya, tepatnya.
Jadi, ketika saya melakukan pointer dan pointer +1 +2,
Aku tidak melakukan pointer sama dengan pointer +1.
Jadi, pointer hanya tetap menunjuk pada awal array.
Hanya ketika saya lakukan plus plus yang menetapkan nilai kembali ke dalam pointer,
bahwa itu benar-benar bergerak ini bersama.
Baiklah.
Lebih banyak pertanyaan?
>> Sekali lagi, jika ini adalah semacam luar biasa, hal ini akan dibahas dalam sesi.
Tanyakan rekan mengajar Anda tentang hal itu, dan kita dapat menjawab pertanyaan-pertanyaan di akhir.
Dan biasanya kita tidak ingin melakukan hal ini dikurangi.
Hal ini harus mengharuskan saya melacak betapa aku offset dalam array.
Jadi, secara umum, ini hanya untuk menjelaskan bagaimana karya pointer aritmatika.
Tapi apa yang biasanya kita ingin lakukan adalah kita ingin membuat salinan pointer,
dan kemudian kita akan menggunakan salinan bahwa ketika kita sedang bergerak di dalam string.
Jadi, dalam hal ini Anda menggunakan salin untuk mencetak seluruh string,
tapi kita tidak harus melakukan seperti pointer minus 6 atau melacak berapa banyak kita pindah dalam hal ini,
hanya karena kita tahu bahwa titik awal kita masih menunjuk ke awal daftar
dan semua yang kita diubah adalah salinan ini.
Jadi, secara umum, mengubah salinan pointer asli Anda.
Jangan mencoba untuk semacam seperti - jangan mengubah salinan asli.
Mencoba untuk mengubah salinan hanya asli Anda.
Jadi, Anda perhatikan ketika kami melewati string menjadi printf
Anda tidak harus meletakkan bintang di depannya seperti yang kami lakukan dengan semua dereferences lain, kan?
Jadi, jika Anda mencetak s seluruh string% mengharapkan adalah alamat,
dan dalam hal ini pointer atau dalam hal ini seperti sebuah array karakter.
>> Karakter, char * s, dan array adalah hal yang sama.
Pointer adalah karakter, dan karakter array adalah hal yang sama.
Dan sebagainya, yang harus kita lakukan adalah lulus dalam pointer.
Kami tidak harus melewati di seperti pointer * atau sesuatu seperti itu.
Jadi, array dan pointer adalah hal yang sama.
Ketika Anda melakukan sesuatu seperti x [y] di sini untuk array,
apa yang dilakukannya di bawah tenda adalah itu mengatakan, oke, itu adalah array karakter,
jadi pointer.
Dan sehingga x adalah hal yang sama,
dan jadi apa yang dilakukannya itu menambahkan y untuk x,
yang merupakan hal yang sama seperti bergerak maju dalam memori yang banyak.
Dan sekarang x + y memberi kita semacam alamat,
dan kami dereference alamat atau mengikuti panah
ke tempat yang lokasi di memori dan kami mendapatkan nilai keluar dari lokasi di memori.
Jadi, sehingga kedua adalah hal yang persis sama.
Ini hanya sintaksis gula.
Mereka melakukan hal yang sama. Mereka hanya Syntactics yang berbeda satu sama lain.
>> Jadi, apa yang bisa salah dengan pointer? Seperti, banyak. Oke. Jadi, hal-hal buruk.
Beberapa hal-hal buruk yang dapat Anda lakukan tidak memeriksa apakah panggilan malloc Anda mengembalikan null, kan?
Dalam kasus ini, saya minta sistem untuk memberikan - berapa nomor itu?
Seperti 2 miliar kali 4, karena ukuran integer adalah 4 byte.
Saya minta itu untuk seperti 8 miliar byte.
Tentu saja komputer saya tidak akan bisa memberikan itu kembali banyak memori.
Dan kami tidak memeriksa apakah ini adalah nol, sehingga ketika kita mencoba untuk dereference itu di sana -
ikuti panah ke mana itu akan - kita tidak memiliki memori itu.
Ini adalah apa yang kita sebut dereferencing pointer null.
Dan ini pada dasarnya menyebabkan Anda segfault.
Ini adalah salah satu cara Anda bisa segfault.
Hal-hal buruk lainnya yang dapat Anda lakukan - oh baik.
Itu dereferencing pointer null. Oke.
Hal-hal buruk lainnya - baik, untuk memperbaiki bahwa Anda hanya menempatkan cek di sana
yang memeriksa apakah pointer adalah null
dan keluar dari program jika terjadi malloc yang mengembalikan pointer null.
Itulah komik xkcd. Orang mengerti sekarang. Semacam.
>> Jadi, memori. Dan aku pergi selama ini.
Kami memanggil malloc dalam satu lingkaran, tapi setiap kali kita sebut malloc
kita kehilangan jejak di mana pointer ini menunjuk ke,
karena kita clobbering itu.
Jadi, panggilan awal untuk malloc memberi saya memori di sini.
Saya pointer pointer ini.
Sekarang, saya tidak membebaskannya, jadi sekarang saya sebut malloc lagi.
Sekarang ini menunjuk ke sini. Sekarang memori saya menunjuk di sini.
Menunjuk ke sini. Menunjuk ke sini.
Tapi aku sudah kehilangan jejak alamat dari semua memori di sini bahwa saya dialokasikan.
Dan jadi sekarang saya tidak punya referensi untuk mereka lagi.
Jadi, saya tidak bisa membebaskan mereka di luar lingkaran ini.
Dan sebagainya dalam rangka untuk memperbaiki sesuatu seperti ini,
jika Anda lupa untuk membebaskan memori dan Anda mendapatkan kebocoran memori,
Anda harus membebaskan memori dalam lingkaran ini setelah Anda selesai dengan itu.
Nah, inilah yang terjadi. Saya tahu banyak dari Anda benci ini.
Tapi sekarang - yay! Anda mendapatkan seperti 44.000 kilobyte.
Jadi, Anda bebas itu pada akhir loop,
dan itu akan hanya membebaskan memori setiap waktu.
Pada dasarnya, program anda tidak memiliki kebocoran memori lagi.
>> Dan sekarang hal lain yang dapat Anda lakukan adalah membebaskan beberapa memori yang telah Anda minta dua kali.
Dalam hal ini, sesuatu malloc, Anda mengubah nilainya.
Anda bebas sekali karena Anda mengatakan Anda selesai dengan itu.
Tapi kemudian kami dibebaskan lagi.
Ini adalah sesuatu yang sangat buruk.
Ini tidak akan awalnya segfault,
tapi setelah beberapa saat apa yang tidak membebaskan ganda ini merusak struktur tumpukan Anda,
dan Anda akan belajar sedikit lebih banyak tentang hal ini jika Anda memilih untuk mengambil kelas seperti CS61.
Tapi pada dasarnya setelah beberapa saat komputer Anda akan bingung
tentang apa lokasi memori yang mana dan di mana itu disimpan -
dimana data disimpan dalam memori.
Dan sehingga membebaskan pointer dua kali adalah hal yang buruk yang Anda tidak ingin lakukan.
>> Hal-hal lain yang bisa salah tidak menggunakan sizeof.
Jadi, dalam hal ini Anda malloc 8 byte,
dan itulah hal yang sama seperti dua bilangan bulat, kan?
Jadi, itu benar-benar aman, tetapi apakah itu?
Yah, seperti Lucas berbicara tentang pada arsitektur yang berbeda,
bilangan bulat dengan panjang yang berbeda.
Jadi, pada alat yang Anda gunakan, bilangan bulat sekitar 4 byte,
tapi pada beberapa sistem lain mereka mungkin 8 byte atau mereka mungkin 16 byte.
Jadi, jika saya hanya menggunakan nomor ini di sini,
program ini bisa bekerja pada alat,
tapi itu tidak akan mengalokasikan cukup memori pada beberapa sistem lain.
Dalam kasus ini, ini adalah apa operator sizeof digunakan untuk.
Ketika kita sebut sizeof (int), apa yang dilakukan adalah
memberikan kita ukuran integer pada sistem bahwa program ini berjalan.
Jadi, dalam hal ini, sizeof (int) akan kembali 4 pada sesuatu seperti alat,
dan sekarang ini kehendak 4 * 2, yaitu 8,
yang hanya jumlah ruang yang diperlukan untuk dua bilangan bulat.
Pada sistem yang berbeda, jika int seperti 16 byte atau 8 byte,
itu hanya akan kembali byte cukup untuk menyimpan jumlah tersebut.
>> Dan akhirnya, structs.
Jadi, jika Anda ingin menyimpan papan sudoku dalam memori, bagaimana mungkin kita melakukan ini?
Anda mungkin berpikir seperti variabel untuk hal pertama,
variabel untuk hal kedua, variabel untuk hal yang ketiga,
variabel untuk hal yang keempat - yang buruk, kan?
Jadi, salah satu perbaikan Anda dapat membuat di atas ini adalah untuk membuat 9 x 9 array.
Itu baik-baik saja, tetapi bagaimana jika Anda ingin mengaitkan hal-hal lain dengan papan sudoku
seperti apa kesulitan papan adalah,
atau, misalnya, berapa skor Anda, atau berapa banyak waktu itu diambil Anda untuk memecahkan forum ini?
Nah, apa yang dapat Anda lakukan adalah Anda dapat membuat sebuah struct.
Apa yang saya katakan adalah pada dasarnya aku mendefinisikan struktur ini di sini,
dan aku mendefinisikan papan sudoku yang terdiri dari papan yang 9 x 9.
>> Dan apa yang telah ia memiliki pointer ke nama tingkat.
Ia juga memiliki x dan y, yang merupakan koordinat keberadaan saya sekarang.
Ini juga memiliki waktu yang dihabiskan [dimengerti], dan memiliki jumlah total bergerak saya sudah diinput sejauh ini.
Dan sehingga dalam kasus ini, saya dapat mengelompokkan sejumlah besar data ke dalam satu struktur
daripada harus seperti terbang di sekitar seperti variabel yang berbeda
bahwa saya tidak bisa benar-benar melacak.
Dan ini memungkinkan kita hanya memiliki sintaks bagus untuk semacam referensi hal yang berbeda dalam struct ini.
Saya hanya bisa melakukan board.board, dan saya mendapatkan papan sudoku kembali.
Board.level, saya mendapatkan betapa sulitnya itu.
Board.x dan board.y memberikan koordinat di mana aku bisa berada di papan.
Dan jadi aku mengakses apa yang kita sebut bidang dalam struct.
Ini mendefinisikan sudokuBoard, yang merupakan jenis yang saya miliki.
Dan sekarang kita di sini. Saya memiliki sebuah variabel yang disebut "papan" dari sudokuBoard jenis.
Dan jadi sekarang saya dapat mengakses semua bidang yang membentuk struktur ini di sini.
>> Setiap pertanyaan tentang struct? Ya?
[Mahasiswa] Untuk int x, y, Anda menyatakan baik pada satu baris? >> [Joseph] Uh-huh.
[Mahasiswa] Jadi, bisa Anda hanya melakukan itu dengan mereka semua?
Seperti di x, y kali koma yang total?
[Yusuf] Ya, Anda pasti bisa melakukan itu, tetapi alasan saya menempatkan x dan y pada baris yang sama -
dan pertanyaannya adalah mengapa kita hanya melakukan ini pada baris yang sama?
Mengapa kita tidak hanya menempatkan semua pada baris yang sama adalah
x dan y yang terkait satu sama lain,
dan ini hanya Gaya lebih benar, dalam arti,
karena itu pengelompokan dua hal pada baris yang sama
semacam seperti dari berhubungan dengan hal yang sama.
Dan saya hanya membagi ini terpisah. Ini hanya hal gaya.
Ini fungsional ada bedanya sama sekali.
Ada pertanyaan lain pada structs?
Anda dapat mendefinisikan Pokédex dengan struct.
Sebuah Pokémon memiliki nomor dan memiliki surat, pemilik, tipe.
Dan kemudian jika Anda memiliki sebuah array Pokémon, Anda dapat membuat Pokédex, kan?
Oke, dingin. Jadi, pertanyaan tentang struct. Mereka adalah terkait dengan struct.
>> Akhirnya, GDB. Apa GDB membiarkan Anda lakukan? Ini memungkinkan Anda men-debug program Anda.
Dan jika Anda belum pernah menggunakan GDB, saya akan merekomendasikan menonton singkat
dan hanya akan atas apa GDB adalah, bagaimana Anda bekerja dengan itu, bagaimana Anda dapat menggunakannya,
dan mengujinya pada sebuah program.
Dan jadi apa GDB memungkinkan Anda lakukan adalah itu memungkinkan jeda [dimengerti] up program Anda
dan garis praktis.
Sebagai contoh, saya ingin eksekusi jeda di seperti baris 3 dari program saya,
dan sementara aku di baris 3 saya bisa mencetak semua nilai-nilai yang ada.
Dan jadi apa yang kita sebut seperti berhenti di baris
yang kita sebut ini menempatkan breakpoint pada baris yang
dan kemudian kita bisa mencetak variabel pada keadaan program pada waktu itu.
>> Kita kemudian dapat dari sana langkah melalui program baris demi baris.
Dan kemudian kita dapat melihat keadaan stack pada saat itu.
Dan agar dapat menggunakan GDB, apa yang kita lakukan adalah kita sebut dentang pada file C,
tapi kita harus lulus bendera ggdb-.
Dan setelah kami selesai dengan itu kita hanya menjalankan gdb pada file output yang dihasilkan.
Dan sehingga Anda mendapatkan beberapa massa seperti teks seperti ini,
tapi benar-benar harus Anda lakukan adalah mengetikkan perintah di awal.
Istirahat utama menempatkan breakpoint di utama.
Daftar 400 daftar baris kode sekitar baris 400.
Dan sehingga dalam hal ini Anda hanya dapat melihat-lihat dan berkata, oh,
Saya ingin mengatur breakpoint pada baris 397, yang merupakan baris ini,
dan kemudian program anda berjalan ke langkah itu dan itu akan pecah.
Ini akan berhenti di sana, dan Anda dapat mencetak, misalnya, nilai rendah atau tinggi.
Dan jadi ada sekelompok perintah yang perlu Anda ketahui,
dan slideshow ini akan naik pada website,
jadi jika Anda hanya ingin referensi ini atau seperti menempatkan mereka pada lembar Anda curang, merasa bebas.
>> Cool. Itu Kuis Ulasan 0, dan kami akan tetap sekitar jika Anda memiliki pertanyaan.
Baiklah.
>> [Tepuk tangan]
>> [CS50.TV]