1 00:00:00,000 --> 00:00:02,500 [Powered by Google Translate] [Раздзел 5 - больш камфортнай] 2 00:00:02,500 --> 00:00:04,690 [Rob Боуден - Гарвардскі універсітэт] 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 Яны маюць Nano. 47 00:03:12,130 --> 00:03:14,990 Nano, як правіла, вельмі простая ў выкарыстанні. 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, Control C? Так. 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 На ПК, Вы можаце SSH выкарыстанні PuTTY, 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 якіх з'яўляецца тое, што вы можаце выкарыстоўваць на ПК. 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 У нас ёсць Redirecting і трубы, і гэтыя тры пытанні. 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 Справа нават не ў крыніцы 1 і 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 Стандартны выхад, па струмені, гэта азначае, што вы проста напісаць 1 і 0 да яго, 95 00:06:36,860 --> 00:06:40,220 , А другі канец стандартнага з проста чытае дадзеныя з патоку. 96 00:06:40,220 --> 00:06:43,540 Гэта проста радок 1 і 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 Напрыклад, скажам, у мяне, аказваецца, ёсць Dict прама тут, 121 00:08:23,430 --> 00:08:27,020 і адзіны матэрыял ўнутры Dict гэта коткі, коткі, сабакі, рыбы, сабакі. 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 Такім чынам, тэхнічна, ён цалкам пераадолеў што мы мелі. 133 00:09:17,910 --> 00:09:22,970 І мы ўбачым, калі я магу змяніць слоўнік, я ўзяў сабаку. 134 00:09:22,970 --> 00:09:29,980 Цяпер, калі мы котку Dict ў файл зноў, мы будзем мець новую версію з сабакам выдаленыя. 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 Я проста атрымліваю радок, а затым друк "Hello" ўсе радкі Я толькі што ўступіў было. 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 калі я запускаю прывітанне, а затым перанакіраваць у тэкставы файл. / Добры дзень, гэта збіраўся сказаць Прывітанне, Боб! неадкладна. 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 Замест гэтага, мы перанакіравалі ў стандартным для чытання з тэкставага файла. 160 00:12:05,980 --> 00:12:10,290 І так будзе чытаць з тэкставага файла, які знаходзіцца ўсяго ў лінію Роб, 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 на стандартны вывад. 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 стандартны вывад, то гэта ў асноўным эквівалентная 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 Раней, калі я сказаў, што я павінен быў змясціць Роб ў тэкставы файл 199 00:15:20,600 --> 00:15:28,830 таму што я магу толькі перанакіраваць тэкставыя файлы, а / я паўтараю, калі 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 , А затым ўвядзіце ў. / Прывітанне, што файл, які быў проста выводзіцца. 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 , Які збіраецца толькі выгляд ліній тэкставы файл. 215 00:16:47,410 --> 00:16:58,080 Калі я зраблю некаторыя тэкставы файл, 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 Гэта на самай справе друк - Давайце паглядзім, мужчына туалет - пераклад радка, слова і байта. 222 00:17:32,560 --> 00:17:38,270 Калі б я толькі клапаціцца пра лініях, то я магу проста зрабіць туалет-л names.txt. 223 00:17:41,730 --> 00:17:44,300 Так што гэта крок 1. 224 00:17:44,300 --> 00:17:50,510 Але я не хачу, каб ЧС-л names.txt, таму што 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 і я хачу выкарыстоўваць яго ў якасці ўкладу ў туалет-л, 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 і гэта URL. 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 якія ў любы час вы атрымаеце сегментацыі, гэта дрэнна. 263 00:21:00,500 --> 00:21:03,810 Пры якіх абставінах вы атрымліваеце сегментацыі? 264 00:21:03,810 --> 00:21:08,210 [Студэнт] разнаймення нулявога паказальніка. >> Так. Так што гэта адзін з прыкладаў. 265 00:21:08,210 --> 00:21:11,580 Разнаймення нулявога паказальніка вы збіраецеся атрымаць сегментацыі. 266 00:21:11,580 --> 00:21:16,720 Што сегментацыі азначае, ты дакранаешся памяці, вы не павінны дакранацца. 267 00:21:16,720 --> 00:21:21,350 Так разнаймення нулявога паказальніка датыкаецца з адрасам 0, 268 00:21:21,350 --> 00:21:28,060 і ў асноўным, усе кампутары ў цяперашні час сказаць, што адрас 0 памяці ў вас не павінна дакранацца. 269 00:21:28,060 --> 00:21:31,920 Дык вось чаму разнаймення нулявога паказальніка ў выніках сегментацыі. 270 00:21:31,920 --> 00:21:37,210 Калі вы выпадкова не ініцыялізаваць паказальнік, то яна мае значэнне смецця, 271 00:21:37,210 --> 00:21:41,520 і таму, калі вы спрабуеце разнаймення гэта, па ўсёй верагоднасці, ты дакранаешся памяці 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 Затым, калі вы разнаймення, што паказальнік, які вы яшчэ не ініцыялізаваны, 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 Затым ты дакранаешся памяці ў вас не павінна датычыцца, і вы сегментацыі. 280 00:22:02,240 --> 00:22:06,370 Пры напісанні рэкурсіўнай функцыі, і гэта рэкурсіўна занадта шмат разоў 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 так што вы сегментацыі. 284 00:22:14,810 --> 00:22:17,010 Гэта тое, што з'яўляецца сегментацыі. 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--я проста збіраюся зрабіць нешта яшчэ. 288 00:22:28,530 --> 00:22:33,770 сімвал * S = "прывітанне свет!"; 289 00:22:33,770 --> 00:22:42,310 Калі я выкарыстоўваю * S = нешта або з [0] = 'X'; 290 00:22:42,310 --> 00:22:47,290 так што прывітанне,. / прывітанне, чаму гэта сегментацыі? 291 00:22:48,410 --> 00:22:51,250 Чаму гэта сегментацыі? 292 00:22:55,660 --> 00:22:57,890 Што вы чакаеце далей? 293 00:22:57,890 --> 00:23:06,640 Калі б я зрабіў Е ("% 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 а гэта паказальнік, што збіраецца пайсці ў стэку, 297 00:23:18,190 --> 00:23:25,880 і што з паказвае на гэта радок, якая змяшчаецца ў ПЗУ. 298 00:23:25,880 --> 00:23:30,560 Так што проста па імені, толькі для чытання памяці, вы павінны атрымаць ідэю 299 00:23:30,560 --> 00:23:33,010 што калі вы спрабуеце змяніць тое, што ў ПЗУ, 300 00:23:33,010 --> 00:23:36,670 Вы робіце тое, што вы не павінны рабіць з памяццю, і вы сегментацыі. 301 00:23:36,670 --> 00:23:45,360 Гэта на самай справе вялікі розніцы паміж сімвал * з і знакаў з []. 302 00:23:45,360 --> 00:23:48,790 Такім чынам, сімвал S [], цяпер гэтая радок будзе пакласці ў стэк, 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 Памятаеце, што калі я раблю знак * S = "прывітанне свет!", А сама знаходзіцца ў стэку 306 00:24:06,250 --> 00:24:10,390 але з пункту куды-небудзь яшчэ, і што дзесьці ў іншым месцы, здараецца, толькі для чытання. 307 00:24:10,390 --> 00:24:15,640 Але сімвал S [] толькі тое, у стэку. 308 00:24:17,560 --> 00:24:21,760 Так што гэта яшчэ адзін прыклад сегментацыі адбываецца. 309 00:24:21,760 --> 00:24:27,820 >> Мы бачылі, што ./buggy1 ў выніку сегментацыі. 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 скалы", ARGV [1]) == 0). 350 00:27:17,360 --> 00:27:24,130 Калі гэта не відавочна, тым не менш, вы можаце атрымаць яго прама адсюль проста думаю, чаму ён segfaulted. 351 00:27:24,130 --> 00:27:28,800 Але мы можам зрабіць яшчэ адзін крок наперад і сказаў: "Чаму б ARGV [1] сегментацыі?" 352 00:27:28,800 --> 00:27:38,830 Друк Давайце ARGV [1], і, падобна, гэта 0x0, які з'яўляецца нулявым паказальнікам. 353 00:27:38,830 --> 00:27:44,750 Мы strcmping CS50 парод і нулявыя, і так, што збіраецца падаць. 354 00:27:44,750 --> 00:27:48,280 І чаму ARGV [1] NULL? 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 будзе толькі ў ARGV [0] ./buggy1. 358 00:27:58,460 --> 00:28:02,100 Гэта не будзе мець ARGV [1], так што збіраецца падаць. 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, ён павінен друкаваць "Вы атрымліваеце D" - 362 00:28:15,240 --> 00:28:20,820 Калі ARGV [1] не з'яўляецца "CS50 скалы", "Вы атрымліваеце D", інакш "Вы атрымліваеце!" 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 Так ARGV [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 ARGV [1] будзе CS50 і ARGV [2] будзе пародах. Добра. 371 00:28:52,540 --> 00:28:56,470 >> Цяпер ./buggy2 збіраецца сегментацыі зноў. 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 якая з'яўляецца сігналу сегментацыі, і гэта, дзе гэта адбылося здарыцца. 376 00:29:15,530 --> 00:29:21,250 Гледзячы на ​​наш след, мы бачым, што мы былі ў функцыі oh_no, 377 00:29:21,250 --> 00:29:23,900 якая была выкліканая функцыя хупавы, якая была выкліканая функцыя Бинки, 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 Аргумент хупавы і Бинки была 1. 381 00:29:34,680 --> 00:29:44,390 Калі мы пералічым функцыі oh_no, мы бачым, што oh_no проста робіць знак ** ы = NULL; 382 00:29:44,390 --> 00:29:47,410 * S = "БУМ"; 383 00:29:47,410 --> 00:29:50,330 Чаму гэта не атрымаецца? 384 00:29:54,330 --> 00:29:58,380 [Студэнт] Вы не можаце разыменовать нулявы паказальнік? >> Так. 385 00:29:58,380 --> 00:30:06,090 Гэта проста кажу ёй гэта 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 Гэта з пустой, так * з у разнаймення нулявога паказальніка, 389 00:30:21,430 --> 00:30:24,800 і так гэта будзе крах. 390 00:30:24,800 --> 00:30:27,540 Гэта адзін з самых хуткіх спосабаў магчыма, вы можаце падаць. 391 00:30:27,540 --> 00:30:31,300 Гэта проста абвясціўшы нулявы паказальнік і адразу ж памылку сегментацыі. 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 Калі вы не ўвядзеце каманду, і вы проста націсніце Enter зноў, 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 яшчэ пайсці ў аблягаў функцыі. 402 00:31:15,960 --> 00:31:18,700 І мы ведаем, я = 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 У цяперашні час мы хупавы, і калі мы пойдзем іншы кадр, мы ведаем, што ў канчатковым выніку ў Бинки. 406 00:31:33,770 --> 00:31:36,600 Up. Цяпер мы знаходзімся ў Бинки. 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 я = RAND ()% 3; 411 00:32:05,030 --> 00:32:08,790 Гэта проста збіраюся даць вам выпадковы лік, якое роўна 0, 1 або 2. 412 00:32:08,790 --> 00:32:12,780 Ён збіраўся патэлефанаваць Бинки з гэтым нумарам, і ён будзе вяртаць 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, так што мы можам надрукаваць значэнне я, 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 што адбываецца ўнутры Бинки. 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 і паглядзіце, што там адбываецца, і я мог ступіць праз функцыю рандаў. 431 00:33:25,110 --> 00:33:26,920 Але я не клапачуся аб функцыі рандаў. 432 00:33:26,920 --> 00:33:30,190 Я проста хачу, каб перайсці да наступнай радку кода ў асноўны, таму я выкарыстоўваю наступны. 433 00:33:30,190 --> 00:33:35,800 Але цяпер я клапачуся аб Бинки функцыі, таму я хачу, каб увайсці ў гэта. 434 00:33:35,800 --> 00:33:37,730 Зараз я знаходжуся ў Бинки. 435 00:33:37,730 --> 00:33:42,040 Першы радок кода будзе казаць тады, калі (я == 0), я раблю крок, 436 00:33:42,040 --> 00:33:44,930 мы бачым, мы ў канчатковым выніку на хупавы. 437 00:33:44,930 --> 00:33:51,620 Калі мы рэчы спісу, мы бачым, што ён праверыў гэта я = 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 Калі вы толькі паглядзіце на гэтых ліній непасрэдна, можна падумаць, калі (я == 0), 442 00:34:07,380 --> 00:34:10,800 Добра, тады я зрабіў крок, і цяпер я ў хупавы (I), 443 00:34:10,800 --> 00:34:14,120 Вы думаеце, што павінна азначаць = 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 таму што я = 1 выклікае функцыю oh_no, які вы можаце ўступіць, 451 00:34:46,489 --> 00:34:52,969 які будзе ўсталяваны знак ** S = NULL, каб і адразу "БУМ". 452 00:34:54,270 --> 00:34:59,690 І тады на самай справе, гледзячы на ​​ажыццяўленне buggy2, 453 00:34:59,690 --> 00:35:04,590 гэта, я проста атрымліваю выпадковыя ліку - 0, 1 або 2 - пакліканне Бинки, 454 00:35:04,590 --> 00:35:10,610 , Які, калі я гэта 0 яно выклікае oh_no, інакш ён называе хупавы, якая прыходзіць сюды. 455 00:35:10,610 --> 00:35:18,100 Калі я 1, выклік oh_no, інакш называюць абліпальныя, якія прыдумляюць тут, 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 Хто-небудзь гл. спосаб зрабіць гэта праграмы, якія не будуць падаць? 459 00:35:30,030 --> 00:35:37,530 Таму што калі я нешта адсутнічае, калі я 0, вы адразу сегментацыі, 460 00:35:37,530 --> 00:35:41,250 яшчэ вы ідзяце ў функцыі якога, калі я гэта 1 Вы сегментацыі, 461 00:35:41,250 --> 00:35:44,540 яшчэ вы ідзяце ў функцыі якой, калі я гэта 2 вы сегментацыі. 462 00:35:44,540 --> 00:35:46,810 Так што не мае значэння, што вы робіце, вы сегментацыі. 463 00:35:46,810 --> 00:35:52,380 >> Я думаю, адзін з спосабаў фіксацыі было б замест таго, каб рабіць знак ** ы = NULL, 464 00:35:52,380 --> 00:35:55,610 Вы можаце Malloc прасторы для гэтага радка. 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 * х. 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 з сімвалаў * х = "БУМ". 480 00:37:20,870 --> 00:37:27,950 "БУМ" ужо існуе. Гэта адбываецца існаваць у даступным толькі для чытання вобласць памяці. 481 00:37:27,950 --> 00:37:35,200 Але ён ужо існуе, а значыць гэты радок кода, калі ёй гэта сімвал **, 482 00:37:35,200 --> 00:37:43,900 Затым * S з'яўляецца знак * і вы ўсталёўваеце гэты знак *, каб паказаць на "БУМ". 483 00:37:43,900 --> 00:37:50,040 Калі б я хацеў, каб скапіяваць "БУМ" у с, то я павінен быў бы вылучыць месца для с. 484 00:37:55,170 --> 00:38:03,900 Я зраблю * S = таНос (SizeOf (Char) * 5); 485 00:38:03,900 --> 00:38:06,210 Чаму 5? 486 00:38:06,210 --> 00:38:10,860 Чаму не 4? Падобна на тое, «БУМ» складае 4 знакаў. >> [Студэнт] нулявой сімвал. 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 [Студэнт] КПЮ? >> ЗЬгсру. 490 00:38:28,520 --> 00:38:32,700 Чалавек зЬгсру. 491 00:38:36,120 --> 00:38:39,590 Так зЬгсру або зЪгпсру. 492 00:38:39,590 --> 00:38:43,410 зЪгпсру трохі бяспечней, паколькі вы можаце дакладна ўказаць, колькі знакаў, 493 00:38:43,410 --> 00:38:46,190 але тут гэта не мае значэння, таму што мы ведаем. 494 00:38:46,190 --> 00:38:50,340 Так зЬгсру і паглядзець у аргументах. 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 Мы збіраемся капіяваць у нашай прызначэння * з паказальнікам «БУМ». 498 00:39:10,310 --> 00:39:19,820 Чаму можа вы хочаце зрабіць гэта з зЬгсру, а не толькі тое, што было раней 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 Цяпер я магу зрабіць нешта накшталт S [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 і другі асобнік «БУМ», зЬгсру стварыў копію "БУМ". 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 Мы проста запусціце яго і мы бачым, мы атрымліваем сегментацыі. 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; ЕдеЬз гэты матэрыял не роўна NULL; 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 , Што, калі вы атрымліваеце сегментацыі, будзе сапраўды загадкавыя імёны функцый 524 00:41:15,350 --> 00:41:18,090 як гэта _IO_fgets. 525 00:41:18,090 --> 00:41:21,770 Але гэта будзе ставіцца да гэтага выкліку ЕдеЬз. 526 00:41:21,770 --> 00:41:25,850 Дзесьці ўнутры тут, мы памылку сегментацыі. 527 00:41:25,850 --> 00:41:30,340 Калі мы паглядзім на аргументы ЕдеЬз, мы можам надрукаваць буфер. 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 Таму, калі я, здараецца, гавораць тут х буфера, ён паказвае мне 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 Размовы тыпу FILE *, так што гэта паказальнік, 545 00:43:22,610 --> 00:43:26,610 і значэнне гэтага паказальніка з'яўляецца нулявым. 546 00:43:26,610 --> 00:43:33,240 Так ЕдеЬз будзе спрабаваць чытаць з гэтага паказальніка, ўскосным чынам, 547 00:43:33,240 --> 00:43:37,320 але для таго, каб атрымаць доступ да гэтага паказальніку, яна павінна разыменовать яго. 548 00:43:37,320 --> 00:43:40,550 Або для таго, каб атрымаць доступ да якой яна павінна быць накіравана на гэта разыменовывает яго. 549 00:43:40,550 --> 00:43:43,810 Так што гэта разнаймення нулявога паказальніка і сегментацыі. 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 Першы радок кода з'яўляецца знак * Файл = "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 і тады я адразу трапляюць у нашу лінію, дзе калісьці я ўдарыў іншы, ён збіраецца падаць. 556 00:44:11,140 --> 00:44:16,880 Хто-небудзь хоча выкінуць з прычын, чаму мы маглі б памылку сегментацыі? 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 Калі мы Еореп файла для чытання, то мы павінны сказаць, 562 00:44:34,700 --> 00:44:45,870 калі (файл == NULL) і сказаць, Е ("Файл не існуе!" 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 Вы заўсёды павінны праверыць, калі Еореп вяртае NULL. 571 00:45:33,870 --> 00:45:38,170 Вы заўсёды павінны праверыць, каб пераканацца, што таНос не вяртае NULL, 572 00:45:38,170 --> 00:45:41,410 , Інакш вы сегментацыі. 573 00:45:42,200 --> 00:45:45,930 >> Цяпер buggy4.c. 574 00:45:49,190 --> 00:45:58,440 Запуск. Я мяркую, што гэта чакае ўводу або, магчыма, бясконцы цыкл. 575 00:45:58,440 --> 00:46:01,870 Так, гэта бясконцы цыкл. 576 00:46:01,870 --> 00:46:05,560 Так buggy4. Падобна на тое, мы бясконцы цыкл. 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 Затым вы можаце выкарыстоўваць п выкарыстоўваць наступную замест таго, каб уводзіць наступны ўсю дарогу. 581 00:46:29,020 --> 00:46:33,730 І зараз, калі я трапіў п раз, то я магу проста націснуць Enter, каб працягваць ісці наступная 582 00:46:33,730 --> 00:46:36,640 замест таго, каб ударыць п Enter, Enter п, п Enter. 583 00:46:36,640 --> 00:46:44,630 Падобна на тое, што я знаходжуся ў нейкі цыкл, што сядзіць масіў [я] = 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 Я буду друкаваць Я, Я = 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 Калі мы проста адлюстроўваць я, ён будзе ставіць тут тое, што значэнне гэта я 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, мы бачым усё, што адбываецца, цэлалікавых масіў [5]; 599 00:48:22,220 --> 00:48:26,200 для (я = 0; I <= SizeOf (масіў), я + +) 600 00:48:26,200 --> 00:48:28,550 Масіў [я] = 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 я павінен быць усталяваны на 0. 618 00:50:16,730 --> 00:50:23,130 [Студэнт] Можа быць, таму што гэта пераазначэнне памяць аб гэтай частцы я 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 нейкім чынам, што прастора, якое мы пераазначэння перавызначаць значэнне я. 622 00:50:39,870 --> 00:50:48,030 І таму, калі мы паглядзім на buggy4, разбіць асноўныя, бег, 623 00:50:48,030 --> 00:50:53,120 Давайце друкаваць адрас я. 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 11с, 120. Масіў [5] bfff124. 629 00:51:14,530 --> 00:51:26,990 Такім чынам, масіў [5] мае той жа адрас, як я, гэта азначае, што масіў [5] я. 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 я аб'яўлены першы, які азначае, што я атрымлівае некаторы прастору ў стэку. 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 Скажам, мы вылучаем я. 644 00:52:53,500 --> 00:52:59,680 Мы вылучаем цэлае я, што азначае, давайце проста скажам, тут я цэлымі атрымлівае вылучаныя. 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 як мы ўсё далей і далей у нашым масіве, мы ўсё бліжэй і бліжэй да нашай цэлае я. 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 , Які быў выдзелены для цэлага я, і мы ўсталёўваем, што на 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 Але C не робіць памылак. Калі я раблю масіў [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 у той час як Java або нешта, вы атрымаеце масіў з індэкса межаў 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 Калі я раблю нешта накшталт Е ("% п \ п", масіў); 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 Clang разумны, і гэта адбываецца заўважыць, што я абвясціў масіў на 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 Вось толькі Clang хітруе. 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 Array, сама пераменная нідзе не захоўваецца. 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 * р = масіве, цяпер р-паказальнік, які паказвае, што масіў, 727 00:59:53,730 --> 00:59:57,830 і цяпер р сапраўды існуе ў стэку. 728 00:59:57,830 --> 01:00:01,950 Я свабодна змяняць р. Я магу зрабіць р = таНос. 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 Калі Clang разумны, ён будзе крычаць на мяне з месца ў кар'ер. 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 Е ("% г \ п", 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 Гэта Clang хітруе зноў. 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 Clang, калі праходзіць праз гэтую функцыю, ён бачыць масіў 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 * р SizeOf (р) у друк 4, 820 01:07:57,470 --> 01:08:04,110 але цэлалікавых масіў [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 * р = масіў; 827 01:08:34,340 --> 01:08:39,779 Унутры гэтай функцыі мы можам у асноўным выкарыстоўваюць р і масіў ў дакладна такой жа спосабамі, 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 (р); 831 01:08:55,600 --> 01:08:59,760 Усярэдзіне функцыі Фу, гэта ж выклік у два разы. 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 Hacker, 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 - я мяркую, што гэта тэрмінал OS або что-то - 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!) Е ("Выкарыстанне:% 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 Так Еореп. Што Еореп выглядаць? 867 01:13:15,010 --> 01:13:22,980 [Студэнт] Імя файла. >> [Боуден] Імя файла будзе ARGV [1]. 868 01:13:22,980 --> 01:13:26,110 [Студэнт] І тое, што вы хочаце з ім рабіць, таму - >> [Боуден] Так. 869 01:13:26,110 --> 01:13:28,740 Так што, калі вы не памятаеце, вы проста маглі б зрабіць чалавек Еореп, 870 01:13:28,740 --> 01:13:32,960 дзе ён будзе константного сімвал шляху *, дзе шлях файла, 871 01:13:32,960 --> 01:13:34,970 сопзЬ сЬаг рэжыме *. 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 п і тое, што вы можаце выкарыстоўваць, каб цыкл праз пошук супадзенняў. 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 Такім чынам, г, Адкрыць тэкставы файл для чытання. Вось што мы хочам зрабіць. 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 Такім чынам, структура будзе тыпу 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 Мы бачым, што ў нас ёсць гэтая tcsetattr Int, Int tcgetattr. 898 01:16:15,810 --> 01:16:22,960 Я праходжу ў termios структуры яго паказальнік. 899 01:16:22,960 --> 01:16:30,640 Як гэта будзе выглядаць гэта - дыскі ўжо забыліся, што такое функцыя была выклікана. 900 01:16:30,640 --> 01:16:34,930 Скапіюйце і ўстаўце яго. 901 01:16:39,150 --> 01:16:45,500 Так tcgetattr, то я хачу перадаць у структуру, што я захавання інфармацыі ў, 902 01:16:45,500 --> 01:16:49,650 які будзе current_settings, 903 01:16:49,650 --> 01:16:59,120 і першым аргументам з'яўляецца дэскрыптар файла для чаго я хачу, каб захаваць атрыбуты. 904 01:16:59,120 --> 01:17:04,360 Што дэскрыптар файла, як і любы раз, калі вы адкрываеце файл, ён атрымлівае дэскрыптар файла. 905 01:17:04,360 --> 01:17:14,560 Калі я Еореп ARGV [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, альбо я магу зрабіць стандартнага ўводу. 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 І як структуры працы ён будзе проста скапіяваць. 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 так ECHO Echo сімвалаў ўваходу. 927 01:18:33,110 --> 01:18:37,710 Спачатку я хачу задаць - дыскі ўжо забыліся, што такое палёў. 928 01:18:45,040 --> 01:18:47,900 Гэта тое, што структура выглядае наступным чынам. 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 Тут мы трапляем у бітавай аператары. 939 01:19:52,280 --> 01:19:54,860 Мы быццам па-за часам, але мы будзем прайсці праз гэта вельмі хутка. 940 01:19:54,860 --> 01:19:56,600 Тут мы трапляем у пабітава аператары, 941 01:19:56,600 --> 01:19:59,950 , Дзе я думаю, што я аднойчы сказаў даўно, што кожны раз, калі вы пачынаеце справу з сцягамі, 942 01:19:59,950 --> 01:20:03,370 Вы збіраецеся выкарыстоўваць аператар пабітава шмат. 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 Такім чынам, каб адключыць гэтую функцыю я і = ¬ ECHO. 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 ECHO будзе адзін біт. 950 01:20:38,440 --> 01:20:44,230 ¬ ECHO будзе азначаць усе біты ўстаноўлены ў 1, што азначае, што усе сцягі устаноўлены на праўдзівы 951 01:20:44,230 --> 01:20:47,140 за выключэннем ECHO няшмат. 952 01:20:47,140 --> 01:20:53,830 Па канчатак майго мясцовага сцягі з гэтым, гэта азначае, што ўсе сцягі, якія ў цяперашні час усталяваны ў праўдзівае 953 01:20:53,830 --> 01:20:56,520 будзе па-ранейшаму устаноўлены на праўдай. 954 01:20:56,520 --> 01:21:03,240 Калі мая ECHO сцяг усталяваны ў сапраўднае, то гэта абавязкова мае значэнне ХЛУСНЯ на ECHO сцяг. 955 01:21:03,240 --> 01:21:07,170 Такім чынам, гэты радок кода проста выключае ECHO сцяг. 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 Гэта, напэўна, лепш прама сказаць стандартнага ўводу. 959 01:21:33,880 --> 01:21:42,100 >> Звярніце ўвагу, што я таксама раблю ECHO | 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 Мы цыкл, працягваючы чытаць адзін знак з файла, 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 Тады риЬспаг толькі збіраецца паставіць знак чытаем тут з файла ў стандартны вывад. 1000 01:24:38,330 --> 01:24:42,890 Вы можаце риЬспаг чалавек, але гэта проста пакласці на стандартны вывад, гэта друк гэтага знака. 1001 01:24:42,890 --> 01:24:51,600 Вы таксама можаце проста зрабіць Е ("% С", С); ж ідэю. 1002 01:24:53,330 --> 01:24:56,670 Гэта збіраецца зрабіць большую частку нашай працы. 1003 01:24:56,670 --> 01:25:00,300 >> Апошняе, што мы збіраемся трэба зрабіць, гэта проста Fclose наш файл. 1004 01:25:00,300 --> 01:25:03,310 Калі вы не Fclose, што гэта ўцечка памяці. 1005 01:25:03,310 --> 01:25:06,680 Мы хочам, каб Fclose файл, які мы першапачаткова адкрыты, і я думаю, што гэта яна. 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', але аргумент тыпу "структура _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 замест стандартнага ўводу, 1025 01:26:55,280 --> 01:27:00,560 якое павінна быць # вызначыць 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 замест стандартнага ўводу 1031 01:27:30,380 --> 01:27:37,480 з'яўляецца тое, што стандартны ўвод з'яўляецца FILE *, які паказвае на тое, што спасылаецца файлавы дэскрыптар 0. 1032 01:27:37,480 --> 01:27:45,070 Так што нават тут, калі я раблю Еореп (ARGV [1], я атрымліваю файл * назад. 1033 01:27:45,070 --> 01:27:51,180 Але дзесьці ў файле * рэч адпаведны файлавы дэскрыптар для гэтага файла. 1034 01:27:51,180 --> 01:27:57,430 Калі вы паглядзіце на даведачнай старонцы для адкрытай, так што я думаю, што вы павінны зрабіць чалавеку адкрыты 3 - Няма - 1035 01:27:57,430 --> 01:27:59,380 Чалавек 2 адкрытых - так. 1036 01:27:59,380 --> 01:28:06,250 Калі вы паглядзіце на старонку адкрытай, адкрытай, як больш нізкага ўзроўню Еореп, 1037 01:28:06,250 --> 01:28:09,350 і ён вяртаецца фактычнае дэскрыптар файла. 1038 01:28:09,350 --> 01:28:12,050 Еореп робіць кучу рэчаў на верхняй адкрытай, 1039 01:28:12,050 --> 01:28:17,640 якія замест вяртання за ўсё, што файлавы дэскрыптар вяртае цэлае FILE * паказальнік 1040 01:28:17,640 --> 01:28:20,590 унутры якой знаходзіцца наша маленькая дэскрыптар файла. 1041 01:28:20,590 --> 01:28:25,020 Такім чынам, стандарт ставіцца да рэчы * FILE, 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]