1 00:00:00,000 --> 00:00:02,500 [Powered by Google Translate] [Дел 5 - поудобно] 2 00:00:02,500 --> 00:00:04,690 [Роб Бауден - Универзитетот Харвард] 3 00:00:04,690 --> 00:00:07,250 [Ова е CS50. - CS50.TV] 4 00:00:08,990 --> 00:00:14,250 >> Како што реков во мојот мејл, постојат многу работи што можете да ги користите 5 00:00:14,250 --> 00:00:17,060 освен апаратот всушност направиме проблем комплети. 6 00:00:17,060 --> 00:00:19,910 Ние Ви препорачуваме да го стори тоа во апаратот само затоа што тогаш ние полесно може да ви помогне 7 00:00:19,910 --> 00:00:22,070 и знаеме колку се оди на работа. 8 00:00:22,070 --> 00:00:26,950 Но, како еден пример каде што можете да ги правите нештата ако, да речеме, немате пристап 9 00:00:26,950 --> 00:00:31,570 кон апаратот или сакате да работите во Научниот центар подрумот - 10 00:00:31,570 --> 00:00:33,090 што всушност тие имаат апаратот премногу - 11 00:00:33,090 --> 00:00:35,150 ако сакате да работат насекаде. 12 00:00:35,150 --> 00:00:42,370 Еден пример е си ја видел / чул за SSH? 13 00:00:44,380 --> 00:00:47,780 SSH е во основа, само како поврзете со нешто. 14 00:00:47,780 --> 00:00:51,340 Всушност, токму сега сум SSHed во уредот. 15 00:00:51,340 --> 00:00:54,290 Јас никогаш не работат директно во апаратот. 16 00:00:55,930 --> 00:01:01,060 Тука е апаратот, и ако се погледне долу тука ќе видите оваа IP адреса. 17 00:01:01,060 --> 00:01:03,650 Јас никогаш не работат во апаратот себе; 18 00:01:03,650 --> 00:01:08,840 Јас секогаш дојде до iTerm2 прозорец / терминален прозорец. 19 00:01:08,840 --> 00:01:15,910 Можете да SSH на таа IP адреса, ssh, jharvard@192.168.129.128. 20 00:01:15,910 --> 00:01:20,390 Се сеќавам дека бројот е многу лесно, бидејќи тоа е толку убаво шема. 21 00:01:20,390 --> 00:01:24,920 Но, тоа ќе ме прашате за мојата лозинка, и сега сум во апаратот. 22 00:01:24,920 --> 00:01:33,060 Во суштина, во овој момент, ако отвори терминал внатрешноста на апаратот себе, 23 00:01:33,060 --> 00:01:36,350 овој интерфејс, сепак ќе го користи, е иста 24 00:01:36,350 --> 00:01:40,010 како интерфејс сум користење на повеќе од тука, но сега сте SSHed. 25 00:01:42,240 --> 00:01:44,920 Вие не треба да SSH на уредот. 26 00:01:44,920 --> 00:01:52,360 Еден пример на друго место можете да SSH да е јас сум прилично сигурен дека имате стандардно - 27 00:01:52,360 --> 00:01:55,020 О. Поголеми. 28 00:01:55,020 --> 00:02:01,130 Сите треба да имаат стандардно ФАС сметки на ФАС сервери. 29 00:02:01,130 --> 00:02:06,840 За мене, јас би SSH за rbowden@nice.fas.harvard.edu. 30 00:02:06,840 --> 00:02:11,610 Тоа се случува да ве прашам што прв пат, и велиш ДА. 31 00:02:11,610 --> 00:02:15,840 Мојата лозинка е само ќе ми биде ФАС лозинка. 32 00:02:15,840 --> 00:02:22,650 И така сега, јас сум SSHed на убаво сервери, и можам да направам ништо што сакате овде. 33 00:02:22,650 --> 00:02:28,560 Многу класи може да се земе како 124, се случува да имаат да испратите нешто овде 34 00:02:28,560 --> 00:02:30,950 всушност да ја поднесете вашата проблемот комплети. 35 00:02:30,950 --> 00:02:34,100 Но, велат дека не имаат пристап до вашиот апарат. 36 00:02:34,100 --> 00:02:37,910 Потоа можете да ги правите нештата, како овде ќе каже - 37 00:02:37,910 --> 00:02:42,160 Ова е само нашиот дел од прашањата. 38 00:02:42,160 --> 00:02:45,070 Тоа ќе побара од вас да го направите ова во апаратот. 39 00:02:45,070 --> 00:02:47,790 Наместо тоа, само ќе го направи на серверот. 40 00:02:47,790 --> 00:02:50,560 Одам да отпакувате тоа. 41 00:02:50,560 --> 00:02:55,670 Проблемот се случува да биде дека сте навикнати да користи нешто како gedit 42 00:02:55,670 --> 00:02:58,160 или што и во внатрешноста на апаратот. 43 00:02:58,160 --> 00:03:01,830 Вие нема да го имаат тоа на ФАС серверот. 44 00:03:01,830 --> 00:03:04,110 Сето тоа е само ќе биде оваа текстуална интерфејс. 45 00:03:04,110 --> 00:03:09,180 Така што би можеле ниту една, обидете се да дознаете текст едитор дека тие немаат. 46 00:03:09,180 --> 00:03:12,130 Тие имаат Нано. 47 00:03:12,130 --> 00:03:14,990 Нано обично е прилично лесен за употреба. 48 00:03:14,990 --> 00:03:19,470 Можете да го користите вашиот стрели и напишете нормално. 49 00:03:19,470 --> 00:03:21,250 Значи тоа не е тешко. 50 00:03:21,250 --> 00:03:24,720 Ако сакате да добиете навистина фенси можете да го користите Emacs, 51 00:03:24,720 --> 00:03:29,850 што јас веројатно не треба да се отвори, бидејќи јас дури и не знаат како да ја затворам Emacs. 52 00:03:29,850 --> 00:03:32,760 Контрола X, контрола Ц? Да. 53 00:03:32,760 --> 00:03:35,310 Или можете да го користите Vim, што е она што јас го користам. 54 00:03:35,310 --> 00:03:37,800 И така тие се вашите опции. 55 00:03:37,800 --> 00:03:43,830 Ако не сакате да го направите тоа, можете исто така, ако се погледне на manual.cs50.net-- 56 00:03:43,830 --> 00:03:45,410 О. 57 00:03:45,410 --> 00:03:49,920 На PC, можете да SSH користење на кит, 58 00:03:49,920 --> 00:03:51,940 кои ви се случува да мора да преземете одделно. 59 00:03:51,940 --> 00:03:55,460 На Mac, можете да само стандардно приклучок или може да го симнете iTerm2, 60 00:03:55,460 --> 00:03:58,490 кој е како убав, фенси терминал. 61 00:03:58,490 --> 00:04:03,780 Ако одите на manual.cs50.net ќе видите линк до Notepad + +, 62 00:04:03,780 --> 00:04:07,120 што е она што можете да го користите на PC. 63 00:04:07,120 --> 00:04:13,340 Тоа ви овозможува да SFTP од Notepad + +, што е основа на SSH. 64 00:04:13,340 --> 00:04:17,750 Што ова ќе ви овозможи да направите е да ги уредувате своите датотеки на локално ниво, 65 00:04:17,750 --> 00:04:20,670 а потоа кога ќе сакате да ги зачувате, тоа ќе заштедите за nice.fas, 66 00:04:20,670 --> 00:04:23,670 каде што можете да ги извршувате. 67 00:04:23,670 --> 00:04:26,880 И еквивалент на Mac ќе биде TextWrangler. 68 00:04:26,880 --> 00:04:28,760 Па што ви овозможува да го прават истото. 69 00:04:28,760 --> 00:04:32,800 Тоа ви овозможува да уредувате датотеки локално и спаси ги nice.fas, 70 00:04:32,800 --> 00:04:35,730 каде што можете да ги извршувате. 71 00:04:35,730 --> 00:04:40,400 Значи, ако сте некогаш залепи без струја, ќе ги имаат овие опции 72 00:04:40,400 --> 00:04:44,230 се уште го направите вашиот проблем комплети. 73 00:04:44,230 --> 00:04:48,250 На еден проблем се случува да биде дека не сте ќе имаат CS50 библиотека 74 00:04:48,250 --> 00:04:51,580 бидејќи nice.fas не по дифолт имаат тоа. 75 00:04:51,580 --> 00:04:55,970 Можете или да го преземете CS50 библиотека - 76 00:04:55,970 --> 00:04:58,470 Мислам дека не ми треба тоа во овој момент. 77 00:04:58,470 --> 00:05:03,270 Можете или да го преземете CS50 библиотека и да ја фотокопирам во текот на nice.fas, 78 00:05:03,270 --> 00:05:07,450 или Мислам дека во овој момент ние не го користат повеќе во секој случај. 79 00:05:07,450 --> 00:05:12,720 Или ако тоа го правиме, можете да за тоа време го замени со 80 00:05:12,720 --> 00:05:18,480 имплементации на функциите во CS50 библиотека во секој случај. 81 00:05:18,480 --> 00:05:21,370 Така што не треба да биде дека голем дел од ограничување. 82 00:05:21,370 --> 00:05:23,710 И тоа е тоа. 83 00:05:26,460 --> 00:05:29,820 >> Јас ќе се вратам на апаратот сега, ние ќе направиме се што е во уредот. 84 00:05:29,820 --> 00:05:37,510 Гледајќи нашата секција на прашања, на почетокот, како што реков во мојот мејл, 85 00:05:37,510 --> 00:05:43,620 ние треба да зборуваме за еден краток што требаше да се види. 86 00:05:43,620 --> 00:05:51,980 Имаме пренасочува & цевки и овие три прашања. 87 00:05:51,980 --> 00:05:56,070 >> Кој поток се функции како printf пишуваат по дифолт? 88 00:05:56,070 --> 00:05:59,130 Значи поток. Што е поток? 89 00:06:06,520 --> 00:06:15,100 А поток е во основа како тоа е само некои - 90 00:06:15,100 --> 00:06:21,450 Тоа не е дури извор на 1S и 0-ти. 91 00:06:21,450 --> 00:06:24,920 Потокот тоа барајќи тука е стандарден излез. 92 00:06:24,920 --> 00:06:27,250 И така стандарден излез е поток што кога ќе пишувам за тоа, 93 00:06:27,250 --> 00:06:30,940 се појавува на екранот. 94 00:06:30,940 --> 00:06:36,860 Стандарден излез, со поток, тоа значи дека само напиши 1S и 0-ти на него, 95 00:06:36,860 --> 00:06:40,220 и на другиот крај на стандарден излез едноставно чита од тој поток. 96 00:06:40,220 --> 00:06:43,540 Тоа е само низа од 1S и 0-ти. 97 00:06:43,540 --> 00:06:45,570 Можете да пишете на текови или можете да прочитате од потоци 98 00:06:45,570 --> 00:06:47,950 зависност од она што поток навистина е. 99 00:06:47,950 --> 00:06:52,800 Другите две стандардно потоци се стандардни и стандардна грешка. 100 00:06:52,800 --> 00:06:57,540 Стандард во е секогаш кога ќе се GetString, тоа е на чекање за вас да го внесете нешта. 101 00:06:57,540 --> 00:07:01,570 Така што на чекање за вас, тоа е всушност чека стандард во, 102 00:07:01,570 --> 00:07:04,880 што е навистина она што го добивате кога ќе напишете на тастатурата. 103 00:07:04,880 --> 00:07:07,530 Ти си пишувате во стандард внатре 104 00:07:07,530 --> 00:07:10,050 Стандардна грешка е во основа еквивалентни на стандарден излез, 105 00:07:10,050 --> 00:07:13,280 но тоа е специјализирана во тоа што кога ќе се печати стандардна грешка, 106 00:07:13,280 --> 00:07:16,770 си требал само да печати грешка пораки дека 107 00:07:16,770 --> 00:07:20,200 па можете да се разликува помеѓу обичните пораки печатени на екранот 108 00:07:20,200 --> 00:07:24,560 наспроти грешка пораки во зависност од тоа дали тие отиде до стандарден излез или стандардна грешка. 109 00:07:24,560 --> 00:07:28,660 Додадени фајлови: премногу. 110 00:07:28,660 --> 00:07:32,440 Стандарден излез, стандардна во, и стандардна грешка се само посебни потоци, 111 00:07:32,440 --> 00:07:36,810 но, навистина било која датотека, кога ќе отворите датотека, станува поток од бајти 112 00:07:36,810 --> 00:07:40,740 каде што само може да се прочита од таа струја. 113 00:07:40,740 --> 00:07:47,770 Вие, во најголем дел, само да се сетам на датотека како поток од бајти. 114 00:07:47,770 --> 00:07:51,190 Значи она што струи тие пишуваат по дифолт? Стандарден излез. 115 00:07:51,190 --> 00:07:56,980 >> Која е разликата помеѓу> и >>? 116 00:07:58,140 --> 00:08:03,710 Дали некој се види на видео однапред? Во ред. 117 00:08:03,710 --> 00:08:10,960 > Ќе биде како ви се пренасочува во датотеки, 118 00:08:10,960 --> 00:08:15,240 и >> е, исто така, ќе пренасочи излез во датотеки, 119 00:08:15,240 --> 00:08:17,820 но тоа е наместо случува да додадете на датотека. 120 00:08:17,820 --> 00:08:23,430 На пример, да речеме јас се случи да имаат речник токму тука, 121 00:08:23,430 --> 00:08:27,020 и само работи во внатрешноста на речник е мачка, мачка, куче, риба, куче. 122 00:08:27,020 --> 00:08:31,530 Една наредба што треба на командната линија е мачка, 123 00:08:31,530 --> 00:08:34,539 што е само ќе печати она што е во датотека. 124 00:08:34,539 --> 00:08:40,679 Значи, кога велам мачка речник, тоа нема да се печати мачка, мачка, куче, риба, куче. Тоа е се мачка прави. 125 00:08:40,679 --> 00:08:46,280 Тоа значи дека печатени до стандарден излез мачка, мачка, куче, риба, куче. 126 00:08:46,280 --> 00:08:53,240 Ако јас наместо сакате да го пренасочи дека во датотека, можам да користам> и пренасочување до она што датотеката е. 127 00:08:53,240 --> 00:08:56,460 Ќе му се јавам на датотеката датотека. 128 00:08:56,460 --> 00:09:00,320 Па сега ако јас ls, јас ќе видам имам нов фајл наречен датотека. 129 00:09:00,320 --> 00:09:05,700 И ако ја отвори, тоа се случува да имаат токму она мачка стави на командната линија. 130 00:09:05,700 --> 00:09:11,040 Па сега, ако го направам тоа повторно, тогаш тоа ќе се пренасочи на излез во датотека, 131 00:09:11,040 --> 00:09:13,930 и јас одам да имаат ист точната нешто. 132 00:09:13,930 --> 00:09:17,910 Значи технички, тоа целосно overrode она што го имавме. 133 00:09:17,910 --> 00:09:22,970 И ние ќе видиме ќе се промени речник, го извадив куче. 134 00:09:22,970 --> 00:09:29,980 Сега ако ние мачка речник во датотека еднаш, ние ќе имаме нова верзија со куче отстранети. 135 00:09:29,980 --> 00:09:32,400 Така што целосно го надминува. 136 00:09:32,400 --> 00:09:36,640 Наместо тоа, ако ние ги користиме >>, тоа се случува да додадете датотека. 137 00:09:36,640 --> 00:09:40,860 Сега, отворање на датотека, можеме да видиме ние имаме само истото печатени двапати 138 00:09:40,860 --> 00:09:44,920 поради тоа што беше таму еднаш, тогаш во прилог на оригиналот. 139 00:09:44,920 --> 00:09:48,130 Значи тоа е она> и >> направи. 140 00:09:48,130 --> 00:09:50,580 Дали следниот прашам - Тоа не прашува за тоа. 141 00:09:50,580 --> 00:09:59,050 >> Другиот што го имаме е <, што ако> пренесувања стандарден излез, 142 00:09:59,050 --> 00:10:01,970 <Ќе биде пренасочување стандард внатре 143 00:10:01,970 --> 00:10:12,050 Ајде да видиме дали имаме еден пример. 144 00:10:14,750 --> 00:10:16,930 Јас можам да пишувам еден вистински брз. 145 00:10:17,870 --> 00:10:25,700 Да го земеме некоја датотека, hello.c. 146 00:10:56,060 --> 00:10:59,070 Релативно јасна датотека. 147 00:10:59,070 --> 00:11:03,570 Јас сум само добивање на стринг, а потоа печати "Здраво" без оглед на стринг Јас само влезе беше. 148 00:11:03,570 --> 00:11:07,990 Така осигурајте се Здраво и тогаш. / Здраво. 149 00:11:07,990 --> 00:11:10,720 Сега е ме прашува да внесете нешто, 150 00:11:10,720 --> 00:11:15,070 што значи дека чека на работи кои треба да се влезе во стандард внатре 151 00:11:15,070 --> 00:11:20,450 Па влезат она што го сакам во стандарден внатре Ние сме само ќе кажам здраво, Роб! 152 00:11:20,450 --> 00:11:23,310 Тогаш тоа е печатење на стандарден излез Здраво, Роб! 153 00:11:23,310 --> 00:11:28,860 Ако го направам. / Здраво и тогаш пренасочување, 154 00:11:30,740 --> 00:11:34,310 за сега може само да се пренасочи од датотека. 155 00:11:34,310 --> 00:11:41,720 Значи, ако јас се стави во некои датотеки, TXT, и да го ставам Роб, 156 00:11:41,720 --> 00:11:52,300 ако јас се кандидира здраво, а потоа се сврти txt датотеката во. / здраво, тоа се случува да се каже Здраво, Роб! веднаш. 157 00:11:52,300 --> 00:11:57,160 Кога за прв пат добива GetString и чека на стандард во, 158 00:11:57,160 --> 00:12:01,730 стандард во веќе не чекаат на тастатурата за податоци да се внесе. 159 00:12:01,730 --> 00:12:05,980 Наместо тоа, ние сме пренасочени стандард во да го прочита од txt датотеката. 160 00:12:05,980 --> 00:12:10,290 И така тоа се случува да прочитам од датотеката txt, што е само линија Роб, 161 00:12:10,290 --> 00:12:13,380 а потоа тоа се случува да се печати Здраво, Роб! 162 00:12:13,380 --> 00:12:18,180 И ако сакав, јас исто така може да го направи. / Здраво 00:12:21,500 и тогаш стандард дека тоа е печатење, кој е Здраво, Роб!, 164 00:12:21,500 --> 00:12:24,700 Јас може да се пренасочи дека во свои датотека. 165 00:12:24,700 --> 00:12:29,790 Јас само ќе се јавите на датотека Здраво - не, јас не ќе се, затоа што тоа е извршна - txt2. 166 00:12:29,790 --> 00:12:40,150 Сега, txt2 се случува да имаат излез на. / Здраво 00:12:43,520 >> Прашања? 168 00:12:45,900 --> 00:12:49,090 >> Во ред. Па тогаш тука имаме гасоводот. 169 00:12:49,090 --> 00:12:53,510 Цевки се последните единица на редирекција. 170 00:12:53,510 --> 00:12:58,750 >> О. Претпоставувам дека уште една единица на пренасочување е ако наместо> правиш 2>, 171 00:12:58,750 --> 00:13:01,070 тоа е пренасочува стандардна грешка. 172 00:13:01,070 --> 00:13:06,280 Па ако нешто отиде во стандардна грешка, тоа не би се стави во txt2. 173 00:13:06,280 --> 00:13:12,480 Но забележите ако го направам 2>, тогаш тоа е уште печатење Здраво, Роб! на командната линија 174 00:13:12,480 --> 00:13:18,600 бидејќи јас сум само пренасочува стандардна грешка, не сум пренасочува стандарден излез. 175 00:13:18,600 --> 00:13:22,210 Стандардна грешка и стандарден излез се различни. 176 00:13:24,210 --> 00:13:27,080 Ако сакаше да всушност пишува за стандардна грешка, 177 00:13:27,080 --> 00:13:35,080 тогаш би можел да ја промените оваа да биде fprintf до stderr. 178 00:13:35,080 --> 00:13:37,850 Значи printf, по дифолт, отпечатоци до стандарден излез. 179 00:13:37,850 --> 00:13:41,720 Ако сакам да се печати стандардна грешка рачно, тогаш треба да се користи fprintf 180 00:13:41,720 --> 00:13:45,010 и да го одредите она што сакам да се печати. 181 00:13:45,010 --> 00:13:49,720 Ако наместо тоа го направив fprintf stdout, тогаш тоа е во основа еквивалентни на printf. 182 00:13:49,720 --> 00:13:55,530 Но fprintf да стандардна грешка. 183 00:13:57,790 --> 00:14:03,650 Па сега, ако јас пренасочи ова во txt2, Здраво, Роб! се уште добивање испечатени на командната линија 184 00:14:03,650 --> 00:14:08,270 бидејќи тоа е добивање печатени стандардна грешка и јас сум само пренасочува стандарден излез. 185 00:14:08,270 --> 00:14:16,420 Ако јас сега пренасочи стандардна грешка, сега тоа не се отпечатени, а txt2 ќе биде Здраво, Роб! 186 00:14:16,420 --> 00:14:21,910 Па сега, можете да печатите вашиот вистински грешки стандардна грешка 187 00:14:21,910 --> 00:14:24,720 и печатење на вашите редовни пораки до стандарден излез. 188 00:14:24,720 --> 00:14:31,420 И така, кога ќе ја стартувате вашата програма, можете да го стартувате како. / Здраво овој тип со 2> 189 00:14:31,420 --> 00:14:33,800 така што вашата програма ќе одвива нормално, 190 00:14:33,800 --> 00:14:38,400 но ниедна грешка пораки кои ги добивате може да се провери подоцна во вашата грешка најавите, 191 00:14:38,400 --> 00:14:44,500 па грешки, и потоа да се погледне подоцна и вашите грешки датотеката да има никакви грешки што се случило. 192 00:14:45,200 --> 00:14:47,540 >> Прашања? 193 00:14:47,540 --> 00:14:58,070 >> Последната е цевката, што можете да замислите како преземање на стандарден излез од една команда 194 00:14:58,070 --> 00:15:01,210 и што го прави стандард во на следниот команда. 195 00:15:01,210 --> 00:15:05,570 Пример тука е ехо е командната линија работа 196 00:15:05,570 --> 00:15:11,840 што е само ќе ехо она што го стави како свој аргумент. Јас не ќе се стави цитати. 197 00:15:11,840 --> 00:15:16,150 Ехо бла, бла, бла е само ќе печати бла, бла, бла. 198 00:15:16,150 --> 00:15:20,600 Пред тоа, кога реков дека мораше да се стави Роб во txt датотеката 199 00:15:20,600 --> 00:15:28,830 бидејќи јас само може да се пренасочи txt датотеки, наместо тоа, / ако ехо Rob 200 00:15:28,830 --> 00:15:35,520 а потоа цевка во. / здраво, кои, исто така, ќе го стори истото тип на работа. 201 00:15:35,520 --> 00:15:39,160 Ова е преземање на излезот од оваа команда, ехо Роб, 202 00:15:39,160 --> 00:15:43,610 и го користи како влез за. / здраво. 203 00:15:44,790 --> 00:15:49,560 Можете да мислите на тоа како првиот пренасочи ехо Роб во датотека 204 00:15:49,560 --> 00:15:54,160 а потоа влез во. / здраво таа датотека која беше само outputted. 205 00:15:54,160 --> 00:15:57,850 Но, потребно е на привремена датотека од слика. 206 00:16:01,890 --> 00:16:04,460 >> Прашања за тоа? 207 00:16:04,460 --> 00:16:07,150 >> Следното прашање се случува да се вклучи тоа. 208 00:16:07,150 --> 00:16:15,310 Што гасоводот можете да го користите да се најде бројот на уникатни имиња во датотека наречена names.txt? 209 00:16:15,310 --> 00:16:24,160 Команди ние ќе сакате да го користите овде се единствени, така Uniq, а потоа тоалет. 210 00:16:24,160 --> 00:16:28,840 Можете да го направите човек Uniq да всушност се погледне во она што го прави, 211 00:16:28,840 --> 00:16:34,840 и тоа само ќе ги филтрираат соседните појавување линии од влезот. 212 00:16:34,840 --> 00:16:40,690 И човекот тоалет се случува да се печати линија, збор, и бајт точки за секоја датотека. 213 00:16:40,690 --> 00:16:43,760 А последната ние ќе сакате да го користите е вид, 214 00:16:43,760 --> 00:16:47,410 кој се случува само сортирање линии на txt датотеката. 215 00:16:47,410 --> 00:16:58,080 Ако можам да направам некои txt датотеката, names.txt, а тоа е Роб, Томи, Јосиф, Томи, Јосиф, RJ, Роб, 216 00:16:58,080 --> 00:17:03,910 она што сакам да го направите тука е да се најде бројот на уникатни имиња во оваа датотека. 217 00:17:03,910 --> 00:17:08,750 Значи она што е одговорот треба да биде? >> [Студент] 4. >> Да. 218 00:17:08,750 --> 00:17:13,780 Тоа треба да биде 4 од Роб, Томи, Јосиф, RJ се само уникатен имиња во оваа датотека. 219 00:17:13,780 --> 00:17:20,180 Првиот чекор, ако јас само го прават збор брои на names.txt, 220 00:17:20,180 --> 00:17:24,290 ова е, всушност, ми кажуваше се. 221 00:17:24,290 --> 00:17:32,560 Ова е, всушност, печатење - Ајде да видиме, човек WC - новите редови, зборови, и бајт брои. 222 00:17:32,560 --> 00:17:38,270 Ако јас само се грижат за линии, тогаш само може да го направи WC-L names.txt. 223 00:17:41,730 --> 00:17:44,300 Значи тоа е чекор 1. 224 00:17:44,300 --> 00:17:50,510 Но, јас не сакам да names.txt WC-L, бидејќи names.txt само ги содржи сите имиња, 225 00:17:50,510 --> 00:17:54,170 и сакам да ги филтрираат сите не-уникатен оние. 226 00:17:54,170 --> 00:18:01,200 Значи, ако јас не Uniq names.txt, тоа сосема не ми даде она што го сакате 227 00:18:01,200 --> 00:18:03,760 бидејќи дупликат имиња се уште се таму. 228 00:18:03,760 --> 00:18:07,690 Зошто е тоа така? Зошто не Uniq прави она што го сакате? 229 00:18:07,690 --> 00:18:10,500 [Студент] дупликати не се [недоловим] >> Да. 230 00:18:10,500 --> 00:18:16,370 Запомни човекот страница за Uniq вели филтер соседните појавување линии. 231 00:18:16,370 --> 00:18:19,680 Тие не се во непосредна близина, така што не ќе ги филтрира. 232 00:18:19,680 --> 00:18:31,100 Ако јас сортирање нив прво, вид names.txt се случува да се стави сите дупликат линии заедно. 233 00:18:31,100 --> 00:18:34,450 Па сега вид names.txt е тоа. 234 00:18:34,450 --> 00:18:40,550 Одам да сакате да го користите дека влезот Uniq, која е | Uniq. 235 00:18:40,550 --> 00:18:43,390 Тоа ми дава Јосиф, RJ, Роб, Томи, 236 00:18:43,390 --> 00:18:49,260 и јас сакам да го користат како влез на WC-L, 237 00:18:49,260 --> 00:18:52,740 кој ќе ми даде 4. 238 00:18:52,740 --> 00:18:56,930 Како што се вели овде, она гасоводот можете да го користите? 239 00:18:56,930 --> 00:19:01,390 Можете да направите многу нешта, како употреба на серија на команди 240 00:19:01,390 --> 00:19:05,130 каде што имате потреба при користење на излез од една команда како влез во следната команда. 241 00:19:05,130 --> 00:19:08,780 Можете да направите многу работи, многу умен нешта. 242 00:19:08,780 --> 00:19:11,440 >> Прашања? 243 00:19:12,910 --> 00:19:14,600 Во ред. 244 00:19:14,600 --> 00:19:17,880 Тоа е тоа за цевки и редирекција. 245 00:19:18,370 --> 00:19:24,090 >> Сега ние одиме на вистинските нешта, кодирање нешта. 246 00:19:24,090 --> 00:19:29,100 Внатрешноста на овој PDF, ќе видите оваа команда, 247 00:19:29,100 --> 00:19:32,950 и ќе сакате да ја извршите оваа команда во Вашиот уред. 248 00:19:36,240 --> 00:19:42,250 wget е команда за само добивање на нешто од интернет, во основа, 249 00:19:42,250 --> 00:19:45,180 па wget и тоа рачно. 250 00:19:45,180 --> 00:19:49,110 Ако отиде во овој URL во вашиот прелистувач, тоа ќе преземете таа датотека. 251 00:19:49,110 --> 00:19:52,510 Јас само кликнал на него, па затоа преземена датотеката за мене. 252 00:19:52,510 --> 00:19:55,650 Но пишувањето wget на тоа нешто внатрешноста на терминал 253 00:19:55,650 --> 00:19:58,620 е само ќе го преземете во вашиот терминал. 254 00:19:58,620 --> 00:20:02,750 Имам section5.zip, и ќе сакате да го отпакувате section5.zip, 255 00:20:02,750 --> 00:20:06,520 која ќе ви даде папка наречена section5, 256 00:20:06,520 --> 00:20:11,550 која се случува да имаат сите датотеки што ќе треба да се користи денес во него. 257 00:20:33,380 --> 00:20:37,710 Како имиња на датотеки овие програми 'сугерира, тие се малку кабриолет, 258 00:20:37,710 --> 00:20:40,990 па вашата мисија е да дознаам зошто користење gdb. 259 00:20:40,990 --> 00:20:44,560 Не секој ги симнат / знаат како да се натераат симнат 260 00:20:44,560 --> 00:20:47,480 во нивните апаратот? Во ред. 261 00:20:47,480 --> 00:20:56,400 >> Вклучување ./buggy1, ќе каже Сегментација на вина (јадро фрлени) 262 00:20:56,400 --> 00:21:00,500 кои во секое време ќе добие segfault, тоа е лоша работа. 263 00:21:00,500 --> 00:21:03,810 Под кои околности што ќе добие segfault? 264 00:21:03,810 --> 00:21:08,210 [Студент] Dereferencing е нулти покажувач. >> Да. Па тоа е еден пример. 265 00:21:08,210 --> 00:21:11,580 Dereferencing е нулти покажувачот си оди за да се добие segfault. 266 00:21:11,580 --> 00:21:16,720 Што segfault значи сте допирање меморија не треба да се допираат. 267 00:21:16,720 --> 00:21:21,350 Значи dereferencing е нулти покажувачот се допира адреса 0, 268 00:21:21,350 --> 00:21:28,060 и во основа, сите компјутери во денешно време се каже дека адресата 0 е меморија не треба да се допираат. 269 00:21:28,060 --> 00:21:31,920 Па затоа dereferencing е нулти покажувачот резултати во segfault. 270 00:21:31,920 --> 00:21:37,210 Кога ќе се случи да не се иницијализира покажувачот, тогаш тоа има ѓубре вредност, 271 00:21:37,210 --> 00:21:41,520 и така, кога ќе се обидат да Dereference тоа, во сите веројатноста сте допирање меморија 272 00:21:41,520 --> 00:21:43,540 тоа е во средината на никаде. 273 00:21:43,540 --> 00:21:45,650 Ако се случи да добиете среќа и ѓубре вредност 274 00:21:45,650 --> 00:21:48,440 се случи да се укаже некаде на магацинот или нешто, 275 00:21:48,440 --> 00:21:50,820 тогаш кога ќе Dereference дека покажувач кој не сте го иницијализира, 276 00:21:50,820 --> 00:21:52,730 ништо нема да тргне наопаку. 277 00:21:52,730 --> 00:21:55,480 Но, ако тоа е што укажува на, да речеме, некаде помеѓу магацинот и грамада, 278 00:21:55,480 --> 00:21:59,850 или тоа е покажувајќи само за некаде дека не е користена од страна на вашата програма, сепак, 279 00:21:59,850 --> 00:22:02,240 тогаш сте допирање меморија не треба да се допира и segfault. 280 00:22:02,240 --> 00:22:06,370 Кога пишувате рекурзивен функција и recurses премногу пати 281 00:22:06,370 --> 00:22:08,720 и вашиот магацинот расте премногу големи и магацинот се судира во нештата 282 00:22:08,720 --> 00:22:12,270 дека не треба да се судир со, ти си допирање меморија не треба да се допира, 283 00:22:12,270 --> 00:22:14,810 па segfault. 284 00:22:14,810 --> 00:22:17,010 Тоа е она што segfault е. 285 00:22:17,010 --> 00:22:21,810 >> Тоа е, исто така, од истата причина дека ако имате низа како - 286 00:22:21,810 --> 00:22:23,930 да се вратиме на претходната програма. 287 00:22:23,930 --> 00:22:28,530 Во hello.c--I'm само случува да се направи нешто друго. 288 00:22:28,530 --> 00:22:33,770 char * s = "Здраво Светот!"; 289 00:22:33,770 --> 00:22:42,310 Ако јас го користам * S = нешто или е [0] = 'X'; 290 00:22:42,310 --> 00:22:47,290 така бидете Здраво,. / здраво, зошто тоа segfault? 291 00:22:48,410 --> 00:22:51,250 Зошто оваа segfault? 292 00:22:55,660 --> 00:22:57,890 Она што би очекувале да се случи? 293 00:22:57,890 --> 00:23:06,640 Ако сум го правела printf ("% s \ n", s), што би очекувале да бидат испечатени? 294 00:23:06,640 --> 00:23:09,930 [Студент] X здраво. >> Да. 295 00:23:09,930 --> 00:23:15,140 Проблемот е што кога ќе се изјасни за низа вака, 296 00:23:15,140 --> 00:23:18,190 s е показател дека се случува да одат на магацинот, 297 00:23:18,190 --> 00:23:25,880 и она што е се укажува на е овој стринг кој е содржан во read-only меморија. 298 00:23:25,880 --> 00:23:30,560 Па само со името, само за читање меморија, треба да добиете идеја 299 00:23:30,560 --> 00:23:33,010 дека ако се обиде да го промени она што е во read-only меморија, 300 00:23:33,010 --> 00:23:36,670 правиш нешто што не треба да се прави со меморија и segfault. 301 00:23:36,670 --> 00:23:45,360 Ова е всушност голема разлика меѓу char * s и знак на []. 302 00:23:45,360 --> 00:23:48,790 Значи знак на [], сега оваа низа ќе биде ставен на магацинот, 303 00:23:48,790 --> 00:23:53,960 и магацинот не е само за читање, што значи дека тоа треба да работат совршено добро. 304 00:23:55,500 --> 00:23:57,370 И тоа го прави. 305 00:23:57,370 --> 00:24:06,250 Запомнете дека кога правам char * s = "Здраво Светот!", А самата е на магацинот 306 00:24:06,250 --> 00:24:10,390 но и укажува на друго место, и дека некаде на друго место се случува да биде само за читање. 307 00:24:10,390 --> 00:24:15,640 Но знак на [] е само нешто на магацинот. 308 00:24:17,560 --> 00:24:21,760 Значи тоа е уште еден пример на segfault случува. 309 00:24:21,760 --> 00:24:27,820 >> Видовме дека ./buggy1 резултираше со segfault. 310 00:24:27,820 --> 00:24:31,810 Во теорија, вие не треба да се погледне во buggy1.c веднаш. 311 00:24:31,810 --> 00:24:35,170 Наместо тоа, ние ќе се погледне во него преку gdb. 312 00:24:35,170 --> 00:24:37,750 Забележете дека кога ќе добие Сегментација на вина (јадро фрлени) 313 00:24:37,750 --> 00:24:40,850 ќе добиете оваа датотека овде наречен јадро. 314 00:24:40,850 --> 00:24:45,200 Ако ние ls-l, ќе видиме дека јадрото е обично прилично голема датотека. 315 00:24:45,200 --> 00:24:51,580 Ова е број на бајти на датотека, па тоа изгледа како да е 250-нешто килобајти. 316 00:24:51,580 --> 00:24:56,120 Причината за ова е тоа што јадрото депонијата всушност е 317 00:24:56,120 --> 00:25:01,410 е кога вашата програма се урна, состојбата на меморијата на вашата програма 318 00:25:01,410 --> 00:25:05,230 само добива копирани и атипичен во оваа датотека. 319 00:25:05,230 --> 00:25:07,270 Станува фрлени во таа датотека. 320 00:25:07,270 --> 00:25:13,060 Оваа програма, а тоа е водење, се случи да имаат меморија од околу 250 килобајти, 321 00:25:13,060 --> 00:25:17,040 и така тоа е она што влегов фрлена во оваа датотека. 322 00:25:17,040 --> 00:25:23,630 Сега можете да се погледне во таа датотека ако правиме gdb buggy1 јадро. 323 00:25:23,630 --> 00:25:30,130 Ние само може да го направи gdb buggy1, а тоа само ќе ја стартувате gdb редовно, 324 00:25:30,130 --> 00:25:33,800 користење buggy1 како свој влезна датотека. 325 00:25:33,800 --> 00:25:38,260 Но, ако не gdb buggy1 јадро, тогаш тоа е конкретно ќе започнат gdb 326 00:25:38,260 --> 00:25:40,330 од страна гледајќи во тоа основни датотека. 327 00:25:40,330 --> 00:25:45,560 И сакаш да кажеш buggy1 средства gdb знае дека тоа основни датотека доаѓа од buggy1 програма. 328 00:25:45,560 --> 00:25:49,580 Значи gdb buggy1 јадро се случува веднаш да ни донесе 329 00:25:49,580 --> 00:25:52,060 каде на програмата се случи да се прекине. 330 00:25:57,720 --> 00:26:02,340 Гледаме тука програма прекинат со 11 сигнал, Сегментација на вина. 331 00:26:02,340 --> 00:26:10,110 Ние се случи за да ја видите линија на собранието, која, најверојатно, не е многу корисна. 332 00:26:10,110 --> 00:26:15,360 Но, ако го напишете БТ или трагата што ќе биде во функција 333 00:26:15,360 --> 00:26:19,430 што ни дава листа на нашите сегашни магацинот рамки. 334 00:26:19,430 --> 00:26:23,150 Па трагата. Изгледа ние само две магацинот рамки. 335 00:26:23,150 --> 00:26:26,310 Првиот е нашата главна магацинот рамка, 336 00:26:26,310 --> 00:26:29,810 а втората е на магацинот рамка за оваа функција што се случи да биде во, 337 00:26:29,810 --> 00:26:34,440 кој изгледа како имаме само собранието код за. 338 00:26:34,440 --> 00:26:38,050 Значи, да се вратиме во нашата главна функција, 339 00:26:38,050 --> 00:26:42,300 и да направиме што можеме да направиме рамка 1, и мислам дека ние исто така може да го направи надолу, 340 00:26:42,300 --> 00:26:45,160 но јас речиси никогаш не се направи надолу - или нагоре. Да. 341 00:26:45,160 --> 00:26:50,710 Нагоре и надолу. До носи до една магацинот рамка, долу носи надолу оџак рамка. 342 00:26:50,710 --> 00:26:53,240 Имам навика да не ја користат таа. 343 00:26:53,240 --> 00:26:59,120 Јас само специјално велат рамка 1, кој се оди на рамка етикетирани 1. 344 00:26:59,120 --> 00:27:01,750 Рамка 1 ќе нè внесе во главниот магацинот рамка, 345 00:27:01,750 --> 00:27:05,570 и вели дека токму тука на линија на кодот ние се случи да биде. 346 00:27:05,570 --> 00:27:07,950 Ако сакавме уште неколку линии на код, можеме да кажеме листа, 347 00:27:07,950 --> 00:27:11,280 и тоа ќе ни даде на сите линии на код околу неа. 348 00:27:11,280 --> 00:27:13,360 Линијата ние segfaulted на е 6: 349 00:27:13,360 --> 00:27:17,360 ако (strcmp ("CS50 карпи", avg [1]) == 0). 350 00:27:17,360 --> 00:27:24,130 Ако тоа не е очигледно, сепак, може да го добие директно од тука само од страна на размислување зошто тоа segfaulted. 351 00:27:24,130 --> 00:27:28,800 Но, ние може да го земе еден чекор понатаму и велат: "Зошто би avg [1] segfault?" 352 00:27:28,800 --> 00:27:38,830 Печати ајде avg [1], и тоа изгледа како тоа е 0x0, кој е нула покажувачот. 353 00:27:38,830 --> 00:27:44,750 Ние сме strcmping CS50 карпи и нула, и така тоа ќе segfault. 354 00:27:44,750 --> 00:27:48,280 И зошто е avg [1] нула? 355 00:27:48,640 --> 00:27:51,280 [Студент] Бидејќи ние не го даде каква било командната линија аргументи. 356 00:27:51,280 --> 00:27:53,390 Да. Ние не го даде каква било командната линија аргументи. 357 00:27:53,390 --> 00:27:58,460 Значи ./buggy1 е само ќе треба avg [0] се ./buggy1. 358 00:27:58,460 --> 00:28:02,100 Тоа нема да имаат avg [1], па тоа ќе segfault. 359 00:28:02,100 --> 00:28:07,450 Но, ако, наместо тоа, јас само CS50, тоа се случува да се каже Ќе добиете D 360 00:28:07,450 --> 00:28:09,950 бидејќи тоа е она што би требало да се направи. 361 00:28:09,950 --> 00:28:15,240 Гледајќи buggy1.c, тоа би требало да се печати "Ќе добиете Д" - 362 00:28:15,240 --> 00:28:20,820 Ако avg [1] не е "CS50 карпи", "Ќе добиете Д", друго "Ти среди А!" 363 00:28:20,820 --> 00:28:25,660 Значи, ако сакаме А, ние треба ова да се споредуваат како вистински, 364 00:28:25,660 --> 00:28:28,710 што значи дека тоа се споредува со 0. 365 00:28:28,710 --> 00:28:31,100 Значи avg [1] треба да биде "CS50 карпи". 366 00:28:31,100 --> 00:28:35,660 Ако сакате да го направите тоа на командната линија, треба да користите \ да избега од простор. 367 00:28:35,660 --> 00:28:41,690 Значи CS50 \ карпи и ќе добиете А! 368 00:28:41,690 --> 00:28:44,060 Ако не го направите обратна коса црта, зошто не оваа работа? 369 00:28:44,060 --> 00:28:47,190 [Студент] Тоа е две различни аргументи. >> Да. 370 00:28:47,190 --> 00:28:52,540 Avg [1] ќе биде CS50, и avg [2] ќе биде карпи. Во ред. 371 00:28:52,540 --> 00:28:56,470 >> Сега ./buggy2 ќе segfault повторно. 372 00:28:56,470 --> 00:29:01,880 Наместо отворање со неговото јадро датотека, ние само ќе се отвори buggy2 директно, 373 00:29:01,880 --> 00:29:05,000 па gdb buggy2. 374 00:29:05,000 --> 00:29:09,590 Сега ако ние едноставно се кандидира нашата програма, тогаш тоа се случува да се каже програма примениот сигналот SIGSEGV, 375 00:29:09,590 --> 00:29:15,530 која е segfault сигнал, и ова е местото каде што се случи да се случи. 376 00:29:15,530 --> 00:29:21,250 Гледајќи нашата трагата, можеме да видиме дека сме биле во функција oh_no, 377 00:29:21,250 --> 00:29:23,900 кој беше наречен од страна на функција спретнат, кој беше наречен од страна на функција binky, 378 00:29:23,900 --> 00:29:26,460 кој бил повикан од главните. 379 00:29:26,460 --> 00:29:31,680 Ние, исто така може да се види аргументите на овие функции. 380 00:29:31,680 --> 00:29:34,680 Аргументот за спретнат и binky беше 1. 381 00:29:34,680 --> 00:29:44,390 Ако ние листа на функцијата oh_no, можеме да видиме дека oh_no е само прави знак ** S = NULL; 382 00:29:44,390 --> 00:29:47,410 * Кликнете = "бум"; 383 00:29:47,410 --> 00:29:50,330 Зошто тоа ќе пропадне? 384 00:29:54,330 --> 00:29:58,380 [Студент] Вие не може Dereference на нула покажувачот? >> Да. 385 00:29:58,380 --> 00:30:06,090 Ова е само велејќи s е NULL, без оглед дали тоа се случува да биде знак **, 386 00:30:06,090 --> 00:30:12,070 кои, во зависност од тоа како ќе го толкува, тоа би можело да биде покажувач на покажувач кон низа 387 00:30:12,070 --> 00:30:15,550 или низа од стрингови. 388 00:30:15,550 --> 00:30:21,430 Тоа е е е NULL, па * s е dereferencing е нулти покажувач, 389 00:30:21,430 --> 00:30:24,800 и така ова ќе се сруши. 390 00:30:24,800 --> 00:30:27,540 Ова е една од најбрзо начини што веројатно може да segfault. 391 00:30:27,540 --> 00:30:31,300 Тоа е само за прогласување на нула покажувачот и веднаш segfaulting. 392 00:30:31,300 --> 00:30:34,570 Тоа е она што oh_no прави. 393 00:30:34,570 --> 00:30:43,400 Ако одиме до една рамка, тогаш ние ќе ја добиеме во функција она што е наречено oh_no. 394 00:30:43,400 --> 00:30:44,830 Ми треба да го направат тоа долу. 395 00:30:44,830 --> 00:30:48,610 Ако не внесете ја командата и вие само притиснете ентер, повторно, 396 00:30:48,610 --> 00:30:52,350 тоа само ќе се повторува претходниот команда која ќе истрча. 397 00:30:52,350 --> 00:30:56,610 Ние сме во рамка 1. 398 00:30:56,610 --> 00:31:04,650 Листата оваа рамка, ние гледаме тука е нашата функција. 399 00:31:04,650 --> 00:31:08,520 Можете да хит листа повторно, или можете да го направите листа 20 и тоа ќе листата повеќе. 400 00:31:08,520 --> 00:31:13,640 Функцијата спретнат вели дека ако јас е 1, тогаш одете на функцијата oh_no, 401 00:31:13,640 --> 00:31:15,960 друго оди во slinky функција. 402 00:31:15,960 --> 00:31:18,700 И знаеме i е 1 затоа што се случи за да ја видите се тука 403 00:31:18,700 --> 00:31:22,560 дека спретнат беше повикана со аргументот 1. 404 00:31:22,560 --> 00:31:27,560 Или едноставно можете да можам да печати и ќе кажам дека е 1. 405 00:31:27,560 --> 00:31:33,770 Ние сме во моментов во спретнат и ако одиме до друга рамка, знаеме дека ќе заврши во binky. 406 00:31:33,770 --> 00:31:36,600 Нагоре. Сега сме во binky. 407 00:31:36,600 --> 00:31:41,340 Листата оваа функција - листата од пред половина ме отсечени - 408 00:31:41,340 --> 00:31:52,670 тоа започна како ако јас е 0, тогаш ние ќе го наречеме oh_no, друг да го повикате спретнат. 409 00:31:52,670 --> 00:31:57,000 Ние знаеме бев 1, па затоа се нарекува спретнат. 410 00:31:57,000 --> 00:32:05,030 И сега ние сме назад во главната, а главната е само ќе биде int i = rand ()% 3; 411 00:32:05,030 --> 00:32:08,790 Тоа е само ќе ви даде случаен број кој е или 0, 1, или 2. 412 00:32:08,790 --> 00:32:12,780 Тоа се случува да се јавите binky со тој број и ќе се вратат 0. 413 00:32:12,780 --> 00:32:16,700 Гледајќи ова, 414 00:32:16,700 --> 00:32:19,880 само одење преку програмата рачно без трчање веднаш, 415 00:32:19,880 --> 00:32:25,400 ќе се постави брејк во главните, што значи дека кога ќе ја стартувате програмата 416 00:32:25,400 --> 00:32:31,020 вашата програма работи се додека не хитови брејк. 417 00:32:31,020 --> 00:32:35,450 Значи водење на програмата, ќе се кандидира и потоа ќе ја погоди главната функција и да престане да работи. 418 00:32:35,450 --> 00:32:44,700 Сега сме во внатрешноста на главниот, и чекор или следната ќе ни донесе на следната линија код. 419 00:32:44,700 --> 00:32:47,050 Можете да направите чекор или следната. 420 00:32:47,050 --> 00:32:51,800 Удирањето следниот, сега јас е поставен на rand ()% 3, па можеме да се печати вредноста на i, 421 00:32:51,800 --> 00:32:55,280 и ќе каже дека е 1. 422 00:32:55,280 --> 00:32:58,110 Сега тоа не е важно дали ние ги користиме следната или чекор. 423 00:32:58,110 --> 00:33:01,000 Претпоставувам дека тоа важно во претходната, но ние би сакале да се користи следната. 424 00:33:01,000 --> 00:33:06,000 Ако ние ги користиме чекор, ние чекор во функција, што значи поглед на вистински работа 425 00:33:06,000 --> 00:33:07,940 што се случува во внатрешноста на binky. 426 00:33:07,940 --> 00:33:10,510 Ако ние ги користиме следната, тогаш тоа значи одиме во текот на функција 427 00:33:10,510 --> 00:33:14,070 и само да одат во следната линија код во нашата главна функција. 428 00:33:14,070 --> 00:33:17,900 Токму тука на оваа линија, јас бев во која се вели Rand ()% 3; 429 00:33:17,900 --> 00:33:21,320 ако сум го правела чекор, тоа ќе оди во спроведувањето на ранд 430 00:33:21,320 --> 00:33:25,110 и се погледне во она што се случува таму, и јас би можеле да чекор преку функцијата rand. 431 00:33:25,110 --> 00:33:26,920 Но јас не се грижат за функцијата rand. 432 00:33:26,920 --> 00:33:30,190 Јас само сакам да одат во следната линија код во главната, па јас го користам следната. 433 00:33:30,190 --> 00:33:35,800 Но, сега се грижат за binky функција, па сакам да влезете во тоа. 434 00:33:35,800 --> 00:33:37,730 Сега сум во binky. 435 00:33:37,730 --> 00:33:42,040 На првата линија на код се случува да се каже ако (i == 0), земам чекор, 436 00:33:42,040 --> 00:33:44,930 можеме да видиме на крајот ќе заврши во спретнат. 437 00:33:44,930 --> 00:33:51,620 Ако ние листа нешта, можеме да видиме дека го проверуваат е i = 0. 438 00:33:51,620 --> 00:33:55,470 Не е еднаков на 0, па затоа отиде на друго состојба, 439 00:33:55,470 --> 00:33:59,540 која ќе ја повика спретнат (i). 440 00:33:59,540 --> 00:34:04,030 Може да се збунети. 441 00:34:04,030 --> 00:34:07,380 Ако само погледнете во овие линии директно, можеби мислат ако (i == 0), 442 00:34:07,380 --> 00:34:10,800 во ред, а потоа отидов чекор и сега сум во спретнат (i), 443 00:34:10,800 --> 00:34:14,120 можеби мислат дека мора да значи i = 0 или нешто. 444 00:34:14,120 --> 00:34:18,980 Не Тоа само значи дека тоа го знае тоа може да се држи директно на линија спретнат (i). 445 00:34:18,980 --> 00:34:23,300 Затоа што не е 0, следниот чекор не се случува да се стави крај на друг. 446 00:34:23,300 --> 00:34:26,239 Друго не е линија тоа се случува да застане на. 447 00:34:26,239 --> 00:34:31,570 Тоа е само случува да одам до следната линија тоа всушност може да се изврши, што е спретнат (i). 448 00:34:31,570 --> 00:34:36,090 Повлекува во спретнат (i), можеме да видиме ако (i == 1). 449 00:34:36,090 --> 00:34:42,670 Ние не знам = 1, па кога ќе чекор, знаеме ние ќе завршат во oh_no 450 00:34:42,670 --> 00:34:46,489 затоа што i = 1 повикува функција oh_no, кој можете да влезете во, 451 00:34:46,489 --> 00:34:52,969 кој ќе се постави знак ** S = до ништовни и веднаш "БУМ". 452 00:34:54,270 --> 00:34:59,690 А потоа всушност да гледа во спроведувањето на buggy2, 453 00:34:59,690 --> 00:35:04,590 ова, јас се само добивање на случаен број - 0, 1 или 2 - повик binky, 454 00:35:04,590 --> 00:35:10,610 што ако јас е 0 го нарекува oh_no, друго што го нарекува спретнат, кој доаѓа до овде. 455 00:35:10,610 --> 00:35:18,100 Ако јас е 1, повик oh_no, друг да го повикате slinky, кои доаѓаат тука, 456 00:35:18,100 --> 00:35:20,460 ако јас е 2, јавете oh_no. 457 00:35:20,460 --> 00:35:24,720 Јас дури и не мислам дека постои начин - 458 00:35:24,720 --> 00:35:30,030 Дали некој ја видите начин за правење на оваа програма која нема да segfault? 459 00:35:30,030 --> 00:35:37,530 Затоа што ако сум недостасува нешто, ако јас е 0, веднаш ќе segfault, 460 00:35:37,530 --> 00:35:41,250 друго што оди на функција која ако јас е 1 ви segfault, 461 00:35:41,250 --> 00:35:44,540 друго што оди до некоја функција каде што ако јас е 2 ти segfault. 462 00:35:44,540 --> 00:35:46,810 Значи без разлика што правиш, можете segfault. 463 00:35:46,810 --> 00:35:52,380 >> Претпоставувам еден начин на одредување на тоа ќе биде наместо да прави знак ** S = NULL, 464 00:35:52,380 --> 00:35:55,610 можете да Примерок простор за тоа стринг. 465 00:35:55,610 --> 00:36:04,230 Ние не можеше да стори Примерок (sizeof) - sizeof што? 466 00:36:09,910 --> 00:36:15,190 [Студент] (знак) * 5? >> Дали ова изгледа добро? 467 00:36:15,190 --> 00:36:21,060 Јас сум претпоставувајќи ова ќе работи ако јас всушност го имаше, но тоа не е она што јас го барам. 468 00:36:24,400 --> 00:36:32,940 Погледни го типот на пријавите. Да додадете int *, па int * x. 469 00:36:32,940 --> 00:36:35,600 Јас би го направил Примерок (sizeof (int)). 470 00:36:35,600 --> 00:36:40,490 Или ако сакав низа на 5, јас би го направил (sizeof (int) * 5); 471 00:36:40,490 --> 00:36:44,210 Што ако имам int **? 472 00:36:46,260 --> 00:36:49,140 Што би ми Примерок? 473 00:36:49,140 --> 00:36:53,510 [Студент] Големина на покажувачот. >> Да. (Sizeof (int *)); 474 00:36:53,510 --> 00:36:56,960 Истото овде. 475 00:36:56,960 --> 00:37:01,280 Сакам (sizeof (char *)); 476 00:37:06,170 --> 00:37:12,840 Ова ќе одвои простор за покажувач кој покажува кон "БУМ". 477 00:37:12,840 --> 00:37:15,330 Јас не треба да одвои простор за "бум" се 478 00:37:15,330 --> 00:37:17,210 бидејќи ова е во основа еквивалент на она што реков пред 479 00:37:17,210 --> 00:37:20,870 на char * x = "БУМ". 480 00:37:20,870 --> 00:37:27,950 "Бум" веќе постои. Тоа се случува да постои во read-only регионот на меморија. 481 00:37:27,950 --> 00:37:35,200 Но, тоа веќе постои, што значи дека оваа линија код, ако е е знак **, 482 00:37:35,200 --> 00:37:43,900 потоа * s е char * и си поставување на овој знак * да се укаже на "бум". 483 00:37:43,900 --> 00:37:50,040 Ако сакав да го копирате "бум" во с, тогаш ќе треба да одвои простор за s. 484 00:37:55,170 --> 00:38:03,900 Јас ќе сторам * S = Примерок (sizeof (знак) * 5); 485 00:38:03,900 --> 00:38:06,210 Зошто 5? 486 00:38:06,210 --> 00:38:10,860 Зошто не 4? Личи на "бум" е 4 карактери. >> [Студент] Карактерот null. 487 00:38:10,860 --> 00:38:14,580 Да. Сите ваши жици се случува да треба на нула карактер. 488 00:38:14,580 --> 00:38:23,590 Сега можам да направам нешто како strcat - Која е функцијата за копирање низа? 489 00:38:23,590 --> 00:38:28,520 [Студент] КПЈ? >> Strcpy. 490 00:38:28,520 --> 00:38:32,700 човек strcpy. 491 00:38:36,120 --> 00:38:39,590 Значи strcpy или strncpy. 492 00:38:39,590 --> 00:38:43,410 strncpy е малку побезбедни, бидејќи можете да наведете точно колку карактери, 493 00:38:43,410 --> 00:38:46,190 но тука тоа не е важно, затоа што знаеме. 494 00:38:46,190 --> 00:38:50,340 Значи strcpy и гледам во аргументите. 495 00:38:50,340 --> 00:38:53,100 Првиот аргумент е нашата дестинација. 496 00:38:53,100 --> 00:38:56,770 Вториот аргумент е нашиот извор. 497 00:38:56,770 --> 00:39:10,310 Одиме да го копирате во нашата дестинација * S покажувачот "БУМ". 498 00:39:10,310 --> 00:39:19,820 Зошто можеби ќе сакате да го направите ова со strcpy наместо само она што го имавме пред 499 00:39:19,820 --> 00:39:22,800 на * S = "бум"? 500 00:39:22,800 --> 00:39:28,630 Постои причина зошто можеби ќе сакате да го направите ова, но она што е таа причина? 501 00:39:28,630 --> 00:39:31,940 [Студент] Ако сакате да промените нешто во "БУМ". >> Да. 502 00:39:31,940 --> 00:39:37,950 Сега можам да направам нешто слично на [0] = 'X'; 503 00:39:37,950 --> 00:39:48,190 бидејќи ги упатува на куп и тој простор на грамада дека е се укажува на 504 00:39:48,190 --> 00:39:52,320 е покажувач кон повеќе простор на грамада, која е чување "БУМ". 505 00:39:52,320 --> 00:39:55,150 Значи ова копија на "бум" се складирани во грамада. 506 00:39:55,150 --> 00:39:58,780 Постојат технички две копии на "бум" во нашата програма. 507 00:39:58,780 --> 00:40:03,500 Тука е првиот што е само дадена од страна на оваа "бум" стринг константа, 508 00:40:03,500 --> 00:40:09,250 и вториот примерок на "бум", strcpy создаде копија на "бум". 509 00:40:09,250 --> 00:40:13,100 Но копија на "бум" се чуваат на куп, и грамада ти си слободен да се промени. 510 00:40:13,100 --> 00:40:17,250 Грамада не е само за читање, па тоа значи дека е [0] 511 00:40:17,250 --> 00:40:20,500 се случува да ви се промени вредноста на "бум". 512 00:40:20,500 --> 00:40:23,130 Тоа ќе ви овозможи да се променат овие карактери. 513 00:40:23,130 --> 00:40:26,640 >> Прашања? 514 00:40:27,740 --> 00:40:29,290 Во ред. 515 00:40:29,290 --> 00:40:35,500 >> Премина на buggy3, ајде gdb buggy3. 516 00:40:35,500 --> 00:40:39,840 Ние само стартувајте го ZiPhone и гледаме да добиеме segfault. 517 00:40:39,840 --> 00:40:46,550 Ако ние трагата, постојат само две функции. 518 00:40:46,550 --> 00:40:52,970 Ако одиме нагоре во нашата главна функција, можеме да видиме дека ние segfaulted во оваа линија. 519 00:40:52,970 --> 00:41:00,180 Значи само гледајќи во оваа линија, за (int линија = 0; fgets овој материјал не е еднакво на нула; 520 00:41:00,180 --> 00:41:03,770 линија + +). 521 00:41:03,770 --> 00:41:08,010 Нашите претходни рамка беше наречен _IO_fgets. 522 00:41:08,010 --> 00:41:10,720 Ќе видите дека многу со вграден во C функции, 523 00:41:10,720 --> 00:41:15,350 дека кога ќе го добиете segfault, ќе има навистина криптичната имиња на функции 524 00:41:15,350 --> 00:41:18,090 вака _IO_fgets. 525 00:41:18,090 --> 00:41:21,770 Но, тоа се случува да се однесуваат на оваа fgets повик. 526 00:41:21,770 --> 00:41:25,850 Некаде во внатрешноста тука, ние сме segfaulting. 527 00:41:25,850 --> 00:41:30,340 Ако ги погледнеме аргументите на fgets, можеме да печатиме тампон. 528 00:41:30,340 --> 00:41:41,180 Ајде да се печати како - О, не. 529 00:41:48,980 --> 00:41:51,900 Печати нема да работат токму онака како што сакате тоа да. 530 00:41:55,460 --> 00:41:58,000 Ајде да погледнеме во вистинските програма. 531 00:42:02,200 --> 00:42:09,640 Тампон е лик низа. Тоа е лик низа од 128 карактери. 532 00:42:09,640 --> 00:42:14,980 Значи, кога велам печатење тампон, тоа се случува да се печати оние 128 карактери, 533 00:42:14,980 --> 00:42:18,300 која претпоставувам дека е она што се очекува. 534 00:42:18,300 --> 00:42:21,390 Она што јас го барате е печатење на адреса на тампон, 535 00:42:21,390 --> 00:42:23,680 но тоа навистина не ми каже многу. 536 00:42:23,680 --> 00:42:30,770 Па кога ќе се случи да се каже се тука x тампон, тоа ми покажува 0xbffff090, 537 00:42:30,770 --> 00:42:38,690 кои, ако се сеќавате од претходните или некоја точка, Oxbffff има тенденција да биде оџак-носталгичната регионот. 538 00:42:38,690 --> 00:42:46,020 Магацинот има тенденција да почнеме од некаде само под 0xc000. 539 00:42:46,020 --> 00:42:51,890 Само со гледање на оваа адреса, знам дека тампон се случува на магацинот. 540 00:42:51,890 --> 00:43:04,500 Рестартирање на мојата програма, трчаат, нагоре, тампон видовме беше оваа секвенца од знаци 541 00:43:04,500 --> 00:43:06,530 кои се доста безначајна. 542 00:43:06,530 --> 00:43:12,270 Потоа печатење датотека, што значи датотека изгледа? 543 00:43:15,120 --> 00:43:17,310 [Студент] NULL. >> Да. 544 00:43:17,310 --> 00:43:22,610 Датотеката е од типот СЛИКА *, па тоа е покажувач, 545 00:43:22,610 --> 00:43:26,610 и вредноста на тоа покажувачот е нула. 546 00:43:26,610 --> 00:43:33,240 Значи fgets се случува да се обидат да го читам од таа покажувачот на индиректен начин, 547 00:43:33,240 --> 00:43:37,320 но со цел да пристапите дека покажувачот, тоа треба да Dereference неа. 548 00:43:37,320 --> 00:43:40,550 Или, со цел да пристапите она што треба да се укажува на тоа дека dereferences. 549 00:43:40,550 --> 00:43:43,810 Така, тоа е dereferencing е нулти покажувач и segfaults. 550 00:43:46,600 --> 00:43:48,730 Јас би можеле да го рестартира таму. 551 00:43:48,730 --> 00:43:52,170 Ако ние се пробие во нашиот главен момент и да ја стартувате, 552 00:43:52,170 --> 00:43:57,320 на првата линија на кодот е char * фајлот = "nonexistent.txt"; 553 00:43:57,320 --> 00:44:00,870 Тоа треба да даде прилично голема навестување за тоа зошто оваа програма не успее. 554 00:44:00,870 --> 00:44:06,080 Пишување следната ме носи до следната линија, каде што ја отворите оваа датотека, 555 00:44:06,080 --> 00:44:11,140 а потоа веднаш влезе во нашата линија, каде што некогаш јас хит следната, тоа се случува да segfault. 556 00:44:11,140 --> 00:44:16,880 Сака ли некој да фрли причина зошто ние би можеле да бидат segfaulting? 557 00:44:16,880 --> 00:44:19,130 [Студент] Датотеката не постои. >> Да. 558 00:44:19,130 --> 00:44:22,250 Ова би требало да биде навестување 559 00:44:22,250 --> 00:44:29,570 дека секогаш кога ќе се отвори датотеката што треба да се провери дека датотеката всушност постои. 560 00:44:29,570 --> 00:44:31,510 Значи тука ", nonexistent.txt"; 561 00:44:31,510 --> 00:44:34,700 Кога ќе fopen име на датотека за читање, тогаш ние треба да се каже 562 00:44:34,700 --> 00:44:45,870 ако (датотека == NULL) и да каже printf ("Датотеката не постои!" 563 00:44:45,870 --> 00:44:56,340 или - уште подобро - име на датотека); враќање 1; 564 00:44:56,340 --> 00:45:00,300 Па сега ние се провери да се види дали тоа е NULL 565 00:45:00,300 --> 00:45:03,930 пред всушност продолжува и се обидува да се прочита од таа датотека. 566 00:45:03,930 --> 00:45:08,800 Можеме да го преобразиме само да се види дека тоа работи. 567 00:45:11,020 --> 00:45:14,970 Јас се наменети да се вклучат во нова линија. 568 00:45:21,090 --> 00:45:25,290 Па сега nonexistent.txt не постои. 569 00:45:26,890 --> 00:45:30,040 Секогаш треба да проверите за овој вид на работа. 570 00:45:30,040 --> 00:45:33,870 Секогаш треба да се провери да се види дали fopen враќа NULL. 571 00:45:33,870 --> 00:45:38,170 Секогаш треба да се провери да бидете сигурни дека Примерок не се врати NULL, 572 00:45:38,170 --> 00:45:41,410 или на друго место segfault. 573 00:45:42,200 --> 00:45:45,930 >> Сега buggy4.c. 574 00:45:49,190 --> 00:45:58,440 Трчање. Јас сум Сомневајќи се ова е на чекање за влез или можеби бесконечна looping. 575 00:45:58,440 --> 00:46:01,870 Да, тоа е бесконечна looping. 576 00:46:01,870 --> 00:46:05,560 Значи buggy4. Тоа изгледа како да сме бесконечна looping. 577 00:46:05,560 --> 00:46:12,590 Ние може да се скрши на главната, работи нашата програма. 578 00:46:12,590 --> 00:46:20,180 Во gdb, додека кратенката користите е недвосмислена 579 00:46:20,180 --> 00:46:23,420 или посебни кратенки кои тие ги обезбедуваат за вас, 580 00:46:23,420 --> 00:46:29,020 тогаш можете да го користите n да се користи следната наместо да напишеш од следната целиот пат. 581 00:46:29,020 --> 00:46:33,730 И сега што сум ги погоди n еднаш, јас само може да се погоди Enter за да продолжувам да одам наредната 582 00:46:33,730 --> 00:46:36,640 наместо да ја погоди N Enter, n Enter, n Enter. 583 00:46:36,640 --> 00:46:44,630 Изгледа како да сум во некој вид на за телефонска линија која е поставување низа [i] на 0. 584 00:46:44,630 --> 00:46:50,510 Тоа изгледа како јас никогаш не сум кршење на овој за телефонска линија. 585 00:46:50,510 --> 00:46:54,780 Ако јас јас печати, па е 2, тогаш јас ќе одиме понатаму. 586 00:46:54,780 --> 00:46:59,250 Ќе јас печати, i е 3, а потоа јас ќе одам понатаму. 587 00:46:59,250 --> 00:47:05,360 Ќе ми печати и јас е 3. Потоа, печати јас, јас е 4. 588 00:47:05,360 --> 00:47:14,520 Всушност, печатење sizeof (низа), па големината на низата е 20. 589 00:47:16,310 --> 00:47:32,870 Но, изгледа дека има некои посебни gdb команда за одење додека нешто се случува. 590 00:47:32,870 --> 00:47:37,620 Тоа е како поставување на состојбата на вредноста на променливата. Но, јас не се сеќавам што е тоа. 591 00:47:37,620 --> 00:47:44,100 Значи, ако ние Продолжувам да одам - 592 00:47:44,100 --> 00:47:47,120 Што се сакаш да кажеш? Што ви донесе до? 593 00:47:47,120 --> 00:47:50,500 [Студент] се прикажува додадам - ​​>> Да. Значи прикаже можам да помогнам. 594 00:47:50,500 --> 00:47:54,530 Ако само јас се прикаже, тоа ќе се стави до тука што вредноста на i е 595 00:47:54,530 --> 00:47:56,470 па јас не треба да го испечатите секој пат. 596 00:47:56,470 --> 00:48:02,930 Ако ние само продолжувам да одам наредната, можеме да видиме 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5. 597 00:48:02,930 --> 00:48:08,530 Нешто се случува ужасно погрешен, и јас се ресетира на 0. 598 00:48:13,330 --> 00:48:22,220 Гледајќи buggy4.c, можеме да видиме сите што се случува е int низа [5]; 599 00:48:22,220 --> 00:48:26,200 за (i = 0; з <= sizeof (низа); i + +) 600 00:48:26,200 --> 00:48:28,550 низа [i] = 0; 601 00:48:28,550 --> 00:48:31,390 Што гледаме дека не е во ред овде? 602 00:48:31,390 --> 00:48:39,480 Како навестување, кога го правев на gdb buggy4 - да се скрши главната, рок - 603 00:48:39,480 --> 00:48:45,980 Јас не печати sizeof (низа) само за да видам што состојбата е местото каде што треба конечно да се пробие. 604 00:48:47,690 --> 00:48:51,100 Каде сум јас? Никако не можев да се кандидира? 605 00:48:51,100 --> 00:48:54,280 Јас не се изјасниле уште. 606 00:48:54,280 --> 00:48:58,680 Значи печати sizeof (низа) и тоа е 20, 607 00:48:58,680 --> 00:49:06,690 кој се очекува со оглед на моето низа е со големина од 5 и е на 5 броеви, 608 00:49:06,690 --> 00:49:12,410 па целата работа треба да биде 5 * sizeof (int) бајти, каде sizeof (int) има тенденција да биде 4. 609 00:49:12,410 --> 00:49:14,780 Значи sizeof (низа) е 20. 610 00:49:14,780 --> 00:49:17,420 Што ова треба да биде? 611 00:49:17,420 --> 00:49:21,720 [Студент] Поделен со sizeof (int). >> Да, / sizeof (int). 612 00:49:21,720 --> 00:49:30,630 Тоа изгледа како таму е уште еден проблем тука. Мислам дека ова само треба да биде < 613 00:49:30,630 --> 00:49:36,960 бидејќи тоа е доста секогаш <никогаш и <=. 614 00:49:36,960 --> 00:49:44,860 Сега ајде да размислиме за тоа зошто ова е всушност скршена. 615 00:49:44,860 --> 00:49:53,370 Дали некој има нагаѓања зошто бев ресетирање на 0 преку секоја повторување на јамка? 616 00:50:01,300 --> 00:50:09,350 Единственото нешто внатре од овде што се случува е дека низа [i] е поставен на 0. 617 00:50:09,350 --> 00:50:15,350 Така некако, оваа линија код предизвикува нашите int i да се постави на 0. 618 00:50:16,730 --> 00:50:23,130 [Студент] Може да биде, бидејќи тоа е највисок меморија на овој дел на i 619 00:50:23,130 --> 00:50:27,970 кога смета дека тоа е следниот елемент од низата? >> [Бауден] Да. 620 00:50:27,970 --> 00:50:33,880 Кога ние ќе по завршувањето на нашата низа, 621 00:50:33,880 --> 00:50:39,870 некако тој простор, дека ние сме највисок е највисок вредноста на i. 622 00:50:39,870 --> 00:50:48,030 И така, ако ги погледнеме buggy4, пауза главната, рок, 623 00:50:48,030 --> 00:50:53,120 ајде да испечатите адреса на i. 624 00:50:53,120 --> 00:50:57,280 Тоа изгледа како тоа е bffff124. 625 00:50:57,280 --> 00:51:03,930 Сега ајде да печати адресата на низа [0]. 110. 626 00:51:03,930 --> 00:51:06,290 Што [1]? 114. 627 00:51:06,290 --> 00:51:07,920 [2], 118. 628 00:51:07,920 --> 00:51:14,530 11c, 120. низа [5] е bfff124. 629 00:51:14,530 --> 00:51:26,990 Значи низа [5] ја има истата адреса како што, што значи дека низа [5] е i. 630 00:51:26,990 --> 00:51:30,720 Ако тие имаат иста адреса, тие се иста работа. 631 00:51:30,720 --> 00:51:38,410 Значи, кога ние во собата низа [5] на 0, ние сме јас Поставување на 0. 632 00:51:38,410 --> 00:51:46,070 И ако мислите дека за ова во поглед на магацинот, 633 00:51:46,070 --> 00:51:55,590 int i е прогласена прво, што значи дека добива некои простор на магацинот. 634 00:51:55,590 --> 00:52:04,730 Потоа низа [5] е наменет, па потоа 20 бајти се распределуваат врз оџакот. 635 00:52:04,730 --> 00:52:08,400 Па јас добива распределени, а потоа овие 20 бајти се распределени. 636 00:52:08,400 --> 00:52:11,400 Па јас се случува непосредно пред низа, 637 00:52:11,400 --> 00:52:19,230 и поради начинот на кој, како што реков минатата недела, каде што технички магацинот расте надолу, 638 00:52:19,230 --> 00:52:28,520 кога ќе индекс на низата, ние се гарантира дека 0. позиција во низа 639 00:52:28,520 --> 00:52:31,970 секогаш се случува пред првата позиција во низа. 640 00:52:31,970 --> 00:52:35,900 Ова е вид на како јас го привлече минатата недела. 641 00:52:35,900 --> 00:52:42,210 Забележете дека на дното имаме адреса 0 и на врвот имаме адреса Макс. 642 00:52:42,210 --> 00:52:44,880 Магацинот е секогаш расте надолу. 643 00:52:48,100 --> 00:52:53,500 Да речеме дека ние i распредели. 644 00:52:53,500 --> 00:52:59,680 Ние додели број I, што значи да речеме овде горе број i добива распределени. 645 00:52:59,680 --> 00:53:06,420 Тогаш ние додели нашата низа од 5 броеви, што значи дека под тоа, 646 00:53:06,420 --> 00:53:11,230 од магацинот расте надолу, оние 5 броеви се доделени. 647 00:53:11,230 --> 00:53:15,900 Но, поради начинот на низи работа, ние сме гаранција дека на првата позиција во низа 648 00:53:15,900 --> 00:53:22,260 секогаш има адреса помалку од Втората работа во низа. 649 00:53:22,260 --> 00:53:28,270 Значи низа положба 0 секогаш треба да се случи прво место во меморијата, 650 00:53:28,270 --> 00:53:30,700 додека низа позиција 1 мора да се случи после тоа 651 00:53:30,700 --> 00:53:33,310 и низа став 2 треба да се случи после тоа, 652 00:53:33,310 --> 00:53:37,900 што значи дека низа положба 0 ќе се случи некаде долу тука, 653 00:53:37,900 --> 00:53:40,690 низа позиција 1 ќе се случи над тоа 654 00:53:40,690 --> 00:53:45,530 бидејќи движат нагоре значи повисоки адреси од максималната адреса е до тука. 655 00:53:45,530 --> 00:53:50,490 Значи низа [0] долу тука, низа [1] се тука, низа [2] се тука, низа [3] се тука. 656 00:53:50,490 --> 00:53:55,620 Забележи како пред доделени целобројни јас целиот пат до тука, 657 00:53:55,620 --> 00:54:01,040 како што се движи понатаму и понатаму во нашата низа, ние сме добивање поблиску и поблиску до нашата цел број i. 658 00:54:01,040 --> 00:54:07,640 Тоа само така се случува, дека низа [5], која е една позиција надвор од нашата низа, 659 00:54:07,640 --> 00:54:13,010 е токму каде што број се случи да бидат распределени. 660 00:54:13,010 --> 00:54:16,920 Значи тоа е точка каде што се случи да биде притискање на просторот на магацинот 661 00:54:16,920 --> 00:54:21,680 кој беше наменет за број I, и ние сме поставување дека на 0. 662 00:54:21,680 --> 00:54:26,160 >> Тоа е како тоа функционира. Прашања? Да. 663 00:54:26,160 --> 00:54:30,710 [Студент] не е важно. Во ред. 664 00:54:30,710 --> 00:54:33,090 [Студент] Како да се избегнат овие вид на грешки? 665 00:54:33,090 --> 00:54:41,190 Овие вид на грешки? Не користите C како програмски јазик. 666 00:54:41,190 --> 00:54:45,840 Користете јазик кој има низа границите проверка. 667 00:54:45,840 --> 00:54:55,900 Додека сте внимателни, можете само треба да се избегне ќе изминатите границите на вашиот низа. 668 00:54:55,900 --> 00:54:58,300 [Студент] Па еве кога отидовме минатото границите на својата низа - 669 00:54:58,300 --> 00:55:01,840 [Бауден] Тоа е каде што работите тргнат наопаку. >> [Студент] О, во ред. 670 00:55:01,840 --> 00:55:05,730 Онолку колку што ќе остане во рамките на меморијата распределени за вашиот низа, ти си во ред. 671 00:55:05,730 --> 00:55:12,400 Но Ц не не грешка проверка. Ако го направам низа [1000], тоа ќе задоволство само менувате она што се случува - 672 00:55:12,400 --> 00:55:16,500 Тоа важи до почетокот на низата, тогаш тоа оди 1000 позиции по и ги става на 0. 673 00:55:16,500 --> 00:55:20,000 Тоа не прави никаква проверка дека ох, тоа не всушност имаат 1000 работи во неа. 674 00:55:20,000 --> 00:55:22,750 1000 е далеку од она што треба да се менува, 675 00:55:22,750 --> 00:55:26,940 додека Јава или нешто ќе добиете низа надвор од границите индекс 676 00:55:26,940 --> 00:55:29,820 или индекс надвор од границите исклучок. 677 00:55:29,820 --> 00:55:33,950 Тоа е зошто многу повисоко ниво јазици имаат овие работи 678 00:55:33,950 --> 00:55:37,340 каде што ако се оди подалеку од границите на низата, ќе пропадне 679 00:55:37,340 --> 00:55:40,070 така што не може да се променат работите од под вас 680 00:55:40,070 --> 00:55:42,590 а потоа работите одат многу полошо отколку само добивање исклучок 681 00:55:42,590 --> 00:55:44,940 велејќи дека ќе отиде подалеку од крајот на низата. 682 00:55:44,940 --> 00:55:50,970 [Студент] И така треба да имаме само смени <= само > [Бауден] Да. 683 00:55:50,970 --> 00:55:54,800 Тоа треба да биде 00:55:59,560 бидејќи sizeof (низа) е 20, но ние само сакаме 5. >> [Студент] Десен. 685 00:55:59,560 --> 00:56:04,060 Повеќе прашања? Во ред. 686 00:56:04,060 --> 00:56:07,380 >> [Студент] Имам едно прашање. >> Да. 687 00:56:07,380 --> 00:56:16,440 [Студент] Што е вистинската низа променлива? 688 00:56:16,440 --> 00:56:20,000 [Бауден] Како што е низа? 689 00:56:20,000 --> 00:56:24,930 Низа сам по себе е симбол. 690 00:56:24,930 --> 00:56:31,490 Тоа е само на адресата на почетокот на 20 бајти дека ние сме референцирање. 691 00:56:31,490 --> 00:56:38,070 Можеш да мислиш за тоа како покажувач, но тоа е постојана покажувач. 692 00:56:38,070 --> 00:56:44,140 Штом работите да се состави, променлива низа веќе не постои. 693 00:56:44,140 --> 00:56:48,210 [Студент] Па како не го најдете на големината на низата? 694 00:56:48,210 --> 00:56:54,130 Големина на низата се однесува на големината на тој блок дека тој знак се однесува. 695 00:56:54,130 --> 00:57:01,240 Кога правам нешто како printf ("% p \ n", низа); 696 00:57:01,240 --> 00:57:05,140 ајде да ја стартувате. 697 00:57:12,960 --> 00:57:15,530 Што јас само направив погрешно? 698 00:57:15,530 --> 00:57:19,220 "Низа" низа прогласи тука. 699 00:57:20,820 --> 00:57:23,200 О, се тука. 700 00:57:23,200 --> 00:57:31,250 Ѕвекот е умен, а тоа се случува да забележите дека јас прогласи низа како 5 елементи 701 00:57:31,250 --> 00:57:34,540 но јас сум индексирање во позиција 1000. 702 00:57:34,540 --> 00:57:38,450 Тоа може да го направи тоа затоа што овие се само константи. 703 00:57:38,450 --> 00:57:43,370 Тоа само може да оди толку далеку во забележи дека јас одам надвор од границите на низата. 704 00:57:43,370 --> 00:57:46,880 Но, забележи порано кога имавме јас се неточни, 705 00:57:46,880 --> 00:57:51,040 тоа не може да се утврди колку вредности би можел да ја преземе, 706 00:57:51,040 --> 00:57:55,540 така што не може да се утврди дека ќе одам по завршувањето на низата. 707 00:57:55,540 --> 00:57:59,430 Тоа е само ѕвекот биде умен. 708 00:57:59,430 --> 00:58:03,340 >> Но сега се направи buggy4. Па што друго правам погрешно? 709 00:58:03,340 --> 00:58:05,970 Имплицитно наведува библиотека функција 'printf'. 710 00:58:05,970 --> 00:58:14,960 Одам да сакаат да # се . 711 00:58:14,960 --> 00:58:18,710 Во ред. Сега работи buggy4. 712 00:58:18,710 --> 00:58:24,840 Печатење на вредност на низата како што го направив тука, печатење тоа како покажувач 713 00:58:24,840 --> 00:58:30,060 отпечатоци нешто што личи ова - bfb8805c - што е некои адреса 714 00:58:30,060 --> 00:58:33,450 тоа е во магацинот-носталгичната регионот. 715 00:58:33,450 --> 00:58:41,820 Низа себе е како покажувач, но тоа не е вистински покажувач, 716 00:58:41,820 --> 00:58:45,410 од редовен покажувачот можеме да го промениме. 717 00:58:45,410 --> 00:58:54,700 Низа е само некои константа. На 20 блокови од меморијата на проектот на адреса 0xbfb8805c. 718 00:58:54,700 --> 00:59:09,020 Значи bfb8805c преку оваа адреса +20--или Претпоставувам -20 - 719 00:59:09,020 --> 00:59:17,400 е сите меморија распределени за оваа низа. 720 00:59:17,400 --> 00:59:20,350 Низа, променливата по себе не се чуваат насекаде. 721 00:59:20,350 --> 00:59:27,660 Кога сте составувањето, компајлерот - рака бран во него - 722 00:59:27,660 --> 00:59:33,060 но компајлерот само ќе го користи кога тоа го знае низа да биде. 723 00:59:33,060 --> 00:59:36,090 Таа не знае каде таа низа започнува, 724 00:59:36,090 --> 00:59:40,910 и така да се секогаш само се прават работите во однос на неутрализира од тоа почеток. 725 00:59:40,910 --> 00:59:43,960 Тоа не треба променлива себе да претставува низа. 726 00:59:43,960 --> 00:59:53,730 Но, кога ќе се направи нешто како int * P = array, а сега p е покажувач што укажува дека низа, 727 00:59:53,730 --> 00:59:57,830 и сега стр всушност постои на магацинот. 728 00:59:57,830 --> 01:00:01,950 Јас сум слободен да се промени стр. Можам да направам p = Примерок. 729 01:00:01,950 --> 01:00:06,500 Значи тоа првично посочи низа, а сега тоа укажува на некои простор на грамада. 730 01:00:06,500 --> 01:00:09,620 Не можам низа = Примерок. 731 01:00:09,620 --> 01:00:13,710 Ако ѕвекот е паметен, тоа ќе викне во мене право надвор од лилјак. 732 01:00:17,000 --> 01:00:21,430 Всушност, јас сум прилично сигурен gcc би го направил тоа премногу. 733 01:00:21,430 --> 01:00:25,010 Значи низа тип "int [5] 'не е преносливи. 734 01:00:25,010 --> 01:00:28,040 Не можете да доделите нешто да се низа тип 735 01:00:28,040 --> 01:00:30,500 бидејќи низа е само постојана. 736 01:00:30,500 --> 01:00:34,760 Тоа е симбол кој референци оние 20 бајти. Не можам да ја промените. 737 01:00:34,760 --> 01:00:37,690 >> [Студент] А каде е големината на низата чуваат? 738 01:00:37,690 --> 01:00:40,670 [Бауден] Тоа не е се чуваат насекаде. Тоа е времето кога тоа е составувањето. 739 01:00:40,670 --> 01:00:46,310 Значи, каде што е големината на низата чуваат? 740 01:00:46,310 --> 01:00:51,870 Можете да користите само sizeof (низа) во внатрешноста на функција која низата е се прогласи. 741 01:00:51,870 --> 01:01:03,150 Значи, ако јас се направи некои функција, foo, а јас не (int низа []) 742 01:01:03,150 --> 01:01:10,450 printf ("% d \ n", sizeof (низа)); 743 01:01:10,450 --> 01:01:21,330 а потоа овде јас го нарекувам foo (низа); 744 01:01:21,330 --> 01:01:24,840 внатрешноста на оваа функција - да го работи. 745 01:01:34,200 --> 01:01:36,840 Ова е ѕвекот биде умен повторно. 746 01:01:36,840 --> 01:01:43,890 Тоа ми кажува дека sizeof на низа параметар за функцијата 747 01:01:43,890 --> 01:01:46,690 ќе се врати големината на "int *. 748 01:01:46,690 --> 01:01:55,150 Ова ќе биде грешка ако тоа не е она што сакав да се случи. 749 01:01:55,150 --> 01:01:58,960 Да, всушност го исклучите Werror. 750 01:02:14,950 --> 01:02:17,590 Предупредување. Предупредувања се во ред. 751 01:02:17,590 --> 01:02:19,960 Тоа сепак ќе се собере колку што има предупредување. 752 01:02:19,960 --> 01:02:22,910 . / A.out се случува да се печати 4. 753 01:02:22,910 --> 01:02:28,650 Предупредувањето што се остварени е јасен показател на она што не беше во ред. 754 01:02:28,650 --> 01:02:34,120 Ова int низа е само ќе печати sizeof (int *). 755 01:02:34,120 --> 01:02:39,790 Дури и ако го ставам низа [5] овде, тоа е сепак само ќе печати sizeof (int *). 756 01:02:39,790 --> 01:02:47,440 Така што веднаш штом ќе го помине во функција, разликата меѓу низи и совети 757 01:02:47,440 --> 01:02:49,670 е непостоечки. 758 01:02:49,670 --> 01:02:52,640 Ова се случува да биде низа што беше прогласена на магацинот, 759 01:02:52,640 --> 01:02:58,300 но штом ќе помине таа вредност, тоа 0xbf бла, бла, бла во оваа функција, 760 01:02:58,300 --> 01:03:03,350 тогаш ова покажувач укажува дека низа на магацинот. 761 01:03:03,350 --> 01:03:08,310 Тоа значи дека sizeof се однесува само во функција која беше прогласена за низа, 762 01:03:08,310 --> 01:03:11,230 што значи дека кога ќе се составувањето на оваа функција, 763 01:03:11,230 --> 01:03:17,330 кога ѕвекот оди преку оваа функција, го гледа низа е int низа на големината 5. 764 01:03:17,330 --> 01:03:20,640 Па тогаш го гледа sizeof (низа). Па, тоа е 20. 765 01:03:20,640 --> 01:03:26,440 Тоа е всушност како sizeof основа работи на речиси сите случаи. 766 01:03:26,440 --> 01:03:31,150 Sizeof не е во функција, тоа е оператор. 767 01:03:31,150 --> 01:03:33,570 Вие не јавите на sizeof функција. 768 01:03:33,570 --> 01:03:38,280 Sizeof (int), компајлерот само ќе го преведе дека до 4. 769 01:03:41,480 --> 01:03:43,700 Добив тоа? Во ред. 770 01:03:43,700 --> 01:03:47,520 >> [Студент] Па што е разликата помеѓу sizeof (низа) во главниот и во foo? 771 01:03:47,520 --> 01:03:52,840 Тоа е затоа што си ти што зборуваш sizeof (низа), кој е од тип int *, 772 01:03:52,840 --> 01:03:57,120 со оглед на низа овде долу не е од тип int *, тоа е int низа. 773 01:03:57,120 --> 01:04:04,540 >> [Студент] Значи, ако сте имале на параметар во низа [] наместо int * низа, 774 01:04:04,540 --> 01:04:09,230 тоа би значело дека сеуште може да се промени низа, бидејќи сега тоа е покажувачот? 775 01:04:09,230 --> 01:04:14,250 [Бауден] Како тоа? >> [Студент] Да. Можете да ги менувате низа во функција сега? 776 01:04:14,250 --> 01:04:18,420 [Бауден] Вие може да се промени низа во двата случаи. 777 01:04:18,420 --> 01:04:23,130 Во двата од овие случаи можете слободно да се каже низа [4] = 0. 778 01:04:23,130 --> 01:04:26,590 [Студент] Но, можете да направите низа точка за нешто друго? 779 01:04:26,590 --> 01:04:30,230 [Бауден] О. Да. Во секој случај - >> [студент] Да. 780 01:04:30,230 --> 01:04:38,410 [Бауден] Разликата помеѓу низа [] и int * низа, не постои. 781 01:04:38,410 --> 01:04:42,570 Исто така можете да добиете некои мултидимензионална низа тука 782 01:04:42,570 --> 01:04:47,050 за некои удобен синтакса, но тоа е сепак само покажувач. 783 01:04:47,050 --> 01:04:56,400 Ова значи дека јас сум слободен да го стори низа = Примерок (sizeof (int)); и сега укажуваат на друго место. 784 01:04:56,400 --> 01:04:59,610 Но исто како и како тоа функционира засекогаш и секогаш, 785 01:04:59,610 --> 01:05:03,210 промена на оваа низа со тоа што укажуваат на нешто друго 786 01:05:03,210 --> 01:05:07,570 не се менува оваа низа долу тука, бидејќи тоа е копија на аргументот, 787 01:05:07,570 --> 01:05:10,780 тоа не е покажувачот во тој аргумент. 788 01:05:10,780 --> 01:05:16,070 И всушност, само што повеќе индикации дека тоа е иста - 789 01:05:16,070 --> 01:05:21,100 ние веќе видовме што печатење низа отпечатоци - 790 01:05:21,100 --> 01:05:31,410 што ако ние печати адресата на низа или адресата на адреса на низата 791 01:05:31,410 --> 01:05:36,290 на било кој од овие? 792 01:05:41,770 --> 01:05:45,220 Да се ​​игнорира оваа. 793 01:05:48,140 --> 01:05:51,660 Во ред. Ова е во ред. Тоа е сега работи. / A.out. 794 01:05:51,660 --> 01:06:00,220 Печатење низа, а потоа печати на адресата на низата, се иста работа. 795 01:06:00,220 --> 01:06:02,870 Низа едноставно не постои. 796 01:06:02,870 --> 01:06:08,190 Знае кога сте печатење низа, сте печатење симбол кој се однесува на оние 20 бајти. 797 01:06:08,190 --> 01:06:11,940 Печатење на адреса на низата, добро, низа не постои. 798 01:06:11,940 --> 01:06:17,200 Тоа не мора на адреса, така што само отпечатоци адресата на оние 20 бајти. 799 01:06:20,820 --> 01:06:28,150 Веднаш штом ќе се собере надолу, како во вашиот Составувач buggy4. / A.out, 800 01:06:28,150 --> 01:06:30,340 низа е непостоечки. 801 01:06:30,340 --> 01:06:33,640 Совети постои. Низи не. 802 01:06:34,300 --> 01:06:38,060 На блокови од меморијата претставува низа сè уште постојат, 803 01:06:38,060 --> 01:06:43,270 но променлива низа и променливи од тој вид не постојат. 804 01:06:46,260 --> 01:06:50,270 Оние се како главните разлики помеѓу низи и совети 805 01:06:50,270 --> 01:06:55,590 се што е можно да се направи функциски повици, не постои никаква разлика. 806 01:06:55,590 --> 01:07:00,460 Но во внатрешноста на функција која е прогласена низата себе, sizeof функционира поинаку 807 01:07:00,460 --> 01:07:05,190 бидејќи сте печатење со големина на блокови наместо на големината на видот, 808 01:07:05,190 --> 01:07:08,950 и не можете да го промените, бидејќи тоа е симбол. 809 01:07:08,950 --> 01:07:14,370 Печатење на работа и адресата на работа отпечатоци истото. 810 01:07:14,370 --> 01:07:18,480 И тоа е доста тоа. 811 01:07:18,480 --> 01:07:20,820 [Студент] Може да се каже дека еден повеќе време? 812 01:07:21,170 --> 01:07:24,170 Јас може да се пропушти нешто. 813 01:07:24,170 --> 01:07:29,260 Печатење низа и адреса на низа отпечатоци истото, 814 01:07:29,260 --> 01:07:33,180 а доколку ги отпечатите покажувач наспроти адреса на покажувачот, 815 01:07:33,180 --> 01:07:36,010 една работа отпечатоци адресата на она што сте укажува на, 816 01:07:36,010 --> 01:07:40,360 Од друга отпечатоци на адреса на покажувачот на магацинот. 817 01:07:40,360 --> 01:07:47,040 Можете да го промените покажувач, вие не може да го промени низа симбол. 818 01:07:47,740 --> 01:07:53,270 И sizeof покажувачот се случува да се печати големината на таа покажувачот тип. 819 01:07:53,270 --> 01:07:57,470 Значи int * P sizeof (м) се случува да се печати 4, 820 01:07:57,470 --> 01:08:04,110 но int низа [5] печати sizeof (низа) се случува да се печати 20. 821 01:08:04,110 --> 01:08:07,480 [Студент] Значи int низа [5] ќе печати 20? >> Да. 822 01:08:07,480 --> 01:08:13,300 Тоа е зошто во внатрешноста на buggy4 кога беше порано да биде sizeof (низа) 823 01:08:13,300 --> 01:08:16,660 ова беше правам <20, што не е она што сакав. 824 01:08:16,660 --> 01:08:20,880 Ние сакаме з <5. >> [Студент] Во ред. 825 01:08:20,880 --> 01:08:25,569 [Бауден] А потоа веднаш штом ќе почнете да поминува во функциите, 826 01:08:25,569 --> 01:08:34,340 ако ние не int * P = array; 827 01:08:34,340 --> 01:08:39,779 внатрешноста на оваа функција, ние во основа може да се користи p и низа на ист начин, 828 01:08:39,779 --> 01:08:43,710 освен за проблемот sizeof и на менување на проблемот. 829 01:08:43,710 --> 01:08:49,810 Но p [0] = 1; е иста како вели низа [0] = 1; 830 01:08:49,810 --> 01:08:55,600 И штом се каже foo (низа); или foo (p); 831 01:08:55,600 --> 01:08:59,760 внатрешноста на функција foo, ова е истиот повик двапати. 832 01:08:59,760 --> 01:09:03,350 Не постои никаква разлика помеѓу овие два повици. 833 01:09:07,029 --> 01:09:11,080 >> Секој добар за тоа? Во ред. 834 01:09:14,620 --> 01:09:17,950 Имаме 10 минути. 835 01:09:17,950 --> 01:09:28,319 >> Ние ќе се обидеме да се добие преку овој Хакер Typer програма, 836 01:09:28,319 --> 01:09:32,350 овој веб-сајт, кој излезе минатата година или така нешто. 837 01:09:34,149 --> 01:09:41,100 Тоа е само би требало да биде како што пишувате случајно и тоа отпечатоци од - 838 01:09:41,100 --> 01:09:46,729 Без оглед на датотеката се случи да се вчитани е она што изгледа како што го пишувате. 839 01:09:46,729 --> 01:09:52,069 Тоа изгледа како некој вид на оперативен систем код. 840 01:09:53,760 --> 01:09:56,890 Тоа е она што ние сакаме да се имплементира. 841 01:10:08,560 --> 01:10:11,690 Вие треба да имаат бинарна извршна име hacker_typer 842 01:10:11,690 --> 01:10:14,350 кој ги зема во еден аргумент, датотеката на "хакер тип." 843 01:10:14,350 --> 01:10:16,480 Вклучување на извршна треба да го исчистите екранот 844 01:10:16,480 --> 01:10:20,850 а потоа печати од еден лик од положениот во датотека секој пат кога корисникот ќе ја притиска копче. 845 01:10:20,850 --> 01:10:24,990 Значи она што клучните ќе притиснете, треба да фрлаат и наместо печати лик од датотека 846 01:10:24,990 --> 01:10:27,810 тоа е аргумент. 847 01:10:29,880 --> 01:10:34,350 Јас доста ќе ви кажам што работите ние ќе треба да се знае се. 848 01:10:34,350 --> 01:10:36,440 Но, ние сакаме да се провери од библиотека termios. 849 01:10:36,440 --> 01:10:44,840 Јас никогаш не го користеле овој библиотека во целиот мој живот, така што има многу минимален цели. 850 01:10:44,840 --> 01:10:48,610 Но, ова ќе биде библиотеката може да се користат да се фрлаат ликот ќе го погоди 851 01:10:48,610 --> 01:10:52,390 кога ќе се пишува во стандард внатре 852 01:10:56,970 --> 01:11:05,840 Значи hacker_typer.c, и ние ќе сакате да # се . 853 01:11:05,840 --> 01:11:12,870 Гледајќи човекот страница за termios - I'm Сомневајќи се дека е терминалот оперативен систем или нешто - 854 01:11:12,870 --> 01:11:16,240 Не знам како да го прочита. 855 01:11:16,240 --> 01:11:21,040 Гледајќи ова, се вели да се вклучат овие додадени фајлови: 2, така што ќе го направи тоа. 856 01:11:37,620 --> 01:11:46,820 >> Првото нешто што прво, ние сакаме да се земе во еден аргумент, кој е датотека што треба да се отвори. 857 01:11:46,820 --> 01:11:52,420 Значи она што сакам да направам? Како можам да се провери да се види имам еден аргумент? 858 01:11:52,420 --> 01:11:56,480 [Студент] Ако argc изнесува. >> [Бауден] Да. 859 01:11:56,480 --> 01:12:21,250 Значи, ако (argc = 2!) Printf ("Употреба:% s [датотеката да се отвори]"). 860 01:12:21,250 --> 01:12:32,750 Па сега ако јас ја извршите оваа без обезбедување на вториот аргумент - О, ми треба нова линија - 861 01:12:32,750 --> 01:12:36,240 ќе видите што вели употреба:. / hacker_typer, 862 01:12:36,240 --> 01:12:39,770 и потоа вториот аргумент треба да биде на датотека Сакам да се отвори. 863 01:12:58,430 --> 01:13:01,260 Сега она што можам да направам? 864 01:13:01,260 --> 01:13:08,490 Сакам да чита од оваа датотека. Како можам да прочитам од датотеката? 865 01:13:08,490 --> 01:13:11,920 [Студент] Ти ја отвори првата. >> Да. 866 01:13:11,920 --> 01:13:15,010 Значи fopen. Што значи fopen изгледа? 867 01:13:15,010 --> 01:13:22,980 [Студент] Име. >> [Бауден] Име ќе биде avg [1]. 868 01:13:22,980 --> 01:13:26,110 [Студент] И тогаш она што сакате да правите со неа, па - >> [Бауден] Да. 869 01:13:26,110 --> 01:13:28,740 Значи, ако не се сеќавам, ти само може да го направи човекот fopen, 870 01:13:28,740 --> 01:13:32,960 каде што тоа се случува да биде const char * патека каде што патот е името на датотеката, 871 01:13:32,960 --> 01:13:34,970 const char * режим. 872 01:13:34,970 --> 01:13:38,660 Ако се случи да не се сетам што владата е, тогаш можете да барате режим. 873 01:13:38,660 --> 01:13:44,660 Внатрешноста на човекот страници, ликот црта е она што можете да го користите за да барате работи. 874 01:13:44,660 --> 01:13:49,790 Па јас тип / режим за пребарување на владата. 875 01:13:49,790 --> 01:13:57,130 n и n се она што можете да го користите за да кружите низ пребарување натпревари. 876 01:13:57,130 --> 01:13:59,800 Еве што вели аргументот на владата укажува на низа 877 01:13:59,800 --> 01:14:01,930 почнувајќи со еден од следниве секвенци. 878 01:14:01,930 --> 01:14:06,480 Значи R, отворен текст датотека за читање. Тоа е она што сакате да го направите. 879 01:14:08,930 --> 01:14:13,210 За читање, и сакам да ги чувате тоа. 880 01:14:13,210 --> 01:14:18,720 Нешто се случува да биде на датотека *. Сега она што сакам да направам? 881 01:14:18,720 --> 01:14:21,200 Дај ми една секунда. 882 01:14:28,140 --> 01:14:30,430 Во ред. Сега она што сакам да направам? 883 01:14:30,430 --> 01:14:32,940 [Студент] Проверете дали тоа е NULL. >> [Бауден] Да. 884 01:14:32,940 --> 01:14:38,690 Во секое време ќе отворите некоја датотека, бидете сигурни дека сте успешно во можност да го отворите. 885 01:14:58,930 --> 01:15:10,460 >> Сега сакам да го правам тоа termios работи каде што сакам прво да го прочитате мојот тековните поставувања 886 01:15:10,460 --> 01:15:14,050 и спаси оние во нешто, тогаш сакам да ги променам моите опции 887 01:15:14,050 --> 01:15:19,420 да се фрлаат било карактер што го пишувате, 888 01:15:19,420 --> 01:15:22,520 и тогаш сакам да се ажурираат овие поставувања. 889 01:15:22,520 --> 01:15:27,250 А потоа на крајот на програмата, сакам да се промени се враќам на оригиналниот поставувања. 890 01:15:27,250 --> 01:15:32,080 Па struct ќе биде од типот termios, а јас ќе одам да сакате две од нив. 891 01:15:32,080 --> 01:15:35,600 Првиот се случува да ми биде current_settings, 892 01:15:35,600 --> 01:15:42,010 а потоа тие ќе ми биде hacker_settings. 893 01:15:42,010 --> 01:15:48,070 Прво, јас одам да сакате да ја спаси мојата тековните поставувања, 894 01:15:48,070 --> 01:15:53,790 тогаш јас ќе одам да сакате да го обновите hacker_settings, 895 01:15:53,790 --> 01:16:01,570 а потоа начинот на кој на крајот на мојата програма, сакам да се вратите на тековните поставувања. 896 01:16:01,570 --> 01:16:08,660 Значи заштеда на тековните поставувања, начинот на кој функционира, ние човек termios. 897 01:16:08,660 --> 01:16:15,810 Можеме да видиме дека имаме оваа int tcsetattr, int tcgetattr. 898 01:16:15,810 --> 01:16:22,960 Јас помине во termios struct од страна на неговиот покажувач. 899 01:16:22,960 --> 01:16:30,640 Начинот на кој тоа ќе изгледа е - I've веќе заборавени што функцијата бил повикан. 900 01:16:30,640 --> 01:16:34,930 Копирате и залепите. 901 01:16:39,150 --> 01:16:45,500 Значи tcgetattr, тогаш сакам да помине во struct дека сум спасување на информации, 902 01:16:45,500 --> 01:16:49,650 која ќе биде current_settings, 903 01:16:49,650 --> 01:16:59,120 и првиот аргумент е датотека descriptor за нешто што сакате да ја зачувате атрибути. 904 01:16:59,120 --> 01:17:04,360 Што опишувач на датотека е е како и секој пат кога ќе отворите некоја датотека, таа добива опишувач за датотеката. 905 01:17:04,360 --> 01:17:14,560 Кога ќе fopen avg [1], таа добива опишувач на датотека која сте референцирање 906 01:17:14,560 --> 01:17:16,730 кога сакаш да прочита или запише на него. 907 01:17:16,730 --> 01:17:19,220 Тоа не е опишувач на датотека сакам да се користи тука. 908 01:17:19,220 --> 01:17:21,940 Постојат три датотека дескриптори имате по дифолт, 909 01:17:21,940 --> 01:17:24,310 кои се стандардни во, стандарден излез, и стандардна грешка. 910 01:17:24,310 --> 01:17:29,960 По дифолт, мислам дека тоа е стандард во е 0, стандарден излез е 1, и стандардна грешка е 2. 911 01:17:29,960 --> 01:17:33,980 Значи она што сакам да ги промените поставките на? 912 01:17:33,980 --> 01:17:37,370 Сакам да ги промените поставките на секогаш кога ќе се погоди некој лик, 913 01:17:37,370 --> 01:17:41,590 Сакам да фрлаат дека карактерот далеку наместо печатење до екранот. 914 01:17:41,590 --> 01:17:45,960 Што поточно - стандард во, стандарден излез, или стандардна грешка - 915 01:17:45,960 --> 01:17:52,050 реагира на нешта кога пишувате на тастатурата? >> [Студент] Стандардна внатре >> Да. 916 01:17:52,050 --> 01:17:56,450 Па јас или да направите 0 или можам да направам stdin. 917 01:17:56,450 --> 01:17:59,380 Јас сум добивање на current_settings на стандардни внатре 918 01:17:59,380 --> 01:18:01,720 >> Сега сакам да се ажурираат овие поставувања, 919 01:18:01,720 --> 01:18:07,200 па прво ќе го копирате во hacker_settings што ми current_settings се. 920 01:18:07,200 --> 01:18:10,430 И како structs работа е тоа само ќе копија. 921 01:18:10,430 --> 01:18:14,510 Оваа копии сите полиња, како што би очекувале. 922 01:18:14,510 --> 01:18:17,410 >> Сега сакам да се ажурира некои од полињата. 923 01:18:17,410 --> 01:18:21,670 Гледајќи termios, вие ќе треба да се чита преку многу на овој 924 01:18:21,670 --> 01:18:24,110 само за да видам што ќе сакате да барате, 925 01:18:24,110 --> 01:18:28,210 но знамиња сте ќе сакате да се погледне за се ехо, 926 01:18:28,210 --> 01:18:33,110 па ехо ехо внесување карактери. 927 01:18:33,110 --> 01:18:37,710 Прво сакам да поставите - I've веќе заборавени што полиња се. 928 01:18:45,040 --> 01:18:47,900 Тоа е она што struct изгледа. 929 01:18:47,900 --> 01:18:51,060 Значи режими мислам дека сакате да го промените. 930 01:18:51,060 --> 01:18:54,210 Ние ќе се погледне на решение да бидете сигурни дека е она што сакате да го промените. 931 01:19:04,060 --> 01:19:12,610 Ние сакаме да се промени lflag со цел да се спречи потреба да се погледне преку сите овие. 932 01:19:12,610 --> 01:19:14,670 Ние сакаме да се смени локалниот режими. 933 01:19:14,670 --> 01:19:17,710 Вие ќе треба да се чита преку целата оваа работа да се разбере каде што припаѓа 934 01:19:17,710 --> 01:19:19,320 дека сакаме да се промени. 935 01:19:19,320 --> 01:19:24,120 Но, тоа е во внатрешноста на локални режими каде што сте ќе сакате да го промени тоа. 936 01:19:27,080 --> 01:19:33,110 Значи hacker_settings.cc_lmode е она што се вика. 937 01:19:39,630 --> 01:19:43,020 c_lflag. 938 01:19:49,060 --> 01:19:52,280 Ова е местото каде што ќе го добиеме во bitwise оператори. 939 01:19:52,280 --> 01:19:54,860 Ние сме вид на надвор од времето, но ние ќе поминат низ вистински брз. 940 01:19:54,860 --> 01:19:56,600 Ова е местото каде што ќе го добиеме во bitwise оператори, 941 01:19:56,600 --> 01:19:59,950 каде што мислам дека реков едно време одамна дека секогаш кога ќе почнете да се занимаваат со знамиња, 942 01:19:59,950 --> 01:20:03,370 сте ќе биде со користење на bitwise оператор многу. 943 01:20:03,370 --> 01:20:08,240 Секој малку на знамето одговара на некој вид на однесување. 944 01:20:08,240 --> 01:20:14,090 Па еве, ова знаме има еден куп на различни нешта, каде што сите од нив значат нешто различно. 945 01:20:14,090 --> 01:20:18,690 Но, она што сакам да направите е само да го исклучите малку што одговара на ехо. 946 01:20:18,690 --> 01:20:25,440 Значи да се претвори дека надвор правам & = ¬ ЕЦХО. 947 01:20:25,440 --> 01:20:30,110 Всушност, мислам дека тоа е како tECHO или нешто. Јас сум само случува да се провери повторно. 948 01:20:30,110 --> 01:20:34,050 Можам да го termios. Тоа е само ехо. 949 01:20:34,050 --> 01:20:38,440 ЕЦХО се случува да биде една малку. 950 01:20:38,440 --> 01:20:44,230 ¬ ЕЦХО ќе значи сите битови се постави на 1, што значи дека сите знамиња се поставени на точно 951 01:20:44,230 --> 01:20:47,140 освен за ЕЦХО малку. 952 01:20:47,140 --> 01:20:53,830 Со завршува мојата локална знамиња со тоа, значи сите знамиња кои се моментално поставено на true 953 01:20:53,830 --> 01:20:56,520 уште ќе биде поставена на true. 954 01:20:56,520 --> 01:21:03,240 Ако мојата ЕЦХО знаме е поставено на true, тогаш ова е нужно наместено како FALSE на ЕЦХО знаме. 955 01:21:03,240 --> 01:21:07,170 Значи оваа линија од кодот само се исклучува ЕЦХО знаме. 956 01:21:07,170 --> 01:21:16,270 Другите линии на код, јас само ќе ги ископирате во интерес на времето, а потоа објасни нив. 957 01:21:27,810 --> 01:21:30,180 Во растворот, рече тој 0. 958 01:21:30,180 --> 01:21:33,880 Тоа е можеби подобро да се експлицитно се каже stdin. 959 01:21:33,880 --> 01:21:42,100 >> Забележете дека јас сум исто така, прави ЕХО | ICANON тука. 960 01:21:42,100 --> 01:21:46,650 ICANON се однесува на нешто посебно, што значи канонски режим. 961 01:21:46,650 --> 01:21:50,280 Што канонски режим значи обично кога сте пишување од командната линија, 962 01:21:50,280 --> 01:21:54,670 стандард во не ги обработува ништо додека не го погоди линија. 963 01:21:54,670 --> 01:21:58,230 Па кога ќе се GetString, ќе напишете еден куп работи, а потоа ќе го погоди линија. 964 01:21:58,230 --> 01:22:00,590 Тоа е кога е испратена до стандард внатре 965 01:22:00,590 --> 01:22:02,680 Тоа е стандардно. 966 01:22:02,680 --> 01:22:05,830 Кога ќе го исклучите канонски владата, сега секој лик ќе го притиснете копчето 967 01:22:05,830 --> 01:22:10,910 е она што се преработува, која обично е вид на лошо, бидејќи тоа е бавен за обработка на овие работи, 968 01:22:10,910 --> 01:22:14,330 кој е зошто тоа е добро да се амортизираат во целиот линии. 969 01:22:14,330 --> 01:22:16,810 Но сакам секој лик да бидат обработени 970 01:22:16,810 --> 01:22:18,810 бидејќи јас не сакам тоа да се чека за мене да ја погоди линија 971 01:22:18,810 --> 01:22:21,280 пред обработува сите ликови сум бил пишување. 972 01:22:21,280 --> 01:22:24,760 Ова се исклучува канонски режим. 973 01:22:24,760 --> 01:22:31,320 Овој материјал само значи кога тоа всушност обработува карактери. 974 01:22:31,320 --> 01:22:35,830 Ова значи процесот на нив веднаш, штом јас сум ги пишувате, процесот на нив. 975 01:22:35,830 --> 01:22:42,510 И ова е функција која е ажурирање на моите опции за стандард во, 976 01:22:42,510 --> 01:22:45,480 и TCSA средства го направите токму сега. 977 01:22:45,480 --> 01:22:50,310 Другите опции се почека до сè што е во моментов на струја се обработува. 978 01:22:50,310 --> 01:22:52,030 Тоа навистина не е важно. 979 01:22:52,030 --> 01:22:56,920 Само во моментов ги променам моите опции за да биде она што во моментов е во hacker_typer_settings. 980 01:22:56,920 --> 01:23:02,210 Претпоставувам дека тоа се нарекува hacker_settings, па ајде смени тоа. 981 01:23:09,610 --> 01:23:13,500 Промени сè до hacker_settings. 982 01:23:13,500 --> 01:23:16,870 >> Сега на крајот на нашата програма ние ќе сакате да се вратите 983 01:23:16,870 --> 01:23:20,210 за она што во моментов е во внатрешноста на normal_settings, 984 01:23:20,210 --> 01:23:26,560 кој се случува само да изгледа како и normal_settings. 985 01:23:26,560 --> 01:23:30,650 Забележиш јас не се променети било кој од моите normal_settings бидејќи првобитно добива. 986 01:23:30,650 --> 01:23:34,520 Потоа само да ги вратиме назад, јас ги помине назад на крајот. 987 01:23:34,520 --> 01:23:38,390 Ова е ажурирање. Во ред. 988 01:23:38,390 --> 01:23:43,900 >> Сега во внатрешноста од овде јас само ќе се објасни го кодот во интерес на времето. 989 01:23:43,900 --> 01:23:46,350 Тоа не е дека многу код. 990 01:23:50,770 --> 01:24:03,750 Гледаме дека чита карактер од датотеката. Ние го нарече ѓ. 991 01:24:03,750 --> 01:24:07,850 Сега можете човек fgetc, но како fgetc се случува на работа 992 01:24:07,850 --> 01:24:11,910 е само тоа нема да се врати на ликот дека сте само читаат или EOF, 993 01:24:11,910 --> 01:24:15,680 што одговара на крајот на датотеката или некои грешка се случува. 994 01:24:15,680 --> 01:24:19,900 Ние сме looping, продолжувајќи да се чита еден карактер од датотеката, 995 01:24:19,900 --> 01:24:22,420 додека ние сме снема карактери да читаат. 996 01:24:22,420 --> 01:24:26,650 И додека ние го правиме тоа, ние се чека на еден лик од стандардните внатре 997 01:24:26,650 --> 01:24:29,090 Секој пат кога ќе напишете нешто на командната линија, 998 01:24:29,090 --> 01:24:32,820 тоа е читање во лик од стандардните внатре 999 01:24:32,820 --> 01:24:38,330 Потоа putchar е само ќе се стави на знак читаме се тука од датотеката до стандарден излез. 1000 01:24:38,330 --> 01:24:42,890 Можете да човек putchar, но тоа е само ставање до стандарден излез, тоа е печатење на тој лик. 1001 01:24:42,890 --> 01:24:51,600 Вие исто така може само направете printf ("% c", в); истата идеја. 1002 01:24:53,330 --> 01:24:56,670 Тоа се случува да се направи најголемиот дел од нашата работа. 1003 01:24:56,670 --> 01:25:00,300 >> Последно нешто што сте ќе сакате да направите е само запишам нашите датотека. 1004 01:25:00,300 --> 01:25:03,310 Ако не запишам, тоа е меморија излегуваат во јавноста. 1005 01:25:03,310 --> 01:25:06,680 Ние сакаме да запишам во датотеката што првично се отвори, и мислам дека тоа е тоа. 1006 01:25:06,680 --> 01:25:13,810 Ако се направи тоа, јас веќе доби проблеми. 1007 01:25:13,810 --> 01:25:17,260 Ајде да видиме. 1008 01:25:17,260 --> 01:25:19,960 Она што не го жалат? 1009 01:25:19,960 --> 01:25:30,220 Очекува "int", но аргумент е од типот "struct _IO_FILE * '. 1010 01:25:36,850 --> 01:25:39,370 Ќе видиме дали тоа функционира. 1011 01:25:45,210 --> 01:25:53,540 Дозволено само во C99. Augh. Океј, се направи hacker_typer. 1012 01:25:53,540 --> 01:25:57,760 Сега ние се повеќе корисни описи. 1013 01:25:57,760 --> 01:25:59,900 Значи употребата на непријавена идентификатор 'normal_settings. 1014 01:25:59,900 --> 01:26:04,170 Јас не го нарекуваат normal_settings. Јас го нарече current_settings. 1015 01:26:04,170 --> 01:26:12,090 Значи, да се промени сето тоа. 1016 01:26:17,920 --> 01:26:21,710 Сега поминува аргумент. 1017 01:26:26,290 --> 01:26:29,500 Ќе се направи овој 0 за сега. 1018 01:26:29,500 --> 01:26:36,720 Во ред. . / Hacker_typer cp.c. 1019 01:26:36,720 --> 01:26:39,590 Јас, исто така не го исчистите екранот на почетокот. 1020 01:26:39,590 --> 01:26:42,960 Но може да се погледне назад на последниот проблем во собата да се види како ќе го исчистите екранот. 1021 01:26:42,960 --> 01:26:45,160 Тоа е само печатење некои карактери 1022 01:26:45,160 --> 01:26:47,210 Иако ова е тоа што сакам да го направам. 1023 01:26:47,210 --> 01:26:48,900 Во ред. 1024 01:26:48,900 --> 01:26:55,280 И размислување за тоа зошто ова треба да биде 0, наместо на stdin, 1025 01:26:55,280 --> 01:27:00,560 кои треба да се # define 0, 1026 01:27:00,560 --> 01:27:03,890 ова се жали дека - 1027 01:27:13,150 --> 01:27:19,360 Пред кога реков дека има датотека дескриптори, но тогаш вие исто така имате СЛИКА *, 1028 01:27:19,360 --> 01:27:23,210 на опишувач на датотека е само еден број, 1029 01:27:23,210 --> 01:27:26,970 додека датотека * има еден куп на работи поврзани со неа. 1030 01:27:26,970 --> 01:27:30,380 Причината ние треба да се каже 0 наместо stdin 1031 01:27:30,380 --> 01:27:37,480 е дека stdin е датотека * што укажува на нешто што е референцирање датотека descriptor 0. 1032 01:27:37,480 --> 01:27:45,070 Па дури и до тука и кога правам fopen (avg [1], јас сум добивање на датотека * назад. 1033 01:27:45,070 --> 01:27:51,180 Но, некаде во таа датотека * е нешто што одговара на опишувач на датотека за таа датотека. 1034 01:27:51,180 --> 01:27:57,430 Ако се погледне на човекот страница за отворени, па мислам дека ќе треба да направите man 3 отворен - Не бе - 1035 01:27:57,430 --> 01:27:59,380 човек 2 отворени - Да. 1036 01:27:59,380 --> 01:28:06,250 Ако се погледне на страната за отворен, отворен е како пониско ниво fopen, 1037 01:28:06,250 --> 01:28:09,350 и тоа е враќање на вистинските опишувач за датотеката. 1038 01:28:09,350 --> 01:28:12,050 fopen прави еден куп на работи на врвот на отворено, 1039 01:28:12,050 --> 01:28:17,640 кои наместо враќање токму тоа опишувач на датотека се враќа целата датотека * покажувачот 1040 01:28:17,640 --> 01:28:20,590 внатрешноста на која е нашата мала опишувач за датотеката. 1041 01:28:20,590 --> 01:28:25,020 Па стандард во однесува на Датотека * работа, 1042 01:28:25,020 --> 01:28:29,120 додека 0 однесува само опишувач на датотека стандард во себе. 1043 01:28:29,120 --> 01:28:32,160 >> Прашања? 1044 01:28:32,160 --> 01:28:35,930 [Се смее] дувна преку тоа. 1045 01:28:35,930 --> 01:28:39,140 Во ред. Ние завршиш. [Се смее] 1046 01:28:39,140 --> 01:28:42,000 >> [CS50.TV]