1 00:00:00,000 --> 00:00:02,730 [Powered by Google Translate] [РАЗДЕЛ 5: по-малко удобни] 2 00:00:02,730 --> 00:00:05,180 [Нейт Hardison, Харвардски университет] 3 00:00:05,180 --> 00:00:08,260 [Това е CS50. [CS50.TV] 4 00:00:08,260 --> 00:00:11,690 Така че добре дошли обратно, момчета. 5 00:00:11,690 --> 00:00:16,320 Добре дошли в раздел 5. 6 00:00:16,320 --> 00:00:20,220 В този момент, след като викторина 0 и след като види как сте направили, 7 00:00:20,220 --> 00:00:25,770 се надяваме, че се чувствам наистина добре, защото бях много впечатлен от резултатите в този раздел. 8 00:00:25,770 --> 00:00:28,050 За нашите онлайн зрителите, имахме няколко въпроса 9 00:00:28,050 --> 00:00:33,680 за последните два проблема по проблема, или на теста, а. 10 00:00:33,680 --> 00:00:39,690 Така че ние ще отидем над тези, които наистина бързо, така че всеки вижда какво се е случило 11 00:00:39,690 --> 00:00:45,060 и как да мине през реалното решение, а не само за гледане самото решение. 12 00:00:45,060 --> 00:00:50,330 Ние ще отидем много бързо през последните няколко проблеми, 32 и 33. 13 00:00:50,330 --> 00:00:53,240 Просто отново, така че онлайн зрителите могат да видят това. 14 00:00:53,240 --> 00:00:59,080 >> Ако се обърнете към вашия проблем 32, който е на страница 13, 15 00:00:59,080 --> 00:01:02,730 13 от 16 проблеми 32 е всичко за суапове. 16 00:01:02,730 --> 00:01:05,010 Това беше всичко, за смяна на две цели числа. 17 00:01:05,010 --> 00:01:08,740 Това е проблем, който си отиде няколко пъти в лекция. 18 00:01:08,740 --> 00:01:13,590 И тук, това, което искаха да направиш е бърз следа памет. 19 00:01:13,590 --> 00:01:17,000 За попълване на стойностите на променливите, тъй като те са в стека 20 00:01:17,000 --> 00:01:20,250 кода минава през този суап функция. 21 00:01:20,250 --> 00:01:24,500 По-конкретно, това, което ние търсим най - Тръгвам този IPAD - 22 00:01:24,500 --> 00:01:29,650 по-специално това, което търсим, е тази линия с номер 6 тук. 23 00:01:29,650 --> 00:01:36,740 И тя наброява 6 само за непосредствена близост с предишния проблем. 24 00:01:36,740 --> 00:01:41,720 Това, което искаме да направим, е да покажете или етикет на състоянието на паметта 25 00:01:41,720 --> 00:01:46,090 тъй като тя е по времето, когато тази линия номер 6, 26 00:01:46,090 --> 00:01:52,540 , което е ефективно връщане от нашия суап функция тук. 27 00:01:52,540 --> 00:01:59,450 Ако превъртете надолу тук видяхме, че адресите на всичко в паметта е предоставена за нас. 28 00:01:59,450 --> 00:02:02,540 Това е много ключов, ние ще се върнем към него само за миг. 29 00:02:02,540 --> 00:02:09,240 И тогава тук в долната част, имахме малко диаграма памет, че отива да се позове на. 30 00:02:09,240 --> 00:02:12,490 Всъщност съм направил това на моя IPAD. 31 00:02:12,490 --> 00:02:20,720 Така че аз отивам да се редуват назад и напред между IPAD и този код само за справка. 32 00:02:20,720 --> 00:02:26,540 >> Нека започнем. Първо, нека се съсредоточим върху първите няколко линии на главната точно тук. 33 00:02:26,540 --> 00:02:30,220 За да започнете, отиваме да се инициализира х 1 и у две. 34 00:02:30,220 --> 00:02:33,040 Така че ние имаме два целочислени променливи, те двамата ще бъдат поставени в стека. 35 00:02:33,040 --> 00:02:36,050 Отиваме да се сложи 1 и 2 в тях. 36 00:02:36,050 --> 00:02:43,150 Така че, ако преобърне на моя IPAD, да се надяваме, да видим - 37 00:02:43,150 --> 00:02:48,660 Apple TV огледало, и там да отидем. Добре. 38 00:02:48,660 --> 00:02:51,670 Така че, ако преобърне на моя IPAD 39 00:02:51,670 --> 00:02:56,220 Искам да се инициализира х 1 и у две. 40 00:02:56,220 --> 00:03:00,580 Ние правим, че просто от написването на едно в полето отбелязани х 41 00:03:00,580 --> 00:03:07,730 и 2 в полето маркирани г. Доста проста. 42 00:03:07,730 --> 00:03:11,620 Така че сега, нека се върнем към лаптопа, да видим какво се случва по-нататък. 43 00:03:11,620 --> 00:03:15,810 Така че това следващия ред е мястото, където нещата стават трудни. 44 00:03:15,810 --> 00:03:28,110 Преминаваме адрес на х и адрес на у параметрите А и Б за суап функция. 45 00:03:28,110 --> 00:03:32,380 Адресът на х и адрес на г са неща, които не може да се изчисли 46 00:03:32,380 --> 00:03:36,360 без да се позовава на тези куршум точки чак тук. 47 00:03:36,360 --> 00:03:39,750 И за щастие, първите две точки ни каже какво точно отговорите са. 48 00:03:39,750 --> 00:03:44,740 Адрес на х памет е 10 и адреса на г. в паметта е 14. 49 00:03:44,740 --> 00:03:51,870 Така че това са ценностите, които се предават като А и Б отгоре в нашата суап функция. 50 00:03:51,870 --> 00:04:00,760 Така че, отново превключване в нашата диаграма, мога да пиша на 10 в 51 00:04:00,760 --> 00:04:07,400 и 14 в б. 52 00:04:07,400 --> 00:04:11,610 Сега, тази точка е мястото, където да продължим с суапа. 53 00:04:11,610 --> 00:04:14,520 Така обръщане на лаптопа отново 54 00:04:14,520 --> 00:04:21,079 ние виждаме, че начина, по който суап работи е, че първият сочен и магазин резултата в ПТУ. 55 00:04:21,079 --> 00:04:27,650 Така сочен оператор казва, "Хей. Лечение на съдържанието на променлива на адрес. 56 00:04:27,650 --> 00:04:33,830 Отиди на каквото и да се съхранява на този адрес и да го заредите. 57 00:04:33,830 --> 00:04:41,720 Какво ви зареди на променливата ще се съхраняват в нашия TMP променлива. 58 00:04:41,720 --> 00:04:45,150 Показваш на IPAD. 59 00:04:45,150 --> 00:04:51,690 Ако тръгнем на адрес 10, знаем, че адрес 10 е varible х 60 00:04:51,690 --> 00:04:55,480 защото ни беше казано от нашия точка, че на адреса на х памет е 10. 61 00:04:55,480 --> 00:05:00,180 Така че можем да отидем там, да получите стойността на това, което е 1, както виждаме на нашия IPAD, 62 00:05:00,180 --> 00:05:06,300 и да заредите, че в малки. 63 00:05:06,300 --> 00:05:08,250 Отново, това не е окончателното съдържание. 64 00:05:08,250 --> 00:05:14,350 Отиваме да преминете през и ние ще стигнем до крайната ни състоянието на програмата в края. 65 00:05:14,350 --> 00:05:17,210 Но точно сега, ние имаме стойност 1 съхраняват в малки. 66 00:05:17,210 --> 00:05:19,210 >> И тук има един бърз въпрос. 67 00:05:19,210 --> 00:05:23,980 [Александър] е сочен оператор - това е само право на звездата в предната част на променливата? 68 00:05:23,980 --> 00:05:27,600 >> Да. Така сочен оператор, като се обърнете назад към нашия лаптоп отново, 69 00:05:27,600 --> 00:05:33,780 е тази звезда точно пред. 70 00:05:33,780 --> 00:05:37,460 В този смисъл, това е - да го съпоставят с оператора за умножение 71 00:05:37,460 --> 00:05:42,400 , който изисква две неща, сочен оператор е унарен оператор. 72 00:05:42,400 --> 00:05:46,130 Само една стойност, за разлика от двоичен оператор, 73 00:05:46,130 --> 00:05:48,810 , където се прилагат за две различни стойности. 74 00:05:48,810 --> 00:05:52,080 Така че това е това, което се случва в този ред. 75 00:05:52,080 --> 00:05:58,390 Натоварени стойност 1 и да го съхраняват временно целочислена променлива. 76 00:05:58,390 --> 00:06:05,800 Следващият ред, ние съхраняваме съдържанието на б 77 00:06:05,800 --> 00:06:12,630 или по-скоро, ние съхраняваме съдържанието, б сочи в мястото, където е насочена към. 78 00:06:12,630 --> 00:06:17,690 Ако анализираме това от дясно на ляво, ние ще сочен б, 79 00:06:17,690 --> 00:06:23,580 ние ще Адрес 14, ние ще грабне цяло число, което е там, 80 00:06:23,580 --> 00:06:26,900 и тогава ние ще отидем на адреса, 10, 81 00:06:26,900 --> 00:06:34,240 и ние ще се хвърлят в резултат на на сочен нашата б в това пространство. 82 00:06:34,240 --> 00:06:40,080 Показваш IPAD, където можем да направим това малко по-конкретни, 83 00:06:40,080 --> 00:06:44,070 може да помогне, ако пиша номера на всички адреси тук. 84 00:06:44,070 --> 00:06:53,820 Така че ние знаем, че в г., ние сме на адрес 14, х е на адрес 10. 85 00:06:53,820 --> 00:07:00,180 Когато почнем да б, сочен б, ние отиваме да вземете стойността 2. 86 00:07:00,180 --> 00:07:08,320 Ние ще вземете тази стойност, тъй като това е стойността, която живее на адрес 14. 87 00:07:08,320 --> 00:07:15,700 И отиваме да го пуснат в променлива, която живее на адрес 10, 88 00:07:15,700 --> 00:07:19,160 което е точно там, съответстваща на нашите променливи х. 89 00:07:19,160 --> 00:07:21,810 Така че ние можем да направим малко от презаписване тук 90 00:07:21,810 --> 00:07:35,380 , където ще се отървем на нашия 1 и вместо да пишем 2. 91 00:07:35,380 --> 00:07:39,560 Така че всичко е много добре в света, въпреки че сега сме презаписани х. 92 00:07:39,560 --> 00:07:44,890 Ние сме съхранили старата стойност на х в нашия TMP променлива. 93 00:07:44,890 --> 00:07:50,210 Така че можем да завърши суап със следващия ред. 94 00:07:50,210 --> 00:07:53,030 Показваш обратно на нашия лаптоп. 95 00:07:53,030 --> 00:07:58,150 Сега всичко, което остава е да се вземе съдържанието на временно целочислена променлива 96 00:07:58,150 --> 00:08:05,630 и да ги съхранява в променлива, която живее на адреса, на който б държи. 97 00:08:05,630 --> 00:08:10,230 Така че ние отиваме за ефективно и сочен б, за да получите достъп до променливата 98 00:08:10,230 --> 00:08:14,340 , който е на адреса, че б държи в него, 99 00:08:14,340 --> 00:08:19,190 и отиваме да се неща стойността, която TMP държи в него. 100 00:08:19,190 --> 00:08:23,280 Показваш на IPAD още веднъж. 101 00:08:23,280 --> 00:08:31,290 Тук мога да изтриете тази стойност, 2, 102 00:08:31,290 --> 00:08:41,010 и вместо това ще копираме 1 право в него. 103 00:08:41,010 --> 00:08:43,059 След това на следващия ред, който изпълнява, разбира се - 104 00:08:43,059 --> 00:08:47,150 ако се обърнете назад към лаптопа - това е точка 6, 105 00:08:47,150 --> 00:08:52,500 което е точката, в която искахме да имаме нашата диаграма напълно попълнени. 106 00:08:52,500 --> 00:08:58,940 Така обръщане на IPAD още веднъж, само за да можете да видите диаграма, 107 00:08:58,940 --> 00:09:06,610 можете да видите, че ние имаме 10 в 14 б, 1 в ПТУ, 2 х и 1 г.. 108 00:09:06,610 --> 00:09:11,000 Има ли някакви въпроси относно това? 109 00:09:11,000 --> 00:09:14,640 Това прави ли повече смисъл, след като мина през него? 110 00:09:14,640 --> 00:09:24,850 Направете по-малко смисъл? Надявам се не. Добре. 111 00:09:24,850 --> 00:09:28,230 >> Указатели са много труден въпрос. 112 00:09:28,230 --> 00:09:33,420 Едно от момчетата, с които работим, има много чести поговорка: 113 00:09:33,420 --> 00:09:36,590 "За да се разбере указатели, трябва да първо да разберем указатели." 114 00:09:36,590 --> 00:09:40,530 Което мисля, че е много вярно. Тя не отнеме известно време да свикне с него. 115 00:09:40,530 --> 00:09:45,360 Тегленето на жребий снимки, теглене на жребий памет схеми като тази са много полезни, 116 00:09:45,360 --> 00:09:49,480 и след като преминете през пример след пример след пример, 117 00:09:49,480 --> 00:09:54,450 , че ще започнат да правят малко повече разум и малко повече разум и малко повече смисъл. 118 00:09:54,450 --> 00:10:01,560 Накрая, един ден, ще имате всичко напълно усвоили. 119 00:10:01,560 --> 00:10:13,800 Всички въпроси, преди да преминем към следващия проблем? Добре. 120 00:10:13,800 --> 00:10:18,840 Така че обърнете гръб на лаптопа. 121 00:10:18,840 --> 00:10:23,300 Следващият проблем, който имаме, е проблем номер 33 на файл I / O. 122 00:10:23,300 --> 00:10:26,350 Увеличаване или намаляване на това малко. 123 00:10:26,350 --> 00:10:28,710 Задача 33 - Да? 124 00:10:28,710 --> 00:10:32,110 >> Даниел аз просто трябваше един бърз въпрос. Тази звезда, или звездичка, 125 00:10:32,110 --> 00:10:35,590 тя се нарича dereferencing когато използвате звездичка преди. 126 00:10:35,590 --> 00:10:38,820 Как се нарича, когато използвате амперсанд преди? 127 00:10:38,820 --> 00:10:43,140 >> Амперсанд преди е адресът на оператора. 128 00:10:43,140 --> 00:10:45,880 Така че нека да превъртите обратно. 129 00:10:45,880 --> 00:10:49,310 Опа. Аз съм в режим на увеличение, така че не мога наистина превъртане. 130 00:10:49,310 --> 00:10:52,780 Ако се вгледаме в този код наистина бързо тук, 131 00:10:52,780 --> 00:10:54,980 отново същото нещо се случва. 132 00:10:54,980 --> 00:10:59,180 Ако се вгледаме в този код точно тук, на тази линия, където можем да призоваваме за суап, 133 00:10:59,180 --> 00:11:10,460 амперсанд е просто казва "да получите адреса, на който живее променливата х." 134 00:11:10,460 --> 00:11:14,460 Компилатор компилира кода си, 135 00:11:14,460 --> 00:11:20,590 има действително физически марка място в паметта за всички променливи, които да живеят. 136 00:11:20,590 --> 00:11:24,910 И така, какво компилаторът може след това, след като всичко е съставен, 137 00:11:24,910 --> 00:11:31,110 го знае, "О, аз слагам х адрес 10. Сложих г. на адрес 14. 138 00:11:31,110 --> 00:11:34,640 След това тя може да запълни тези ценности за вас. 139 00:11:34,640 --> 00:11:44,740 Така че може да - може да мине и преминават г., както и. 140 00:11:44,740 --> 00:11:50,730 Тези момчета са с адрес, но те, когато ги предадат в суап функция, 141 00:11:50,730 --> 00:11:55,690 този тип информация, това INT * точно тук, казва на компилатора, 142 00:11:55,690 --> 00:12:01,350 "Добре, ние отиваме да бъде тълкуването на този адрес като адрес на целочислена променлива. 143 00:12:01,350 --> 00:12:05,900 Като адрес на вътр, който е различен от адреса на променливата характер 144 00:12:05,900 --> 00:12:09,930 защото вътр заема, на 32-битова машина, заема 4 байта пространство, 145 00:12:09,930 --> 00:12:13,310 като има предвид, че символ заема само 1 байт на пространството. 146 00:12:13,310 --> 00:12:17,310 Така че е важно да се знае и това, което е - какво живее, какъв тип на стойност 147 00:12:17,310 --> 00:12:20,340 живее на адреса, на който се премина инча 148 00:12:20,340 --> 00:12:22,020 Или адрес, че си имате работа с. 149 00:12:22,020 --> 00:12:29,020 По този начин, вие знаете колко байта на информация действително да се зареди на вашия RAM. 150 00:12:29,020 --> 00:12:31,780 И тогава, да, този сочен оператор, като теб искаха, 151 00:12:31,780 --> 00:12:37,200 отива и достъп до информация по конкретен адрес. 152 00:12:37,200 --> 00:12:42,820 Така се казва, с тази променлива, лечение на съдържанието на като адрес, 153 00:12:42,820 --> 00:12:47,880 отидете на този адрес, и издърпайте, заредете в процесора, натоварване в регистър 154 00:12:47,880 --> 00:12:56,340 действителните стойности или съдържанието, които живеят на този адрес. 155 00:12:56,340 --> 00:12:59,620 Има ли още въпроси? Това са добри въпроси. 156 00:12:59,620 --> 00:13:01,650 Това е много нова терминология. 157 00:13:01,650 --> 00:13:09,800 То също е вид фънки, тъй като и и * на различни места. 158 00:13:09,800 --> 00:13:13,180 >> Добре. 159 00:13:13,180 --> 00:13:18,530 Така че обратно към проблем 33, подайте I / O. 160 00:13:18,530 --> 00:13:22,540 Това е един от тези проблеми, които мисля, че няколко неща се случиха. 161 00:13:22,540 --> 00:13:25,400 Едно, че е сравнително нова тема. 162 00:13:25,400 --> 00:13:30,590 Той беше представен съвсем скоро преди теста, 163 00:13:30,590 --> 00:13:33,400 и след това мисля, че беше нещо като един от проблемите с тези думи по математика 164 00:13:33,400 --> 00:13:39,720 , където те дават много информация, но всъщност не в крайна сметка се налага да използвате един тон от него. 165 00:13:39,720 --> 00:13:44,060 В първата част на този проблем се описва какво CSV файл. 166 00:13:44,060 --> 00:13:50,620 Сега, CSV файл, според описанието, е, разделени със запетая стойности. 167 00:13:50,620 --> 00:13:55,300 Причината това са всички интересни и причината, поради която някога ги използват, 168 00:13:55,300 --> 00:14:00,800 , защото, колко от вас са използвали някога подобни неща Excel? 169 00:14:00,800 --> 00:14:03,240 Фигура повечето от вас, вероятно, или ще се използва в някакъв момент в живота си. 170 00:14:03,240 --> 00:14:06,430 Ще използвате нещо като Excel. 171 00:14:06,430 --> 00:14:10,940 За да получите данните от таблица в Excel или да направите каквато и да е обработка с него, 172 00:14:10,940 --> 00:14:17,240 ако искаш да се напише програма на C или Python програма, Java програма, 173 00:14:17,240 --> 00:14:20,070 да се справят с данни, които сте там, 174 00:14:20,070 --> 00:14:23,170 един от най-често срещаните начини, за да я получите, е в CSV файл. 175 00:14:23,170 --> 00:14:26,850 И можете да отворите Excel и когато отидете на "Save As" диалог, 176 00:14:26,850 --> 00:14:32,840 можете да получите действително CSV файл. 177 00:14:32,840 --> 00:14:35,890 >> Добре е да се знае как да се справят с тези неща. 178 00:14:35,890 --> 00:14:42,010 Начина, по който тя работи, е, че това е подобно на - Искам да кажа, това е по същество имитира електронна таблица, 179 00:14:42,010 --> 00:14:47,590 където, както виждаме тук, в най-лявата част, 180 00:14:47,590 --> 00:14:49,910 имаме всички фамилни имена. 181 00:14:49,910 --> 00:14:54,670 Така че ние имаме Малан, тогава Hardison, и след това Боудън, MacWilliam, и след това Чан. 182 00:14:54,670 --> 00:14:59,470 Всички фамилни имена. И тогава запетая разделя последните имена от първите имена. 183 00:14:59,470 --> 00:15:02,970 Дейвид, Нейт, Роб, Томи и Zamyla. 184 00:15:02,970 --> 00:15:06,850 Винаги съм се смесват Роби и Том. 185 00:15:06,850 --> 00:15:10,940 И най-накрая, третата колона е имейл адресите. 186 00:15:10,940 --> 00:15:18,500 След като разбират, че останалата част от програмата е сравнително лесно за изпълнение. 187 00:15:18,500 --> 00:15:23,850 Това, което ние сме направили, за да се имитира същата тази структура в нашата програма C 188 00:15:23,850 --> 00:15:27,510 е, че ние сме използвали структура. 189 00:15:27,510 --> 00:15:30,520 Ще започнете да играете с тези малко повече, както добре. 190 00:15:30,520 --> 00:15:35,790 Ние ги видях за първи малко проблем комплект 3, когато ние се занимавахме с речниците. 191 00:15:35,790 --> 00:15:40,290 Но този персонал структура съхранява фамилно име, собствено име и имейл. 192 00:15:40,290 --> 00:15:44,500 Точно като CSV файла съхранение. 193 00:15:44,500 --> 00:15:47,950 Така че това е просто конвертиране от един формат в друг. 194 00:15:47,950 --> 00:15:54,630 Трябва да конвертирате, в този случай, структурата на персонала в една линия, 195 00:15:54,630 --> 00:15:59,060 , разделени със запетая линия, просто ей така. 196 00:15:59,060 --> 00:16:01,500 Това прави ли смисъл? Вие, момчета, всички викторина, 197 00:16:01,500 --> 00:16:07,680 така че представете си, че са най-малко трябваше известно време да мисля за това. 198 00:16:07,680 --> 00:16:16,410 >> В наем функция, проблемът ни кара да се вземат в we'll увеличение на това малко - 199 00:16:16,410 --> 00:16:22,480 в структурата на персонала, структурата на персонала, с името и, 200 00:16:22,480 --> 00:16:30,900 и прилага съдържанието му в нашия файл staff.csv. 201 00:16:30,900 --> 00:16:34,230 Оказва се, че това е сравнително лесно за използване. 202 00:16:34,230 --> 00:16:37,430 Ще играят наоколо с тези функции малко повече днес. 203 00:16:37,430 --> 00:16:44,510 Но в този случай, fprintf функция е наистина ключов. 204 00:16:44,510 --> 00:16:51,960 Така че с fprintf, ние може да печата, точно като вас са използвали ФОРМАТ целия този план. 205 00:16:51,960 --> 00:16:55,050 Можете да ФОРМАТ линия във файл. 206 00:16:55,050 --> 00:16:59,030 Така че, вместо просто обичайната ФОРМАТ повикване, когато ти я дам низ формат 207 00:16:59,030 --> 00:17:05,380 и тогава ще замени всички променливи със следните аргументи, 208 00:17:05,380 --> 00:17:11,290 с fprintf си първият аргумент е, вместо файла, който искате да напишете. 209 00:17:11,290 --> 00:17:21,170 Ако бяхме да гледам на това в уреда, например, човек fprintf 210 00:17:21,170 --> 00:17:25,980 можем да видим разликата между ФОРМАТ и fprintf. 211 00:17:25,980 --> 00:17:28,960 Ще я увеличите тук малко. 212 00:17:28,960 --> 00:17:33,140 ФОРМАТ, ние го дам формат низ, а след това следващите аргументи 213 00:17:33,140 --> 00:17:37,580 са всички променливи за замяна или за замяна в нашия формат низ. 214 00:17:37,580 --> 00:17:47,310 Като има предвид, че с fprintf, първият аргумент е наистина този файл * нарича поток. 215 00:17:47,310 --> 00:17:51,800 >> Преместване тук, за да ни под наем, 216 00:17:51,800 --> 00:17:54,550 Вече си имаме нашия поток файл * отвори за нас. 217 00:17:54,550 --> 00:17:57,810 Това е, което прави тази първа линия; го отваря файла staff.csv, 218 00:17:57,810 --> 00:18:01,690 тя се отваря в режим за добавяне и всичко, което е останало от нас да направим, е 219 00:18:01,690 --> 00:18:08,640 напиши структурата на персонала към файла. 220 00:18:08,640 --> 00:18:10,870 И нека да видим, не искам да използвате IPAD? 221 00:18:10,870 --> 00:18:17,900 Ще използвам IPAD. Имаме невалидни - Нека сложим на масата, така че мога да напиша малко по-добре - 222 00:18:17,900 --> 00:18:33,680 анулира под наем и го отвежда в един аргумент, на персонала, структура, наречена S. 223 00:18:33,680 --> 00:18:44,120 Имаме скоби, ние имаме файла * файл, наречен, 224 00:18:44,120 --> 00:18:48,380 ние имаме fopen линия, дадена ни, 225 00:18:48,380 --> 00:18:51,890 и аз просто ще го напиша като точки, тъй като това е вече в Родословие. 226 00:18:51,890 --> 00:19:00,530 И след това на следващия ни ред, ние отиваме да осъществите повикване до fprintf 227 00:19:00,530 --> 00:19:03,700 и отиваме да премине в преписката, че искаме да печатате, 228 00:19:03,700 --> 00:19:10,290 и след това формат низ, който 229 00:19:10,290 --> 00:19:14,300 Ще ви оставя вие да ми кажете това, което изглежда. 230 00:19:14,300 --> 00:19:20,500 Какво ще кажете вие, Стела? Знаете ли, това, което прилича на първата част на формат низ? 231 00:19:20,500 --> 00:19:24,270 Стела] Аз не съм сигурен. >> Чувствайте се свободни да поиска Джими. 232 00:19:24,270 --> 00:19:27,690 Знаеш ли, Джими? 233 00:19:27,690 --> 00:19:31,000 [Джими би той просто да бъде последно? Не знам. Аз не съм съвсем сигурен. 234 00:19:31,000 --> 00:19:39,020 >> Добре. Какво ще кажете, че някой се това е правилно на изпита? 235 00:19:39,020 --> 00:19:41,770 Добре. 236 00:19:41,770 --> 00:19:47,920 Оказва се, че тук всичко, което трябва да направим, е да искаме всяка част от структурата на нашия екип 237 00:19:47,920 --> 00:19:53,290 да бъдат отпечатани като низ в нашия файл. 238 00:19:53,290 --> 00:19:59,900 Ние просто използвайте характер замяна на низ три пъти, защото имаме фамилно име 239 00:19:59,900 --> 00:20:07,160 последвано от запетая, а след това първо име, последвано от запетая, 240 00:20:07,160 --> 00:20:12,430 и накрая имейл адрес, който е последван - което не е 241 00:20:12,430 --> 00:20:15,140 монтиране на екрана си, но е последван от символ за нов ред. 242 00:20:15,140 --> 00:20:20,060 Така че аз ще го напиша малко по-надолу има. 243 00:20:20,060 --> 00:20:23,560 И тогава след нашия формат низ, 244 00:20:23,560 --> 00:20:27,880 ние просто трябва да смени, които достъп се използва отбелязването точка 245 00:20:27,880 --> 00:20:31,370 че видяхме в проблем комплект 3. 246 00:20:31,370 --> 00:20:48,820 Ние можем да използваме s.last, s.first и s.email 247 00:20:48,820 --> 00:20:58,990 да замени в тези три стойности в нашата формат низ. 248 00:20:58,990 --> 00:21:06,190 Е, как е, че отиде? Направи ли смисъл? 249 00:21:06,190 --> 00:21:09,700 Да? Не? Евентуално? Добре. 250 00:21:09,700 --> 00:21:14,180 >> Крайният нещо, което правим след като сме се отпечатват и след като сме отворили нашия файл: 251 00:21:14,180 --> 00:21:17,370 всеки път, когато сте отворили файл, ние винаги трябва да помним, за да го затворите. 252 00:21:17,370 --> 00:21:19,430 Защото в противен случай ние ще свършим изтичане на паметта, 253 00:21:19,430 --> 00:21:22,500 използване на файлови дескриптори. 254 00:21:22,500 --> 00:21:25,950 Така че, за да го затворите, чиято функция ще се използва? Даниел? 255 00:21:25,950 --> 00:21:30,120 Даниел] неуспешно? >> Неуспешно, точно така. 256 00:21:30,120 --> 00:21:37,520 Така последната част от този проблем е правилно затворете файла, с помощта на функцията неуспешно, 257 00:21:37,520 --> 00:21:40,370 което просто изглежда по този начин. 258 00:21:40,370 --> 00:21:43,880 Не е твърде луд. 259 00:21:43,880 --> 00:21:46,990 Cool. 260 00:21:46,990 --> 00:21:49,520 Така че това е проблем на 33 на теста. 261 00:21:49,520 --> 00:21:52,480 Ще има определено повече файла I / O идва. 262 00:21:52,480 --> 00:21:55,130 Ние ще направим малко повече в лекция днес, или в раздел днес, 263 00:21:55,130 --> 00:22:01,710 защото това е какво ще се формират по-голямата част от този предстоящ pset. 264 00:22:01,710 --> 00:22:05,020 Нека преминем от теста в този момент. Да? 265 00:22:05,020 --> 00:22:10,880 >> [Шарлот] Защо неуспешно (файл), вместо неуспешно (staff.csv)? 266 00:22:10,880 --> 00:22:19,100 >> Ah. Защото се оказва, че - така че въпросът, който е страхотно, 267 00:22:19,100 --> 00:22:27,800 Ето защо, когато пишем неуспешно, ще писмено неуспешно (файл) звезда променлива 268 00:22:27,800 --> 00:22:33,680 за разлика от името на файла, staff.csv? Вярно ли е? Да. 269 00:22:33,680 --> 00:22:39,570 Така че нека да разгледаме. Ако се върнете обратно към лаптопа си, 270 00:22:39,570 --> 00:22:45,040 и нека погледнем неуспешно функция. 271 00:22:45,040 --> 00:22:51,460 Така че неуспешно функция затваря поток и да го взема в показалеца на поток, който искате да затворите, 272 00:22:51,460 --> 00:22:57,010 за разлика от действителното име на файла, който искате да затворите. 273 00:22:57,010 --> 00:23:01,620 И това е така, защото зад кулисите, когато се обаждате fopen 274 00:23:01,620 --> 00:23:12,020 , когато отворите файл, вие всъщност разпределяне на памет за съхранение на информация за файла. 275 00:23:12,020 --> 00:23:16,380 Така имате файлов указател, който има информация за файла, 276 00:23:16,380 --> 00:23:23,080 като тя е отворена, неговия размер, къде се намирате в момента файла, 277 00:23:23,080 --> 00:23:29,100 така че можете да направите за четене и запис на разговори, че специално място в рамките на файла. 278 00:23:29,100 --> 00:23:38,060 В крайна сметка затваряне на показалеца вместо затваряне на името на файла. 279 00:23:38,060 --> 00:23:48,990 >> Да? [Даниел] Така че, за да се използва под наем, ще ви кажа - как получите входния потребител? 280 00:23:48,990 --> 00:23:53,830 Ли fprintf действа като GetString в смисъл, че тя просто ще чака за въвеждане на потребителя 281 00:23:53,830 --> 00:23:57,180 и да ви помоля да напишете това - или да изчакате, за да въведете тези три неща в? 282 00:23:57,180 --> 00:24:00,480 Или ще трябва да използвате нещо, което да се приложи под наем? 283 00:24:00,480 --> 00:24:04,100 >> Да. Така че ние не сме - въпросът е, как да получите входния на потребителя 284 00:24:04,100 --> 00:24:09,220 с цел да се приложи под наем? И това, което имаме тук, е на повикващия за наем, 285 00:24:09,220 --> 00:24:17,690 приет през този персонал структура на данните, съхранявани в структурата вече. 286 00:24:17,690 --> 00:24:22,990 Така че fprintf е в състояние само да напиша, че данните директно файла. 287 00:24:22,990 --> 00:24:25,690 Няма нужда да чакате за приноса на потребителите. 288 00:24:25,690 --> 00:24:32,110 Потребителят вече входа от правилно поставяйки я в този персонал структура. 289 00:24:32,110 --> 00:24:36,510 И всичко, разбира се, ще се счупи, ако някой от тези указатели са нула, 290 00:24:36,510 --> 00:24:40,370 така че ние превъртете обратно тук, и ние с нетърпение в нашата структура. 291 00:24:40,370 --> 00:24:43,640 Имаме низ последно низ първата, низ имейл. 292 00:24:43,640 --> 00:24:48,530 Ние вече знаем, че всички тези, които наистина, под капака, Чар * променливите. 293 00:24:48,530 --> 00:24:53,470 Това може или не може да се посочи присвоява. 294 00:24:53,470 --> 00:24:55,800 Те могат да бъдат насочени към паметта на куп, 295 00:24:55,800 --> 00:24:59,650 може би паметта на стека. 296 00:24:59,650 --> 00:25:04,580 Ние наистина не знам, но ако някой от тези насоки са нула, или невалидни, 297 00:25:04,580 --> 00:25:08,120 , че това със сигурност ще се срине под наем на нашата функция. 298 00:25:08,120 --> 00:25:11,050 Това беше нещо, което е вид извън обхвата на изпита. 299 00:25:11,050 --> 00:25:16,440 Ние не се тревожим за това. 300 00:25:16,440 --> 00:25:22,170 Велики. Добре. Така от теста. 301 00:25:22,170 --> 00:25:25,760 >> Нека да затворите този човек, и отиваме да разгледаме pset 4. 302 00:25:25,760 --> 00:25:34,700 Така че, ако вие погледнете в спец. pset, след като можете да го ползвате, cs50.net/quizzes 303 00:25:34,700 --> 00:25:42,730 ние ще да мине през някои от днешните проблеми раздел. 304 00:25:42,730 --> 00:25:52,240 Аз превъртите надолу - раздел от въпроси започва на трета страница на pset спец.. 305 00:25:52,240 --> 00:25:57,800 И първата част ще ви помоли да отидете и да гледате кратко пренасочване на средства и тръби. 306 00:25:57,800 --> 00:26:02,820 Кой е вид хладно кратък, показва някои нови, готини трикове на командния ред, които можете да използвате. 307 00:26:02,820 --> 00:26:06,050 И тогава ние имаме няколко въпроса към теб, както добре. 308 00:26:06,050 --> 00:26:10,860 Този първи въпрос за потоци, към която ФОРМАТ пише по подразбиране, 309 00:26:10,860 --> 00:26:15,920 ние вид засегна само малко преди малко. 310 00:26:15,920 --> 00:26:22,380 Това fprintf, че ние тъкмо обсъждахме се в потока файл * за аргумент. 311 00:26:22,380 --> 00:26:26,580 неуспешно се в потока файл *, както и, 312 00:26:26,580 --> 00:26:32,660 и връщане на стойността на fopen ви дава поток файл *, както добре. 313 00:26:32,660 --> 00:26:36,060 Причината, поради която не сме виждали онези преди, когато сме разглеждат ФОРМАТ 314 00:26:36,060 --> 00:26:39,450 е така, защото ФОРМАТ има по подразбиране поток. 315 00:26:39,450 --> 00:26:41,810 И по подразбиране поток, към който може да пише 316 00:26:41,810 --> 00:26:45,190 ще разберете в краткосрочен. 317 00:26:45,190 --> 00:26:50,080 Така категорично да го погледнете. 318 00:26:50,080 --> 00:26:53,010 >> В раздел днес, отиваме да поговорим малко за GDB, 319 00:26:53,010 --> 00:26:57,720 тъй като по-запознати сте с него, повече практика с него, 320 00:26:57,720 --> 00:27:01,390 в състояние по-добре ще бъде да преследва грешки в собствения си код. 321 00:27:01,390 --> 00:27:05,540 Това ускорява процеса на отстраняване на грешки значително. 322 00:27:05,540 --> 00:27:09,230 Така че с помощта ФОРМАТ, всеки път, когато направите това, което трябва да компилирате кода си, 323 00:27:09,230 --> 00:27:13,000 трябва да го стартирате отново, понякога трябва да се движат около ФОРМАТ повикване, 324 00:27:13,000 --> 00:27:17,100 коментар код, то просто отнема известно време. 325 00:27:17,100 --> 00:27:20,850 Нашата цел е да се опита да ви убеди, че с GDB, можете същество 326 00:27:20,850 --> 00:27:26,810 ФОРМАТ нещо във всяка точка в кода си и никога не трябва да го компилирате. 327 00:27:26,810 --> 00:27:35,120 Вие никога не трябва да се започне и да познае къде да ФОРМАТ следващия. 328 00:27:35,120 --> 00:27:40,910 Първото нещо, което трябва да направите, е да копирате този ред и да получите код за раздел на уеб. 329 00:27:40,910 --> 00:27:47,530 Съм копиране В този ред на кода, който казва: "Wget http://cdn.cs50.net". 330 00:27:47,530 --> 00:27:49,510 Отивам да го копирате. 331 00:27:49,510 --> 00:27:55,950 Аз ще отида да ми уред, отдалечаване, така че можете да видите това, което правя, 332 00:27:55,950 --> 00:28:01,890 поставяне там, и щом натисна бутона Enter, това Wget команда буквално е уеб получите. 333 00:28:01,890 --> 00:28:06,210 Това ще събарят този файл на Интернет, 334 00:28:06,210 --> 00:28:11,790 и това ще да го запишете на текущата директория. 335 00:28:11,790 --> 00:28:21,630 Сега, ако аз добавя моя текущата директория, можете да видите, че аз имам тази section5.zip файл точно там. 336 00:28:21,630 --> 00:28:25,260 Начин да се справят с този човек, е да го разархивирате, 337 00:28:25,260 --> 00:28:27,650 което можете да направите в командния ред, просто така. 338 00:28:27,650 --> 00:28:31,880 Section5.zip. 339 00:28:31,880 --> 00:28:36,980 Това ще го разархивирайте, създайте папка за мен, 340 00:28:36,980 --> 00:28:40,410 надуват цялото съдържание, сложете ги там. 341 00:28:40,410 --> 00:28:47,410 Така че сега мога да отида в моя точка 5 директория, като използвате CD команда. 342 00:28:47,410 --> 00:28:58,310 Изчистете екрана с помощта на ясно. Така изчистване на екрана. 343 00:28:58,310 --> 00:29:02,280 Сега имам хубав чист терминал, за да се справят с. 344 00:29:02,280 --> 00:29:06,200 >> Сега, ако се изброят всички файлове, които виждам в тази директория, 345 00:29:06,200 --> 00:29:12,270 виждаш ли, че имам четири файлове: buggy1, buggy2, buggy3 и buggy4. 346 00:29:12,270 --> 00:29:16,180 Аз също имам съответните им файлове в. 347 00:29:16,180 --> 00:29:20,400 Ние не отиваме да разгледаме файлове в предприятието. 348 00:29:20,400 --> 00:29:24,140 Вместо това, ние отиваме да ги използва, когато се отворим GDB. 349 00:29:24,140 --> 00:29:28,220 Сме ги държат около, така че имаме достъп до действителния изходен код, когато ние използваме GDB, 350 00:29:28,220 --> 00:29:32,740 но целта на тази част на секцията е да калайджия наоколо с GDB 351 00:29:32,740 --> 00:29:40,370 и да видим как можем да го използваме, за да разбера какво не е наред с всяка от тези четири бъги програми. 352 00:29:40,370 --> 00:29:43,380 Така че ние просто ще из стаята много бързо, 353 00:29:43,380 --> 00:29:47,000 и аз ще помоля някой, който да се изпълнява една от бъгави програми, 354 00:29:47,000 --> 00:29:54,730 и тогава ние ще отидем като група през GDB, и ще видим какво можем да направим, за да се определи тези програми, 355 00:29:54,730 --> 00:29:58,460 или поне да се определи какво точно не е наред във всяка от тях. 356 00:29:58,460 --> 00:30:04,760 Нека започнем тук с Даниел. Ще ви свършат buggy1? Нека видим какво ще стане. 357 00:30:04,760 --> 00:30:09,470 Даниел казва, че има заявление вина. >> Да. Точно така. 358 00:30:09,470 --> 00:30:12,460 Така че, ако аз тичам buggy1, получавам сегмента вина. 359 00:30:12,460 --> 00:30:16,210 В този момент, мога да отида и отвори buggy1.c, 360 00:30:16,210 --> 00:30:19,450 се опитам да разбера какво не е наред, 361 00:30:19,450 --> 00:30:22,000 но една от най-неприятните неща за този сегмент грешка вина 362 00:30:22,000 --> 00:30:27,610 е, че тя не ви кажа по линия на програмата неща всъщност се обърка и се счупи. 363 00:30:27,610 --> 00:30:29,880 Можете вид трябва да погледнете кода 364 00:30:29,880 --> 00:30:33,990 и да разбера използва предполагам и проверете или ФОРМАТ за да видим какво точно не е наред. 365 00:30:33,990 --> 00:30:37,840 Един от най-готините неща за GDB е, че тя е много, много лесно 366 00:30:37,840 --> 00:30:42,170 да разбера линията при които програмата катастрофи. 367 00:30:42,170 --> 00:30:46,160 Това е напълно си заслужава да го използвате, дори и ако само за това. 368 00:30:46,160 --> 00:30:56,190 Така че, за да се зареди GDB, въведете GDB, и след това го даде пътя към изпълнимия файл, че искам да изпълните. 369 00:30:56,190 --> 00:31:01,960 Тук съм пишете GDB ./buggy1. 370 00:31:01,960 --> 00:31:06,600 Хит Enter. Дава ми всичко това информация за авторските права, 371 00:31:06,600 --> 00:31:13,000 и тук ще видите тази линия, която казва: "Четене на символи от / дом / 372 00:31:13,000 --> 00:31:17,680 jharvard/section5/buggy1 ". 373 00:31:17,680 --> 00:31:22,060 И ако всичко върви добре, ще видите, че отпечатате съобщение, което прилича на това. 374 00:31:22,060 --> 00:31:25,500 Ще прочетете символи, тя ще каже: "Аз чета символите от изпълнимия файл," 375 00:31:25,500 --> 00:31:29,900 и след това ще има тази "направи" съобщение тук. 376 00:31:29,900 --> 00:31:35,410 Ако видите някой друг вариант на този или виждате, че не можах да намеря символите 377 00:31:35,410 --> 00:31:41,460 или нещо подобно, какво означава това е, че просто не са съставили изпълним правилно. 378 00:31:41,460 --> 00:31:49,980 Когато се съставят програми за използване с GDB, ние трябва да използваме този специален грама флаг, 379 00:31:49,980 --> 00:31:54,540 и че е направено по подразбиране, ако вие компилирате вашите програми, просто като напишете направи 380 00:31:54,540 --> 00:31:59,320 или да направите бъги или да възстанови всеки един от тези. 381 00:31:59,320 --> 00:32:07,800 Но ако сте съставянето ръчно с звъня, тогава ще трябва да отидат и да включва, че грам флаг. 382 00:32:07,800 --> 00:32:10,310 >> В този момент, сега, че ние имаме GDB ред, 383 00:32:10,310 --> 00:32:12,310 Това е доста проста, за да стартирате програмата. 384 00:32:12,310 --> 00:32:19,740 Ние можем или да въведете план, или можем просто Type R. 385 00:32:19,740 --> 00:32:22,820 Повечето команди GDB може да бъде съкратен. 386 00:32:22,820 --> 00:32:25,940 Обикновено само една или няколко букви, което е доста хубаво. 387 00:32:25,940 --> 00:32:30,980 Така че Саад, ако Type R и натиснете Enter, какво се случва? 388 00:32:30,980 --> 00:32:39,390 Саад] Имам SIGSEGV, сегментация вина, и след това всичко това бръщолевене. 389 00:32:39,390 --> 00:32:43,650 >> Да. 390 00:32:43,650 --> 00:32:47,990 Както виждаме на екрана, точно сега, и като Саад каза, 391 00:32:47,990 --> 00:32:53,430 , когато въвеждате план или R и натиснете Enter, ние все още се същата грешка сегмента. 392 00:32:53,430 --> 00:32:55,830 Така че използването GDB не решава нашия проблем. 393 00:32:55,830 --> 00:32:59,120 Но това ни дава някаква бръщолевене, и се оказва, че това бръщолевене 394 00:32:59,120 --> 00:33:03,080 всъщност ни казва къде това се случва. 395 00:33:03,080 --> 00:33:10,680 Да прави разбор на това малко, това първо малко е функция, в която всичко е наред. 396 00:33:10,680 --> 00:33:20,270 Е това __ strcmp_sse4_2 и ни казва, че това се случва в този файл 397 00:33:20,270 --> 00:33:29,450 наречен sysdeps/i386, всичко това, отново, вид на каша, но линията 254. 398 00:33:29,450 --> 00:33:31,670 Това е малко трудно да се направи разбор. Обикновено, когато видя подобни неща, 399 00:33:31,670 --> 00:33:38,770 което означава, че Seg Faulting в един от системните библиотеки. 400 00:33:38,770 --> 00:33:43,220 Значи нещо да направя с strcmp. Вие, момчета, съм виждал strcmp преди. 401 00:33:43,220 --> 00:33:52,730 Не е твърде луд, но това означава, че strcmp е счупен или че има проблем с strcmp? 402 00:33:52,730 --> 00:33:57,110 Какво мислиш, Александър? 403 00:33:57,110 --> 00:34:04,890 [Александър], че е 254 ред? И - не двоичен, но това не е своите тавани, 404 00:34:04,890 --> 00:34:10,590 и тогава там е друг език за всяка функция. Е, че 254 в тази функция, или -? 405 00:34:10,590 --> 00:34:21,460 >> Това е линия 254. Изглежда, че в този файл, така че е монтаж код вероятно. 406 00:34:21,460 --> 00:34:25,949 >> Но, предполагам, че още по-наложително е, защото сме придобили сегмента вина, 407 00:34:25,949 --> 00:34:29,960 и тя изглежда като тя идва от strcmp функция, 408 00:34:29,960 --> 00:34:38,030 означава това, тогава, че strcmp е счупен? 409 00:34:38,030 --> 00:34:42,290 Тя не трябва, да се надяваме. Така че просто защото си имат сегментация вина 410 00:34:42,290 --> 00:34:49,480 в едно функциите на системата, обикновено това означава, че просто не сте го нарече правилно. 411 00:34:49,480 --> 00:34:52,440 Най-бързият нещо, което трябва да направя, за да разбера какво всъщност се случва 412 00:34:52,440 --> 00:34:55,500 когато видите нещо лудо като това, всеки път, когато видите сегмента вина, 413 00:34:55,500 --> 00:34:59,800 особено ако имате програма, която използва повече от основната, 414 00:34:59,800 --> 00:35:03,570 е да използвате обратно проследяване. 415 00:35:03,570 --> 00:35:13,080 Съкращавам обратно проследяване от писмено БТ, за разлика от цялата дума, обратно проследяване. 416 00:35:13,080 --> 00:35:16,510 Но Шарлот, какво се случва, когато въвеждате БТ и натиснете Enter? 417 00:35:16,510 --> 00:35:23,200 Шарлот] ми показва две линии, линия 0 и линия 1. 418 00:35:23,200 --> 00:35:26,150 >> Да. Така линия 0 и линия 1. 419 00:35:26,150 --> 00:35:34,560 Това са реалните рамки стека, които в момента са в игра, когато вашата програма се разби. 420 00:35:34,560 --> 00:35:42,230 Като се започне от най-горната рамка, рамка 0, а най-долния, който е кадър 1. 421 00:35:42,230 --> 00:35:45,140 Нашата най-горната рамка е strcmp рамка. 422 00:35:45,140 --> 00:35:50,080 Можете да мислите за това, подобен на този проблем, ние просто се правиш на викторина с указатели, 423 00:35:50,080 --> 00:35:54,890 където бяхме суап рамка топче на върха на основната рамка на стека, 424 00:35:54,890 --> 00:35:59,700 и имахме променливи, които суап се използва на върха на променливите, че основната е използвал. 425 00:35:59,700 --> 00:36:08,440 Тук нашата катастрофа се случи в strcmp нашата функция, която е наречена от нашата основна функция, 426 00:36:08,440 --> 00:36:14,370 и обратно проследяване ни дава не само функциите, в които не неща, 427 00:36:14,370 --> 00:36:16,440 но тя също ни казва, където всичко е наречен от. 428 00:36:16,440 --> 00:36:18,830 Така че, ако сменя малко по-надясно, 429 00:36:18,830 --> 00:36:26,110 можем да видим, че да, ние бяхме на линия 254 от strcmp sse4.s файл. 430 00:36:26,110 --> 00:36:32,540 Но обаждането е направено в buggy1.c, линия 6. 431 00:36:32,540 --> 00:36:35,960 Така че това означава, че можем да направим - можем просто да проверя и да видим какво се случва 432 00:36:35,960 --> 00:36:39,930 в buggy1.c, линия 6. 433 00:36:39,930 --> 00:36:43,780 Отново, има няколко начина да направите това. Един от тях е да излезете от GDB 434 00:36:43,780 --> 00:36:49,460 или имат своя код се отваря в друг прозорец и позоваване на кръста. 435 00:36:49,460 --> 00:36:54,740 Това, само по себе си, е доста удобен, защото сега, ако сте на работното време 436 00:36:54,740 --> 00:36:57,220 и имаш сегмента вина и си TF чудите къде всичко се счупи, 437 00:36:57,220 --> 00:36:59,710 може просто да се каже: "О, линия 6. Не знам какво става, 438 00:36:59,710 --> 00:37:03,670 но нещо за линия 6 се създава програмата ми да се счупят. 439 00:37:03,670 --> 00:37:10,430 Друг начин да го направя е, можете да използвате тази команда, наречена списъка в GDB. 440 00:37:10,430 --> 00:37:13,650 Можете да го съкрати с л. 441 00:37:13,650 --> 00:37:18,910 Така че, ако ние удари л, какво да стигна до тук? 442 00:37:18,910 --> 00:37:21,160 Ние цял куп странни неща. 443 00:37:21,160 --> 00:37:26,030 Това е действителният код събрание 444 00:37:26,030 --> 00:37:29,860 , която е през strcmp_sse4_2. 445 00:37:29,860 --> 00:37:32,440 Това изглежда фънки вид, 446 00:37:32,440 --> 00:37:36,520 и причината да получавате това е така, защото точно сега, 447 00:37:36,520 --> 00:37:40,160 GDB нас има в кадъра 0. 448 00:37:40,160 --> 00:37:43,070 >> Така че всеки път когато се вгледате в променливи, всеки път, когато погледнете изходния код, 449 00:37:43,070 --> 00:37:50,530 търсим изходен код, който се отнася до рамката стека В момента ние сме инча 450 00:37:50,530 --> 00:37:53,200 Така че, за да се получи нещо смислено, трябва да 451 00:37:53,200 --> 00:37:57,070 се премести в купчина рамка, която има повече смисъл. 452 00:37:57,070 --> 00:38:00,180 В този случай основната рамка стак ще направи малко повече смисъл, 453 00:38:00,180 --> 00:38:02,680 защото това е всъщност кода, който пише. 454 00:38:02,680 --> 00:38:05,330 Не strcmp код. 455 00:38:05,330 --> 00:38:08,650 Начинът, по който можете да се придвижвате между кадрите, в този случай, защото имаме две, 456 00:38:08,650 --> 00:38:10,430 имаме 0 и 1, 457 00:38:10,430 --> 00:38:13,650 можете да направите това с нагоре и надолу команди. 458 00:38:13,650 --> 00:38:18,480 Ако се преместя един кадър, 459 00:38:18,480 --> 00:38:21,770 сега съм в основния екран на стека. 460 00:38:21,770 --> 00:38:24,330 Може да се движи надолу, за да се върнете до мястото, където бях, 461 00:38:24,330 --> 00:38:32,830 тръгне отново нагоре, отидете отново, и да тръгне отново нагоре. 462 00:38:32,830 --> 00:38:39,750 Ако някога сте си програма в GDB, можете да получите катастрофа, вие получавате обратно проследяване, 463 00:38:39,750 --> 00:38:42,380 и ще видите, че тя е в някой файл, че не знаете какво се случва. 464 00:38:42,380 --> 00:38:45,460 Вие се опитвате списък, кодът не изглежда познато за вас, 465 00:38:45,460 --> 00:38:48,150 погледнете си рамки и да разбера къде се намирате. 466 00:38:48,150 --> 00:38:51,010 Вие вероятно сте в грешната рамка на стека. 467 00:38:51,010 --> 00:38:58,760 Или най-малкото сте в стек рамка, която не е един, че наистина може да развенчава. 468 00:38:58,760 --> 00:39:03,110 Сега, когато сме в подходяща рамка стека, ние сме в основната, 469 00:39:03,110 --> 00:39:08,100 сега можем да използваме командата списък, за да разбера какво линията. 470 00:39:08,100 --> 00:39:13,590 И вие можете да го видя, го отпечатани за нас тук. 471 00:39:13,590 --> 00:39:19,470 Но ние можем да удари изброят всички едно и също, и списъка ни дава тази хубава разпечатка 472 00:39:19,470 --> 00:39:23,920 на действителния изходен код, което се случва тук. 473 00:39:23,920 --> 00:39:26,420 >> По-специално, ние можем да погледнем на ред 6. 474 00:39:26,420 --> 00:39:29,330 Ние можем да видим какво се случва тук. 475 00:39:29,330 --> 00:39:31,250 И изглежда, че ние правим низ сравнение 476 00:39:31,250 --> 00:39:41,050 между стринга "CS50 скали" и argv [1]. 477 00:39:41,050 --> 00:39:45,700 Нещо в този трясък. 478 00:39:45,700 --> 00:39:54,120 Така че Миси, имаш ли някакви мисли за това какво може да се случва тук? 479 00:39:54,120 --> 00:39:59,400 [Missy] Аз не знам защо това се трясък. >> Не знам защо е трясък? 480 00:39:59,400 --> 00:40:02,700 Джими, някакви мисли? 481 00:40:02,700 --> 00:40:06,240 Джими] Не съм съвсем сигурен, но последния път, когато използвания низ сравнение, 482 00:40:06,240 --> 00:40:10,260 или strcmp, имахме три различни случая по него. 483 00:40:10,260 --> 00:40:12,800 Ние не са имали ==, аз не мисля, че точно в този първи ред. 484 00:40:12,800 --> 00:40:16,700 Вместо това, той е разделен на три, и е == 0, 485 00:40:16,700 --> 00:40:19,910 едно е <0, мисля, че и една е> 0. 486 00:40:19,910 --> 00:40:22,590 Така че може би нещо подобно? >> Да. Така че този въпрос 487 00:40:22,590 --> 00:40:27,200 се правим сравнението правилно? 488 00:40:27,200 --> 00:40:31,660 Стела? Някакви идеи? 489 00:40:31,660 --> 00:40:38,110 Стела] Аз не съм сигурен. >> Не съм сигурен. Даниел? Мисли? Добре. 490 00:40:38,110 --> 00:40:44,770 Оказва се, че това, което се случва тук, е, когато ние се завтече програма 491 00:40:44,770 --> 00:40:48,370 и ние имаме сегмента вина, когато сте стартирали програмата за първи път, Даниел, 492 00:40:48,370 --> 00:40:50,800 ти я дам никакви аргументи от командния ред? 493 00:40:50,800 --> 00:40:58,420 Даниел] бр. >> В този случай, каква е стойността на argv [1]? 494 00:40:58,420 --> 00:41:00,920 >> Има никаква стойност. >> Точно така. 495 00:41:00,920 --> 00:41:06,120 Е, не е подходяща стойност низ. 496 00:41:06,120 --> 00:41:10,780 Но има някаква стойност. Каква е стойността, която се записва там? 497 00:41:10,780 --> 00:41:15,130 >> Боклук стойност? >> Това е стойността на боклук или, в този случай, 498 00:41:15,130 --> 00:41:19,930 края на масива argv винаги се прекратява с нула. 499 00:41:19,930 --> 00:41:26,050 Така че това, което всъщност се съхранява в е нула. 500 00:41:26,050 --> 00:41:30,810 Другият начин да се разреши този проблем, вместо да го мислене чрез 501 00:41:30,810 --> 00:41:33,420 е да се опитаме да ги извежда. 502 00:41:33,420 --> 00:41:35,880 Това е мястото, където казва, че използването на GDB е страхотно, 503 00:41:35,880 --> 00:41:40,640 защото можете да отпечатате всички променливи, всички стойности, които искате 504 00:41:40,640 --> 00:41:43,230 използвате този удобен конте стр. команда. 505 00:41:43,230 --> 00:41:48,520 Така че, ако въведете стр. и след това въведете стойността на променлива или името на дадена променлива, 506 00:41:48,520 --> 00:41:55,320 се каже, argc, виждам, че argc е 1. 507 00:41:55,320 --> 00:42:01,830 Ако искам да отпечатате argv [0], може да направи така, просто ей така. 508 00:42:01,830 --> 00:42:04,840 И както видяхме, argv [0] винаги е на името на вашата програма, 509 00:42:04,840 --> 00:42:06,910 винаги името на изпълнимия файл. 510 00:42:06,910 --> 00:42:09,740 Тук можете да видите има пълното име на път. 511 00:42:09,740 --> 00:42:15,920 Също така мога да отпечатате argv [1] и да видим какво ще се случи. 512 00:42:15,920 --> 00:42:20,890 >> Тук имаме този вид мистична стойност. 513 00:42:20,890 --> 00:42:23,890 Имаме 0x0. 514 00:42:23,890 --> 00:42:27,850 Не забравяйте в началото на мандата, когато говорихме за шестнадесетични числа? 515 00:42:27,850 --> 00:42:34,680 Или че малко въпрос на края на pset 0 за това как да представляват 50 в шестнадесетичен? 516 00:42:34,680 --> 00:42:39,410 Начинът, по който пишем шестнадесетични числа в CS, просто няма да се обърка 517 00:42:39,410 --> 00:42:46,080 с десетични числа, е, че ние винаги ги поставете в 0x. 518 00:42:46,080 --> 00:42:51,420 Така че това 0x префикс винаги означава само тълкуване на следния номер като шестнадесетично число, 519 00:42:51,420 --> 00:42:57,400 не като низ, не като десетично число, а не като двоично число. 520 00:42:57,400 --> 00:43:02,820 Тъй като броят 5-0 е валиден номер в шестнадесетичен. 521 00:43:02,820 --> 00:43:06,240 И това е в десетичен номер, 50. 522 00:43:06,240 --> 00:43:10,050 Така че това е просто начина, по който двусмислието. 523 00:43:10,050 --> 00:43:14,860 Така 0x0 средства шестнадесетичен 0, което е също десетичната 0, двоични 0. 524 00:43:14,860 --> 00:43:17,030 Това е просто стойност 0. 525 00:43:17,030 --> 00:43:22,630 Оказва се, че това е, което, всъщност, е нищожна в паметта. 526 00:43:22,630 --> 00:43:25,940 Null е само 0. 527 00:43:25,940 --> 00:43:37,010 Тук елемент се съхранява при argv [1] е нищожна. 528 00:43:37,010 --> 00:43:45,220 Така че ние се опитваме да се сравни "CS50 скали" низ с нулев низ. 529 00:43:45,220 --> 00:43:48,130 Така dereferencing опитвате да отворите неща на нула, нула, 530 00:43:48,130 --> 00:43:55,050 обикновено ще предизвика някаква сегментация вина или други лоши неща да се случат. 531 00:43:55,050 --> 00:43:59,350 И се оказва, че strcmp не проверява, за да видите 532 00:43:59,350 --> 00:44:04,340 дали или не сте преминали в стойност, която е нула. 533 00:44:04,340 --> 00:44:06,370 Вместо това, тя просто върви напред, се опитва да направи нещо, 534 00:44:06,370 --> 00:44:14,640 и ако Seg грешки, SEG грешки, и това си е ваш проблем. Вие трябва да отидете да го поправим. 535 00:44:14,640 --> 00:44:19,730 Наистина бързо, как бихме могли да решите този проблем? Шарлот? 536 00:44:19,730 --> 00:44:23,540 Шарлот] Можете да проверите използвате, ако. 537 00:44:23,540 --> 00:44:32,240 Така че, ако argv [1] е нула, == 0, след това се върнете един или нещо неразбираемо. 538 00:44:32,240 --> 00:44:34,590 >> Да. Така че това е един чудесен начин да го направя, тъй като можем да проверим, за да видите, 539 00:44:34,590 --> 00:44:39,230 стойност, ние сме на път да премине в strcmp, argv [1], е нула? 540 00:44:39,230 --> 00:44:45,830 Ако това е нищожна, ние може да се каже нищо, се откажем. 541 00:44:45,830 --> 00:44:49,450 >> По-често срещаният начин да направите това е да използвате argc стойност. 542 00:44:49,450 --> 00:44:52,040 Можете да видите точно тук, в началото на главната, 543 00:44:52,040 --> 00:44:58,040 бяхме пропуснали, че първият тест, който ние обикновено правим, когато използвате аргументи от командния ред, 544 00:44:58,040 --> 00:45:05,240 , която е да се провери дали не ни argc стойност е това, което ние очакваме. 545 00:45:05,240 --> 00:45:10,290 В този случай, можем да очакваме най-малко два аргумента, 546 00:45:10,290 --> 00:45:13,660 името на програмата плюс един от другите. 547 00:45:13,660 --> 00:45:17,140 Защото ние сме на път да използват втория аргумент тук. 548 00:45:17,140 --> 00:45:21,350 Така че като някакъв вид тест предварително, преди strcmp нашия призив 549 00:45:21,350 --> 00:45:37,390 че тестовете дали или не argv е най-малко два, също така ще направи същото нещо. 550 00:45:37,390 --> 00:45:40,620 Ние можем да видим дали това работи като стартирате програмата отново. 551 00:45:40,620 --> 00:45:45,610 Винаги можете да стартирате програмата си в рамките на GDB, което е много хубаво. 552 00:45:45,610 --> 00:45:49,310 Можете да пуснете, а когато премине в аргументи за вашата програма, 553 00:45:49,310 --> 00:45:53,060 преминаване покрай тях, когато ти се обадя управлява, а не когато се стартират GDB. 554 00:45:53,060 --> 00:45:57,120 По този начин можете да поддържате позоваването на вашата програма с различни аргументи всеки път. 555 00:45:57,120 --> 00:46:08,080 Така тичайте, или отново, мога да Type R и нека да видим какво ще стане, ако напишете "здравей". 556 00:46:08,080 --> 00:46:11,140 Тя винаги ще ви попита дали искате да го започне отначало. 557 00:46:11,140 --> 00:46:17,490 Обикновено искаш да я стартирате отново от самото начало. 558 00:46:17,490 --> 00:46:25,010 И в този момент, тя се рестартира го отново, тя се отпечатва 559 00:46:25,010 --> 00:46:28,920 програмата, че ние сме, buggy1, с аргумента, здравей, 560 00:46:28,920 --> 00:46:32,720 и го отпечатва този стандарт се, тя казва: "Можете да получите D," тъжно лице. 561 00:46:32,720 --> 00:46:37,610 Но ние не Seg вина. Той заяви, че този процес излезе нормално. 562 00:46:37,610 --> 00:46:39,900 Така че изглежда доста добре. 563 00:46:39,900 --> 00:46:43,050 Не повече сегмента вина, то е минало, 564 00:46:43,050 --> 00:46:48,190 така че изглежда, че наистина е SEG бъг виновен, че ние се. 565 00:46:48,190 --> 00:46:51,540 За съжаление, това ни казва, че ние сме Г. 566 00:46:51,540 --> 00:46:54,090 >> Можем да се върнем и да погледнете кода и да видите какво се случва там 567 00:46:54,090 --> 00:46:57,980 да разбера какво е - защо той ни казва, че имаме D. 568 00:46:57,980 --> 00:47:03,690 Да видим, тук е това ФОРМАТ казва, че имаш D. 569 00:47:03,690 --> 00:47:08,540 Ако въведете списък, колкото можете да пишете списък, тя продължава да итерации през вашата програма, 570 00:47:08,540 --> 00:47:10,940 , така че ще ви покажем първите няколко реда от вашата програма. 571 00:47:10,940 --> 00:47:15,450 След това ще ви покажем следващите няколко реда, а на следващия парче и следващото парче. 572 00:47:15,450 --> 00:47:18,240 И ще продължавам да опитвам да сляза. 573 00:47:18,240 --> 00:47:21,180 И сега ние ще стигнем до "линия номер 16 е извън обхват". 574 00:47:21,180 --> 00:47:23,940 Защото има само 15 реда. 575 00:47:23,940 --> 00:47:30,310 Ако стигнете до този момент и се чудех, "Какво да правя?" можете да използвате командата помощ. 576 00:47:30,310 --> 00:47:34,340 Използвайте помощ и след това да го името на команда. 577 00:47:34,340 --> 00:47:36,460 И вие виждате, GDB ни дава този вид неща. 578 00:47:36,460 --> 00:47:43,870 Той казва: "По никакъв аргумент, изброява още десет реда след или около предходната регистрация. 579 00:47:43,870 --> 00:47:47,920 Списък - изброява десет реда преди " 580 00:47:47,920 --> 00:47:52,960 Така че, нека се опитаме списък минус. 581 00:47:52,960 --> 00:47:57,000 И това се изброяват 10 линии предишното можете да си поиграете с списъка с малко. 582 00:47:57,000 --> 00:48:02,330 Можете да направите списък, списък, може дори да се изброят редица, както и списък 8, 583 00:48:02,330 --> 00:48:07,500 и ще посочим 10 линии около линия 8. 584 00:48:07,500 --> 00:48:10,290 И можете да видите какво става тук имаш проста, ако друго. 585 00:48:10,290 --> 00:48:13,980 Ако напишете в CS50 скали, отпечатва "Можете да получите А." 586 00:48:13,980 --> 00:48:16,530 В противен случай той ще отпечатва "Можете да получите Г." 587 00:48:16,530 --> 00:48:23,770 Кофти града. Добре. Да? 588 00:48:23,770 --> 00:48:26,730 >> [Даниел] Така че, когато се опитах да прави CS50 скали без кавичките, 589 00:48:26,730 --> 00:48:29,290 той казва: "Можете да получите Г." 590 00:48:29,290 --> 00:48:32,560 Имах нужда от кавички, за да го накарам да работи, защо е така? 591 00:48:32,560 --> 00:48:38,490 >> Да. Оказва се, че когато - това е още една забавна малка хапка - 592 00:48:38,490 --> 00:48:47,900 когато стартирате програмата, ако ние го стартирате и въвеждате в CS50 скали, 593 00:48:47,900 --> 00:48:50,800 точно като Даниел казваше той го направи, и да ви удари Въведете, 594 00:48:50,800 --> 00:48:52,870 тя все още казва, че Г. 595 00:48:52,870 --> 00:48:55,580 И въпросът е, защо е това? 596 00:48:55,580 --> 00:49:02,120 И се оказва, че и двете ни терминал и GDB разбор като тези две отделни аргументи. 597 00:49:02,120 --> 00:49:04,800 Защото, когато има пространство, което е косвено, 598 00:49:04,800 --> 00:49:08,730 края на първия аргумент следващия аргумент, който е на път да започне. 599 00:49:08,730 --> 00:49:13,260 Начин да се съчетаят тези на две или Съжалявам, в един аргумент, 600 00:49:13,260 --> 00:49:18,510 е да се използват кавичките. 601 00:49:18,510 --> 00:49:29,560 Така че сега, ако го в кавички и да го стартирате отново, получаваме А. 602 00:49:29,560 --> 00:49:38,780 Така че просто трябва да набележи без кавичките, CS50 и скали биват анализирани като две отделни аргументи. 603 00:49:38,780 --> 00:49:45,320 С кавички, това е разбор съвсем като един аргумент. 604 00:49:45,320 --> 00:49:53,070 >> Можем да видим това, с точка на прекъсване. 605 00:49:53,070 --> 00:49:54,920 Досега сме се провежда в нашата програма, и да го е бил 606 00:49:54,920 --> 00:49:58,230 докато или Seg повреди или Хитове грешка 607 00:49:58,230 --> 00:50:05,930 или докато не излезе и всичко е било напълно глоба. 608 00:50:05,930 --> 00:50:08,360 Това не е непременно най-полезното нещо, защото понякога 609 00:50:08,360 --> 00:50:11,840 имате грешка в програмата си, но това не причинява сегментация вина. 610 00:50:11,840 --> 00:50:16,950 Не причинява си програма, за да спре или нещо подобно. 611 00:50:16,950 --> 00:50:20,730 Начин да се GDB да направите пауза в програмата в определен момент 612 00:50:20,730 --> 00:50:23,260 е да зададете точка на прекъсване. 613 00:50:23,260 --> 00:50:26,520 Можете да направите това чрез създаване на прекъсване на името на функцията 614 00:50:26,520 --> 00:50:30,770 или можете да зададете точка на прекъсване на определена линия на код. 615 00:50:30,770 --> 00:50:34,450 Харесва ми да се определят гранични стойности на имена на функции, защото лесно да се помни, 616 00:50:34,450 --> 00:50:37,700 и ако действително и промените изходния код на малко, 617 00:50:37,700 --> 00:50:42,020 тогава си точка на прекъсване действително ще остане на същото място в кода си. 618 00:50:42,020 --> 00:50:44,760 Като има предвид, че ако използвате номерата на редовете и номерата на редовете се променят 619 00:50:44,760 --> 00:50:51,740 защото вие добавяте или изтривате някакъв код, след което ви гранични стойности са всички тотално прецакани. 620 00:50:51,740 --> 00:50:58,590 Един от най-честите неща, които правя се на прекъсване на основната функция. 621 00:50:58,590 --> 00:51:05,300 Често ще стартира GDB, ще въведете б главната удари Въведете, и че ще зададете точка на прекъсване 622 00:51:05,300 --> 00:51:10,630 на главната функция, която просто казва: "пауза в програмата, веднага след като започнат да действат", 623 00:51:10,630 --> 00:51:17,960 и по този начин, когато пускам моята програма, да речем, CS50 скали като два аргумента 624 00:51:17,960 --> 00:51:24,830 и натиснете Enter, той получава основната функция и спира точно в най-горния ред, 625 00:51:24,830 --> 00:51:30,620 точно преди да оценява strcmp функция. 626 00:51:30,620 --> 00:51:34,940 >> Тъй като аз съм в пауза, сега мога да започна да се откажете от около и да видим какво става 627 00:51:34,940 --> 00:51:40,250 с всички на различните променливи, които са преминали в моята програма. 628 00:51:40,250 --> 00:51:43,670 Тук мога да отпечатате argc и да видим какво става. 629 00:51:43,670 --> 00:51:50,030 Argc е 3, тъй като тя има три различни стойности в него. 630 00:51:50,030 --> 00:51:54,060 Тя получава името на програмата, тя има първият аргумент и на втория аргумент. 631 00:51:54,060 --> 00:52:09,330 Ние можем да отпечатате тези от гледаш argv [0], argv [1], и argv [2]. 632 00:52:09,330 --> 00:52:12,030 Така че сега можете да видите също и защо настоящата покана strcmp ще се провалят, 633 00:52:12,030 --> 00:52:21,650 защото вие виждате, че е разделен на CS50 и скалите в две отделни аргументи. 634 00:52:21,650 --> 00:52:27,250 В този момент, след като удари на прекъсване, може да продължи да се засили чрез вашата програма 635 00:52:27,250 --> 00:52:32,920 ред по ред, за разлика стартиране на програмата отново. 636 00:52:32,920 --> 00:52:35,520 Така че, ако не искате да стартирате програмата отново и просто продължете от тук, 637 00:52:35,520 --> 00:52:41,970 можете да използвате командата продължават и продължават да стартирате програмата до края. 638 00:52:41,970 --> 00:52:45,010 Точно както го е направил тук. 639 00:52:45,010 --> 00:52:54,880 Въпреки това, ако рестартирате програмата, CS50 скали, го удари преКъсване ми, 640 00:52:54,880 --> 00:52:59,670 и този път, ако аз не искам просто да отидем по целия път през останалата част от програмата, 641 00:52:59,670 --> 00:53:08,040 Мога да използвам следващата команда, която да се съкрати с N. 642 00:53:08,040 --> 00:53:12,960 И това ще засили чрез програмата ред по ред. 643 00:53:12,960 --> 00:53:17,530 Така че можете да гледате, тъй като нещата се изпълняват, като променливи промяна, тъй като нещата се актуализира. 644 00:53:17,530 --> 00:53:21,550 Което е доста хубаво. 645 00:53:21,550 --> 00:53:26,570 Другите готино нещо е по-скоро от повтаряне на същата команда отново и отново и отново, 646 00:53:26,570 --> 00:53:30,670 ако можете просто да натиснете Enter - така че ето виждаш ли, че не сте въвели в нещо - 647 00:53:30,670 --> 00:53:33,780 ако аз просто да натиснете Enter, ще повтори предишната команда, 648 00:53:33,780 --> 00:53:36,900 или предишната команда GDB, че аз съм сложил инча 649 00:53:36,900 --> 00:53:56,000 Мога да продължа да удря Въведете и ще продължаваме да стъпва чрез моя код ред по ред. 650 00:53:56,000 --> 00:53:59,310 Бих насърчил вас да проверя, както и на други програми бъги. 651 00:53:59,310 --> 00:54:01,330 Ние не разполагат с време, за да получите чрез всички тях днес в раздел. 652 00:54:01,330 --> 00:54:05,890 Изходният код е там, така че да видим какво се случва 653 00:54:05,890 --> 00:54:07,730 зад кулисите, ако ви наистина остана, 654 00:54:07,730 --> 00:54:11,940 но най-малкото, просто практикуват зарежда GDB, 655 00:54:11,940 --> 00:54:13,940 изпълнението на програмата, докато тя се разпада на вас, 656 00:54:13,940 --> 00:54:18,260 получаване на обратно проследяване, фигуриращ какво функционират катастрофата е в 657 00:54:18,260 --> 00:54:24,450 какво линия, отпечатване на някои променливи стойности, 658 00:54:24,450 --> 00:54:30,140 само така можете да получите представа за него, защото това наистина ще ви помогне да вървите напред. 659 00:54:30,140 --> 00:54:36,340 В този момент, ние ще излезем на GDB, които можете да използвате откажат или просто р. 660 00:54:36,340 --> 00:54:40,460 Ако програмата ви е в средата на все още работи, и то не е излязъл, 661 00:54:40,460 --> 00:54:43,510 тя винаги ще ви попита: "Вие ли сте сигурен, че наистина искате да се откажете? 662 00:54:43,510 --> 00:54:48,770 Можете просто да удари. 663 00:54:48,770 --> 00:54:55,250 >> Сега отиваме да разгледаме следващия проблем, който имаме, което е програмата на котката. 664 00:54:55,250 --> 00:54:59,880 Ако гледате за пренасочване на средства и тръби, ще видите, че Томи използва тази програма 665 00:54:59,880 --> 00:55:07,540 , която основно се отпечатва цялата продукция на файл на екрана. 666 00:55:07,540 --> 00:55:12,660 Така че, ако аз тичам котка, това всъщност е вграден в програмата на уреда, 667 00:55:12,660 --> 00:55:16,860 и ако имате Mac-ове, можете да направите това на вашия Mac, ако се отвори терминал. 668 00:55:16,860 --> 00:55:25,630 А ние - котка, да речем, cp.c, и натиснете Enter. 669 00:55:25,630 --> 00:55:29,640 Това, ако ние се придвижите нагоре малко и да видим къде се прокара линията, 670 00:55:29,640 --> 00:55:40,440 или когато ние се завтече котка команда, буквално отпечатани съдържанието на cp.c да ни екрана. 671 00:55:40,440 --> 00:55:44,140 Ние можем да го стартирате отново и можете да поставите в множество файлове. 672 00:55:44,140 --> 00:55:49,880 Така че можете да направите cp.c котка, а след това можем да се слеят в cat.c файл, 673 00:55:49,880 --> 00:55:53,250 което е програмата сме да пиша, 674 00:55:53,250 --> 00:55:58,140 и това ще отпечатате двата файла, за да направите резервно копие на нашия екран. 675 00:55:58,140 --> 00:56:05,490 Така че, ако ние превъртете малко, ние виждаме, че когато ние се завтече тази котка cp.c, cat.c, 676 00:56:05,490 --> 00:56:17,110 за първи път го отпечатва на КП файл и след това под него, отпечатани cat.c файл чак тук. 677 00:56:17,110 --> 00:56:19,650 Отиваме да използвате тази просто да се качите краката ни мокри. 678 00:56:19,650 --> 00:56:25,930 Поиграйте си с прости печат към терминала, вижте как работи. 679 00:56:25,930 --> 00:56:39,170 Ако вие се отвори с Gedit cat.c, удари Enter, 680 00:56:39,170 --> 00:56:43,760 можете да видите програмата, която сме на път да пиша. 681 00:56:43,760 --> 00:56:48,980 Включили сме тази хубава плоча на котела, така че не е нужно да прекарват времето си пишете всички, че. 682 00:56:48,980 --> 00:56:52,310 Ние също така да проверите броя на аргументи премина инча 683 00:56:52,310 --> 00:56:56,910 Ние печат приятен за използване. 684 00:56:56,910 --> 00:57:00,950 >> Това е вид на нещо, че отново, както и ние сме били говорим за, 685 00:57:00,950 --> 00:57:04,490 това е почти като мускулна памет. 686 00:57:04,490 --> 00:57:07,190 Само не забравяйте да правиш едно и също такива неща 687 00:57:07,190 --> 00:57:11,310 и винаги отпечатване някаква полезна съобщение 688 00:57:11,310 --> 00:57:17,670 така че хората да знаят как да изпълнявате вашата програма. 689 00:57:17,670 --> 00:57:21,630 С котка, това е доста проста, просто щяхме да мине през всички различни аргументи 690 00:57:21,630 --> 00:57:24,300 , които бяха приети в нашата програма, и отиваме да отпечатате 691 00:57:24,300 --> 00:57:29,950 съдържанието им, на екрана един по един. 692 00:57:29,950 --> 00:57:35,670 За да отпечатате файлове на екрана, ние ще направим нещо подобно 693 00:57:35,670 --> 00:57:38,120 на това, което направихме в края на теста. 694 00:57:38,120 --> 00:57:45,350 В края на теста, които наемат програма, ние трябваше да отвори файл, 695 00:57:45,350 --> 00:57:48,490 и след това трябваше да се печата на него. 696 00:57:48,490 --> 00:57:54,660 В този случай, ние отиваме да отворите файл, и отива да чете от него, вместо да. 697 00:57:54,660 --> 00:58:00,630 След това отиваме да отпечатате, вместо на файл, отиваме да отпечатате на екрана. 698 00:58:00,630 --> 00:58:05,830 Така отпечатване на екрана всички сте правили преди с ФОРМАТ. 699 00:58:05,830 --> 00:58:08,290 Така че това не е твърде луд. 700 00:58:08,290 --> 00:58:12,190 Но четенето на файла е някак странно. 701 00:58:12,190 --> 00:58:17,300 Ще отидем през тази малко в даден момент. 702 00:58:17,300 --> 00:58:20,560 Ако вие се върнете на последния проблем на викторина, проблем 33, 703 00:58:20,560 --> 00:58:27,280 на първа линия, че ние ще направим тук, за отваряне на досието, е много подобен на това, което направихме там. 704 00:58:27,280 --> 00:58:36,370 Така Стела, какво прави тази линия изглежда като, когато отворите файл? 705 00:58:36,370 --> 00:58:47,510 [Stella] Capital FILE *, файл - >> Добре. >> - Е равна на fopen. >> Мда. 706 00:58:47,510 --> 00:58:55,980 Което в този случай? Това е в коментара. 707 00:58:55,980 --> 00:59:06,930 >> В коментара? argv [] и R? 708 00:59:06,930 --> 00:59:11,300 >> Точно така. Точно така. Така че Стела е напълно прав. 709 00:59:11,300 --> 00:59:13,720 Това е линията прилича. 710 00:59:13,720 --> 00:59:19,670 Отиваме да се получи променлив поток файл, той се съхранява във файл *, така че всички шапки, 711 00:59:19,670 --> 00:59:25,720 FILE *, както и името на тази променлива ще бъде файл. 712 00:59:25,720 --> 00:59:32,250 Бихме могли да го наречем, каквото ни харесва. Бихме могли да го наречем first_file или file_i, каквото и да искате. 713 00:59:32,250 --> 00:59:37,590 И след това името на файла е приет на командния ред за тази програма. 714 00:59:37,590 --> 00:59:44,450 Така че се съхранява в argv [] и след това отиваме да отворите този файл в режим на четене. 715 00:59:44,450 --> 00:59:48,100 Сега, когато сме отворили файла, какво е това, което ние винаги трябва да помним, да се направи 716 00:59:48,100 --> 00:59:52,230 когато сме отворили файл? Затворете. 717 00:59:52,230 --> 00:59:57,220 Така че Миси, как да затворите файл? 718 00:59:57,220 --> 01:00:01,020 [Missy] неуспешно (файл) >> неуспешно (файл). Точно така. 719 01:00:01,020 --> 01:00:05,340 Велики. Добре. Ако се вгледаме в това да направя коментар тук, 720 01:00:05,340 --> 01:00:11,940 се казва: "Open argv [] и отпечатване на съдържанието му на стандартния изход." 721 01:00:11,940 --> 01:00:15,460 >> Standard навън е странно име. STDOUT е само начин да се каже 722 01:00:15,460 --> 01:00:22,880 искаме да я отпечатате на терминала, ние искаме да го отпечатате на стандартния изходен поток. 723 01:00:22,880 --> 01:00:26,450 Ние действително можем да се отървем от този коментар тук. 724 01:00:26,450 --> 01:00:36,480 Отивам да го копирате и да го поставите, тъй като това е, което ние направихме. 725 01:00:36,480 --> 01:00:41,290 В този момент, сега ще трябва да прочетете малко на файла по малко. 726 01:00:41,290 --> 01:00:46,300 Сме обсъждали няколко начина на четене на файлове. 727 01:00:46,300 --> 01:00:51,830 Кои са вашите фаворити досега? 728 01:00:51,830 --> 01:00:57,960 Какви начини виждал ли си или не си спомняте, да чете файлове? 729 01:00:57,960 --> 01:01:04,870 [Даниел] fread? >> Fread? Така че fread е един. Джими, знаеш ли някакви други? 730 01:01:04,870 --> 01:01:12,150 Джими] Не >> Добре. Не. Шарлот? Александър? Всички други? Добре. 731 01:01:12,150 --> 01:01:20,740 Затова другите са fgetc, е, че ние ще използваме много. 732 01:01:20,740 --> 01:01:26,410 Има също така и fscanf, вие се види модела тук? 733 01:01:26,410 --> 01:01:29,170 Всички те започват с е. Нещо общо с даден файл. 734 01:01:29,170 --> 01:01:35,260 Fread, fgetc, fscanf. Те всички са от читалищата функции. 735 01:01:35,260 --> 01:01:49,120 За писане имаме неуспешно, ние имаме fputc вместо fgetc. 736 01:01:49,120 --> 01:01:58,250 Ние също имаме fprintf както видяхме в анкетата. 737 01:01:58,250 --> 01:02:01,680 Тъй като това е проблем, който включва четене от файл, 738 01:02:01,680 --> 01:02:04,940 отиваме да се използва един от тези три функции. 739 01:02:04,940 --> 01:02:10,890 Ние няма да се използват тези функции тук. 740 01:02:10,890 --> 01:02:14,880 Тези функции са в стандартния I / O библиотека. 741 01:02:14,880 --> 01:02:17,510 Така че, ако се вгледате в горната част на тази програма, 742 01:02:17,510 --> 01:02:24,110 можете да видите, че ние вече включва заглавния файл за стандартния I / O библиотека. 743 01:02:24,110 --> 01:02:27,120 Ако искаме да разберем кой искате да използвате, 744 01:02:27,120 --> 01:02:29,690 винаги можем да се отворят страниците на човек. 745 01:02:29,690 --> 01:02:34,350 Така че можем да въведете stdio човек 746 01:02:34,350 --> 01:02:43,180 и да прочетете всичко за stdio входни и изходни функции в C. 747 01:02:43,180 --> 01:02:49,870 И ние вече можем да видим О, вижте. Споменава fgetc, той споменава fputc. 748 01:02:49,870 --> 01:02:57,220 Така че можете да пробиете малко и погледнете, да речем, fgetc 749 01:02:57,220 --> 01:03:00,060 и погледнете в страницата си човек. 750 01:03:00,060 --> 01:03:03,430 Можете да видите, че той отива заедно с цял куп други функции: 751 01:03:03,430 --> 01:03:12,640 fgetc, fgets, getc, getchar, получава, ungetc, и въвеждане на символи и низове. 752 01:03:12,640 --> 01:03:19,180 Така че това е как четем в символи и струнни от файлове от стандартния вход, 753 01:03:19,180 --> 01:03:21,990 който е по същество от потребителя. 754 01:03:21,990 --> 01:03:24,780 И това е как го правим в действителност C. 755 01:03:24,780 --> 01:03:30,850 Така че това не е с помощта на GetString и GetChar функции 756 01:03:30,850 --> 01:03:36,840 че ние използвахме от библиотеката CS50. 757 01:03:36,840 --> 01:03:39,710 Ние ще направим този проблем по няколко начина 758 01:03:39,710 --> 01:03:43,430 , така че да могат да се виждат два различни начини да го направите. 759 01:03:43,430 --> 01:03:48,490 Както fread функция, която Даниел спомена и fgetc са добри начини да го направя. 760 01:03:48,490 --> 01:03:53,790 Мисля, fgetc е малко по-лесно, тъй като тя има само, както виждате, 761 01:03:53,790 --> 01:03:59,660 един аргумент, FILE *, че ние се опитваме да прочетете на героя от, 762 01:03:59,660 --> 01:04:02,740 и неговото връщане стойност е вътр. 763 01:04:02,740 --> 01:04:05,610 И това е малко объркващо, нали? 764 01:04:05,610 --> 01:04:11,450 >> Защото ние сме характер, така че защо не това завръщане Чар? 765 01:04:11,450 --> 01:04:18,700 Вие имате някакви идеи за това защо това не може да се върне Чар? 766 01:04:18,700 --> 01:04:25,510 [Миси отговори, неразбираем] >> Да, Така че Миси е напълно прав. 767 01:04:25,510 --> 01:04:31,570 Ако това е ASCII, тогава това число може да бъде съпоставена с действително Чар. 768 01:04:31,570 --> 01:04:33,520 Може да е ASCII характер, и това е вярно. 769 01:04:33,520 --> 01:04:36,220 Това е точно това, което се случва. 770 01:04:36,220 --> 01:04:39,190 Ние използваме едно цяло число, просто защото тя има повече битове. 771 01:04:39,190 --> 01:04:44,750 Това е по-голям от Чар, Чар ни има само 8 бита, че 1 байт на нашите 32-битови машини. 772 01:04:44,750 --> 01:04:48,520 И Int има всички 4 байта на пространството. 773 01:04:48,520 --> 01:04:50,940 И се оказва, че начина, по който fgetc работи, 774 01:04:50,940 --> 01:04:53,940 ако ние превъртете надолу в резюме ни в страницата с този човек малко, 775 01:04:53,940 --> 01:05:05,000 превъртете надолу. Оказва се, че те използват тази особена стойност EOF. 776 01:05:05,000 --> 01:05:09,640 Това е специална константа като върнатата стойност на fgetc функция 777 01:05:09,640 --> 01:05:14,570 всеки път, когато удари в края на файла или ако получите съобщение за грешка. 778 01:05:14,570 --> 01:05:18,170 И се оказва, че за да правите тези сравнения с EOF правилно, 779 01:05:18,170 --> 01:05:24,060 искате да имате, че допълнително количество информация, която имате в Int 780 01:05:24,060 --> 01:05:28,420 за разлика от използването на знак променлива. 781 01:05:28,420 --> 01:05:32,130 Въпреки че fgetc е ефективно знак от файл, 782 01:05:32,130 --> 01:05:38,450 искате да си припомните, че се връща нещо, което е от тип Int. 783 01:05:38,450 --> 01:05:41,360 Това заяви, че е доста лесен за използване. 784 01:05:41,360 --> 01:05:44,960 Това ще ни даде знак, така че всичко, което трябва да направим, е да продължавам да се питам файла, 785 01:05:44,960 --> 01:05:48,440 "Дай ми следващия знак, дай ми следващия знак, дай ми следващия знак" 786 01:05:48,440 --> 01:05:51,400 докато не стигнем до края на файла. 787 01:05:51,400 --> 01:05:54,730 И това ще дръпне в един символ в даден момент от нашия файл 788 01:05:54,730 --> 01:05:56,250 и след това можем да правим каквото искаме с него. 789 01:05:56,250 --> 01:06:00,160 Можем да го съхранява, ние можем да го добавите в низ, можем да го разпечатате. 790 01:06:00,160 --> 01:06:04,630 От това. 791 01:06:04,630 --> 01:06:09,600 >> Приближаването обратно и връщане назад към cat.c нашата програма, 792 01:06:09,600 --> 01:06:16,170 ако ще да използвате fgetc, 793 01:06:16,170 --> 01:06:21,710 как бихме могли да се подходи към този от следващия ред? 794 01:06:21,710 --> 01:06:26,020 Отиваме да използвате fread ще направи нещо по-различно. 795 01:06:26,020 --> 01:06:32,600 И този път, ние просто ще използваме fgetc да се получи един символ в даден момент. 796 01:06:32,600 --> 01:06:40,910 Да обработите цялата преписка, какво бихме могли да трябва да направя? 797 01:06:40,910 --> 01:06:44,030 Колко знака има във файл? 798 01:06:44,030 --> 01:06:47,390 Има много. Така че най-вероятно искате да се получи един 799 01:06:47,390 --> 01:06:49,860 и след това получи друг и да получите друг и да получите друга. 800 01:06:49,860 --> 01:06:53,330 Какъв алгоритъм мислиш ли, че може да се наложи да се използва тук? 801 01:06:53,330 --> 01:06:55,470 Какъв тип? [Александър] А за контур? >> Точно така. 802 01:06:55,470 --> 01:06:57,500 Някакъв вид на линията. 803 01:06:57,500 --> 01:07:03,380 А за цикъла всъщност е страхотно, в този случай. 804 01:07:03,380 --> 01:07:08,620 И както казах, това звучи като искате примка над цялата преписка, 805 01:07:08,620 --> 01:07:11,820 получаване на символ в даден момент. 806 01:07:11,820 --> 01:07:13,850 Всички предложения за това какво може да изглежда? 807 01:07:13,850 --> 01:07:22,090 [Александър, неразбираем] 808 01:07:22,090 --> 01:07:30,050 >> Добре, само ми кажи на английски език това, което се опитваме да направим? [Александър, неразбираем] 809 01:07:30,050 --> 01:07:36,270 Така че в този случай, това звучи като ние просто се опитваме да отскача над цялата преписка. 810 01:07:36,270 --> 01:07:45,330 [Александър] Така че аз <размера на Int? >> Размер на - 811 01:07:45,330 --> 01:07:49,290 Предполагам, че размера на файла, нали? Размер - Ще го напиша по този начин. 812 01:07:49,290 --> 01:07:57,470 Размер на файла за момента, аз + +. 813 01:07:57,470 --> 01:08:04,610 Така се оказва, че начина, по който се прави със fgetc и това е нещо ново, 814 01:08:04,610 --> 01:08:10,460 е, че няма лесен начин да получите размера на файла 815 01:08:10,460 --> 01:08:16,979 с този тип конструкция, която сте виждали преди "sizeof". 816 01:08:16,979 --> 01:08:20,910 Когато ние използваме тази fgetc функция, ние ви представяме някакъв вид 817 01:08:20,910 --> 01:08:29,069 нова, фънки синтаксис за цикъл, където, вместо да използват само основен брояч 818 01:08:29,069 --> 01:08:33,920 да отиде знак по знак, отиваме да дръпнете един символ в даден момент, 819 01:08:33,920 --> 01:08:37,120 един символ в даден момент, и начина, по който ние знаем, че сме в края 820 01:08:37,120 --> 01:08:41,290 когато не сме броят определен брой знаци, 821 01:08:41,290 --> 01:08:49,939 но когато характера извадя е, че специална края на файла характер. 822 01:08:49,939 --> 01:08:58,689 Така че можем да направим това, като - Аз наричам това CH, и ние ще го инициализира 823 01:08:58,689 --> 01:09:08,050 с първата покана за първия знак на файла. 824 01:09:08,050 --> 01:09:14,979 Така че тази част точно тук, това ще се получи, символ на файла 825 01:09:14,979 --> 01:09:20,840 и да го съхранява в променливата гл. 826 01:09:20,840 --> 01:09:25,420 Ние ще продължим да правиш това, докато стигнем до края на файла, 827 01:09:25,420 --> 01:09:41,170 , които правим чрез тестване за характера, не е равен на този специален характер EOF. 828 01:09:41,170 --> 01:09:48,750 И тогава, вместо да прави CH + +, която просто ще увеличите стойността, 829 01:09:48,750 --> 01:09:52,710 така че ако четем от файла, на капитала на, да речем, 830 01:09:52,710 --> 01:09:56,810 CH + + ще ни даде б, и тогава ние ще получите в и след това г. 831 01:09:56,810 --> 01:09:59,310 Това очевидно не е това, което искаме. Това, което искаме тук 832 01:09:59,310 --> 01:10:05,830 в това последно малко искаме да получим следващия знак от файла. 833 01:10:05,830 --> 01:10:09,500 >> И така, как бихме могли да получи следващия знак от файла? 834 01:10:09,500 --> 01:10:13,470 Как да стигнем до първия знак от файл? 835 01:10:13,470 --> 01:10:17,200 [Студентски fgetfile? >> Fgetc, съжалявам, бяхте напълно прав. 836 01:10:17,200 --> 01:10:20,470 Аз го сгрешена точно там. Така че, да. 837 01:10:20,470 --> 01:10:26,240 Тук, вместо да правиш CH + +, 838 01:10:26,240 --> 01:10:29,560 ние просто ще се обадя fgetc (файл) 839 01:10:29,560 --> 01:10:39,180 и запазване на резултата в същото CH променлива. 840 01:10:39,180 --> 01:10:43,730 [Student въпрос, неразбираем] 841 01:10:43,730 --> 01:10:52,390 >> Това е мястото, където тези момчета файл * са специални. 842 01:10:52,390 --> 01:10:59,070 Начинът, по който те работят, те - когато за пръв път отворите - когато за първи път правите, че fopen разговор, 843 01:10:59,070 --> 01:11:04,260 FILE * ефективно служи като указател към началото на файла. 844 01:11:04,260 --> 01:11:12,830 И тогава всеки път, когато ти се обадя fgetc, тя се движи един символ във файла. 845 01:11:12,830 --> 01:11:23,280 Така че, когато ти се обадя, увеличаване на файловия указател от един символ. 846 01:11:23,280 --> 01:11:26,210 И когато fgetc отново, сте го движи друг характер 847 01:11:26,210 --> 01:11:28,910 и друг характер и друг характер и друг характер. 848 01:11:28,910 --> 01:11:32,030 [Student въпрос, неразбираем] >> И това е - да. 849 01:11:32,030 --> 01:11:34,810 Това е вид на тази магия под капака. 850 01:11:34,810 --> 01:11:37,930 Увеличаване чрез. 851 01:11:37,930 --> 01:11:46,510 В този момент, вие сте в състояние действително да работи с характер. 852 01:11:46,510 --> 01:11:52,150 И така, как бихме могли да отпечатате това на екрана, сега? 853 01:11:52,150 --> 01:11:58,340 Ние можем да използваме същата ФОРМАТ нещо, което сме използвали преди. 854 01:11:58,340 --> 01:12:00,330 Че ние сме били семестър. 855 01:12:00,330 --> 01:12:05,450 Можем да наречем ФОРМАТ, 856 01:12:05,450 --> 01:12:21,300 и ние можем да преминем в характера просто ей така. 857 01:12:21,300 --> 01:12:27,430 Друг начин да го направя вместо да използва ФОРМАТ и се налага да правя този низ формат, 858 01:12:27,430 --> 01:12:29,490 ние също може да използва един от другите функции. 859 01:12:29,490 --> 01:12:40,090 Ние можем да използваме fputc, която отпечатва символ на екрана, 860 01:12:40,090 --> 01:12:52,580 освен ако погледнем в fputc - нека я увеличите малко. 861 01:12:52,580 --> 01:12:56,430 Виждаме, което е хубаво е, че отнема в характера, които четем, като се използва fgetc, 862 01:12:56,430 --> 01:13:05,100 но тогава ние трябва да му се даде поток да печатате. 863 01:13:05,100 --> 01:13:11,850 Можем също така да използвате putchar функция, която ще постави директно на стандартния изход. 864 01:13:11,850 --> 01:13:16,070 Така че има един куп от различните варианти, които можем да използваме за печат. 865 01:13:16,070 --> 01:13:19,580 Те всички са в стандартния I / O библиотека. 866 01:13:19,580 --> 01:13:25,150 Всеки път, когато искате да отпечатате - така ФОРМАТ, по подразбиране, ще се отпечата на специален стандарт от поток, 867 01:13:25,150 --> 01:13:27,910 което е, че стандартния изход. 868 01:13:27,910 --> 01:13:41,300 Така че ние можем само да се отнасят към него като един вид от тази магия стойност, стандартния изход тук. 869 01:13:41,300 --> 01:13:48,410 Опа. Поставете запетая извън. 870 01:13:48,410 --> 01:13:52,790 >> Това е много нова, фънки информация тук. 871 01:13:52,790 --> 01:13:58,600 Голяма част от това е много идиоматичен, в смисъл, че това е код 872 01:13:58,600 --> 01:14:05,700 , което е написано по този начин, само защото тя е чиста, да чете, да се чете лесно. 873 01:14:05,700 --> 01:14:11,520 Има много различни начини да го направя, много различни функции, които можете да използвате, 874 01:14:11,520 --> 01:14:14,680 но ние сме склонни да просто следвайте същите тези модели отново и отново. 875 01:14:14,680 --> 01:14:20,180 Така че не се изненадвайте, ако видите код, като това идва отново и отново. 876 01:14:20,180 --> 01:14:25,690 Добре. В този момент, ние трябва да се прекъсне за деня. 877 01:14:25,690 --> 01:14:31,300 Благодаря, че дойдохте. Благодаря за гледане, ако сте онлайн. И ние ще се видим следващата седмица. 878 01:14:31,300 --> 01:14:33,890 [CS50.TV]