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