1 00:00:00,000 --> 00:00:02,520 [Powered by Google Translate] [Частка 4 - больш камфортнай] 2 00:00:02,520 --> 00:00:04,850 [Rob Боуден - Гарвардскі універсітэт] 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 Гэта ў асноўным усё, што вы маглі бачыць у класе або павiнны былi бачыць у сваім класе. 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 але звычайна вы не хвалюйцеся пра гэта, і вы проста кажаце х + 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 [Боуден] Так амперсанда літаральна называецца адрас аператара. 25 00:01:45,300 --> 00:01:50,460 Таму, калі я кажу, і х ён становіцца адрас памяці зменнай х. 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 (* Р). Што гэта робіш? Што азначае, што зорка на ўвазе? 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 Зорка прытрымлівайцеся за стрэлкай, а затым рабіць усё, што вы хочаце з гэтай скрынцы прама там. 36 00:02:46,480 --> 00:03:01,090 Таму я магу сказаць * р = 7, і што пойдзе на скрыню, які з'яўляецца х і змены, якія да 7. 37 00:03:01,090 --> 00:03:13,540 Ці я мог бы сказаць Int г = * р * 2; Гэта зман, таму што гэта зорка, зорка. 38 00:03:13,540 --> 00:03:19,230 Адна зорка разнаймення р, іншая зорка памнажэннем на 2. 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 Так што цяпер P больш не паказвае на х; ён паказвае на г. 44 00:03:44,940 --> 00:03:50,510 І ў любы час я * р гэта так жа, як рабіў г. 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 а затым вы проста разнаймення яго 48 00:04:03,140 --> 00:04:06,060 калі вы маглі б выкарыстоўваць арыгінальны зменную з самага пачатку. 49 00:04:06,060 --> 00:04:18,190 Але калі вы атрымліваеце ў функцыі - так скажам, у нас ёсць некаторыя функцыі, унутр Фу, 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 [Боуден] Вяртае паказальнік, як у нешта накшталт Int у = 3; вяртанне & Y? >> [Студэнт] Так. 63 00:05:44,270 --> 00:05:48,480 [Боуден] Добра. Вы ніколі не павінны гэта рабіць. Гэта дрэнна. 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 і тут у вас ёсць адрас памяці, 4 гігабайтамі або ад 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 Адмова ад адказнасці: Anywhere з 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 куча знаходзіцца на вяршыні самога таксама, так што that's - >> Так. 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 [Студэнт] у жыве ў бары. >> [Боуден] Так. 111 00:09:36,900 --> 00:09:45,010 Дзесьці ў гэтым маленькім квадраце памяці квадратных Литтлер, які мае ў ў ім. 112 00:09:45,010 --> 00:09:53,370 Калі я вярнуся, і ў, я вяртаю паказальнік на гэты невялікі блок памяці. 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 Гэта таксама было б Int бар *, таму што гэта вяртае паказальнік, 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 * у = таНос (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 [Студэнт] Але калі б мы не, мы б да гэтага часу атрымаць 3? 140 00:11:43,080 --> 00:11:44,990 [Боуден] Па ўсёй верагоднасці, вы б. 141 00:11:44,990 --> 00:11:49,670 Але вы не можаце спадзявацца на гэта. C проста кажа нявызначаны паводзіны. 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 Malloc - >> [студэнт] Я думаю, што таНос пазначае блок памяці, які можна выкарыстоўваць у якасці паказальніка. 156 00:13:15,400 --> 00:13:19,610 [Боуден] Я хачу, каб схема зноў. >> [Студэнт] Такім чынам, гэтая функцыя працуе, праўда? 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 >> [Боуден] Так. Такім чынам, калі вы таНос, вы захоп некаторых блок памяці 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 Тыя, на самай справе з'яўляюцца толькі 3 тыпаў памяці, на самай справе. 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 х, памяці вылучаецца для внутр х. 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 у = 3;}. 191 00:15:45,900 --> 00:15:48,440 Гэта павінна быць тут. 192 00:15:48,440 --> 00:15:52,450 Але гэта цалкам вызначае сферу Int у. 193 00:15:52,450 --> 00:15:57,320 Пасля таго, што другі фігурнай дужкай, у не можа быць выкарыстана больш. 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 Вы выдзяленні некаторых кавалак аператыўнай памяці для гэтай зменнай. 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 Але як 2 праграмы магчыма мець паказальнікі на тую ж памяць? 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 >> Так што калі вы запусціце 2 праграмы адначасова, гэтая праграма бачыць 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 фактычных рэчаў на памяць. 220 00:18:20,470 --> 00:18:22,940 Так што да вашай аперацыйнай сістэме ведаць, што, 221 00:18:22,940 --> 00:18:28,080 эй, калі гэты паказальнік хлопец разыменовывает oxbfff, што на самой справе азначае 222 00:18:28,080 --> 00:18:31,040 што ён хоча байт RAM 1000, 223 00:18:31,040 --> 00:18:38,150 а калі гэта 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 гігабайтамі аператыўнай памяці. 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 І такім чынам, вы можаце напісаць любую праграму, якая проста разыменовывает любой паказальнік, 241 00:20:12,140 --> 00:20:19,340 хацеў проста напісаць праграму, якая кажа * (ox1234), 242 00:20:19,340 --> 00:20:22,890 і гэта разнаймення адрас памяці 1234. 243 00:20:22,890 --> 00:20:28,870 >> Але гэта да аперацыйнай сістэмы, каб затым перавесці тое, што 1234 сродкі. 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 і вы сапраўды не выкарысталі гэта, то што, калі вы атрымліваеце нешта накшталт сегментацыі 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 у любым месцы ад Ох0 Ох 8 f's - FFFFFFFF. 258 00:21:46,330 --> 00:21:49,180 [Студэнт] Хіба вы не кажаце, што яны 4 байта? >> Так. 259 00:21:49,180 --> 00:21:52,730 [Студэнт] Тады кожны байт будзе - >> [Боуден] шаснаццатковай. 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 Кожныя 2 лічбы шаснаццатковай 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 Ці ёсць розніца паміж Int і доўга, ці гэта адно і тое ж? 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 стандартная проста кажа, што знак будзе вечна і заўсёды будзе 1 байт. 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 Int проста вызначаецца як больш або роўна кароткі. 310 00:25:31,940 --> 00:25:36,210 І доўга проста вызначаецца як большая ці роўнае Int. 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 Ints амаль заўсёды будзе 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-разрадную сістэму, як Appliance, гэта будзе 4 байт. 321 00:26:34,530 --> 00:26:42,570 Калі вы выкарыстоўваеце 64-разрадную, як шмат апошніх кампутарах, гэта будзе 8 байт. 322 00:26:42,570 --> 00:26:45,230 >> Ints амаль заўсёды 4 байта ў гэтай кропцы. 323 00:26:45,230 --> 00:26:47,140 Доўгія доўгія, амаль заўсёды 8 байт. 324 00:26:47,140 --> 00:26:50,300 У мінулым цэлыя выкарыстаны толькі быць 2 байта. 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 Зараз вы зможаце выкарыстоўваць 9 лічбаў або 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 [Боуден] Здаецца - >> [студэнт] Якая сітуацыя? 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 >> . C файл, проста павінен змяшчаць функцый. 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 яно спалучае ў сабе гэтыя 2 двайковых файлаў у выкананы файл. 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 І адказ быў ілжывым, і я зразумеў, чаму гэта не так, як Clang. 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 тое, што робіць збіраецца зрабіць, гэта проста перакампілявання, што 1 файл 401 00:32:47,870 --> 00:32:50,640 , А затым паўторна звязаць усе разам. 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 Вы можаце напісаць зрабіць файл, так што, калі вы ўводзіце зрабіць гэта толькі кампакт-дыскі ў іншы каталог. 407 00:33:09,150 --> 00:33:15,560 Я расчараваныя, таму што я трэка ўнутры ўсе мае Appliance 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 і сервер падлучыцца да маё Appliance, а затым я адкрываю PDF 411 00:33:36,950 --> 00:33:40,190 , Які атрымлівае складзены LaTeX. 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, выкарыстоўвайце Clang. 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 гэта кампакт-дыскаў у каталогу і робіць іншыя рэчы, 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 * х * У - 435 00:35:24,890 --> 00:35:28,130 Гэта не зусім тут нічога, я думаю. 436 00:35:28,130 --> 00:35:32,140 Але, як і * х * у, тыя 2 зменныя, якія знаходзяцца на стэку. 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 Многія людзі блытаюць і кажуць Int * х = таНос; х у кучу. 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 [Студэнт] Гэта ідзе ад C у двайковы фармат. 468 00:38:28,210 --> 00:38:30,970 >> [Боуден] Гэта не прайсці ўвесь шлях у двайковы фармат. 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 Такім чынам, складанне збіраецца вывесці яго з C Асамблеі. 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 на самай справе не аб файле, але гэта досыць блізка, што няма ніякай прынцыповай розніцы. 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 Вам толькі трэба перакампіляваць, што 1. З файла, а затым перелинковки ўсё астатняе, 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, як я, я <п; Int J, J <п - >> [студэнт] п квадрат. >> Ён мае тэндэнцыю быць паказаны ў квадраце. 535 00:44:22,260 --> 00:44:25,280 Калі вы патройны ўкладзены, ён, як правіла, п кубе. 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 Гэта лягчэй зразумець, чаму яны з'яўляюцца п квадратаў і п § п і ўсё, што 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 Вы можаце проста сказаць, што гэта рабіць гэта і гэта. Гэта п квадрат. 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 Для кожнага элемента масіва, які будзе нешта, што п ў квадраце. 550 00:45:45,370 --> 00:45:49,940 Ёсць агульныя пытанні, напрыклад, прама тут, у нас - Oh. 551 00:45:55,290 --> 00:45:58,530 Літаральна на днях, Дуг заявіў: "Я вынайшаў алгарытм, які можа сартаваць масіў 552 00:45:58,530 --> 00:46:01,780 "П лікаў у O (часопіс N) раз!" 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 так што гэта немагчыма зрабіць гэта менш чым за O н. 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 І that's - Я забыўся, што that's - Хіба падліку роду? 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 Так. Гэтыя тыпы відаў, якія могуць выканаць рэчы ў вялікай O н. 565 00:47:13,000 --> 00:47:18,430 Але ёсць абмежаванні, як вы можаце выкарыстоўваць толькі цэлыя лікі да вызначанага ліку. 566 00:47:20,870 --> 00:47:24,560 Плюс, калі вы спрабуеце разабрацца нешта that's - 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 [Боуден] Так. 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 у канчатковым выніку ён будзе працаваць у кучу і тады вы атрымаеце памылку сегментацыі 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 Гэтыя аперацыі, замяніўшы, што 1 значэнне ў стэку і скача назад да пачатку, 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 і дэмантажу і ўсе гэтыя рэчы. 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 [Студэнт], калі бар (х + 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) неабходна вярнуць для таго, каб вылічыць, што ў 2 разы значэння, 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 [Боуден] У ідэальным свеце, але ў 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 * у. 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 Паказальнік арыфметыка. 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 Давайце проста скажам, сімвал * S = "прывітанне". 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 І знак * S будзе паказваць на пачатак гэтага масіва. 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], гэта будзе ёй і падлік 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 [Студэнт] І мы маглі б дасягнуць такога ж значэння, робячы з + 3, а затым дужкі зоркі? 657 00:55:20,460 --> 00:55:22,570 Так. 658 00:55:22,570 --> 00:55:26,010 Гэта эквівалентна * (S + 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 [Боуден], што збіраецца стварыць 4 цэлых лікаў у стэку, таму 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 складае іх, і разыменовывает. 680 00:57:07,970 --> 00:57:14,710 Так што гэта толькі ж сілу, як * (S + 3) ці з [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-мерны масіў знаходзіцца ўсяго ў 1-мерны масіў з некаторым зручны сінтаксіс 684 00:57:34,720 --> 00:57:54,110 таму што, калі я кажу Int х [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 * р = х; 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 Але гэта ўсяго толькі Int *. 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 , Які, калі мы паглядзім на тут скажам, гэта наша памяць, 722 01:01:09,010 --> 01:01:16,600 калі ў мяне ёсць 2 гігабайта аператыўнай памяці, гэта сапраўды адрасе 0 як нулявы байт маёй памяці, 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 >> [Боуден] Гэты тып масіва, як правіла, у стэку 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 Ён збіраецца стварыць 4-цэлы лік блокаў у стэку для гэтага масіва. 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 з паказальнікамі, што вы можаце зрабіць нешта накшталт, скажам, Int ** рр = таНос (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 Я мог бы сказаць п.п. [3] [4], але цяпер гэта не тое ж самае, шматмерныя масівы 773 01:06:58,030 --> 01:07:05,390 таму што шматмерныя масівы ў яе перакладзе [3] [4] у адну зрушэнне ў масіве х. 774 01:07:05,390 --> 01:07:14,790 Гэта разыменовывает р, доступ да трэцяга індэкса, то, што разыменовывает 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 Вы вынікаеце 2 асобныя паказальнікі. 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 [Студэнт] Калі ў мяне ёсць Int *** р а затым я разнаймення, і я кажу р * роўная гэтаму значэнні, 791 01:08:35,649 --> 01:08:39,560 гэта толькі збіраецца зрабіць 1 ўзровень разнаймення? >> Так. 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 >> [Боуден] І калі яны былі 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 Паказальнік арыфметыка. 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 Таму, калі я кажу нешта накшталт X [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 на самай справе азначае зрушэнне 1 807 01:10:08,470 --> 01:10:12,030 раз памер незалежна ад тыпу масіва. 808 01:10:12,030 --> 01:10:17,170 Гэта масіў цэлых лікаў, таму ён ведае, што трэба рабіць 1 раз памер Int, калі ён хоча, каб кампенсаваць. 809 01:10:17,170 --> 01:10:25,260 Іншы сінтаксіс. Памятаеце, што гэта эквівалентна * (х + 1); 810 01:10:25,260 --> 01:10:35,250 Калі я кажу паказальнік + 1, тое, што вяртае гэта адрас, што паказальнік захоўвання 811 01:10:35,250 --> 01:10:40,360 плюс 1 раз памер тып паказальніка. 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, ён глядзіць на C, гэта знакавы паказальнік, так што ён збіраецца дадаць 1 разы памер сімвалаў, 819 01:11:45,390 --> 01:11:48,110 які заўсёды будзе на 1, так што вы атрымаеце 101, 820 01:11:48,110 --> 01:11:54,890 а калі я зраблю х, якая таксама яшчэ 100, х + 1 будзе 104. 821 01:11:56,660 --> 01:12:06,340 [Студэнт] Ці можна выкарыстоўваць C + +, у мэтах прасоўвання паказальніка на 1? 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 Калі з проста Int *, то 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 [Студэнт] паказальнік + 2? 835 01:13:26,590 --> 01:13:29,350 [Боуден] Такім чынам, х + 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 [Студэнт] Калі мы не будзем ставіць амперсанда або - што, што называецца? >> Star? 846 01:14:20,050 --> 01:14:23,200 [Студэнт] Star. >> Тэхнічна, аператар разнаймення, але - >> [студэнт] Dereference. 847 01:14:23,200 --> 01:14:29,310 >> Калі мы не ставім зоркі або амперсанда, што адбудзецца, калі я проста скажу, у = х і х з'яўляецца паказальнікам? 848 01:14:29,310 --> 01:14:34,620 Які тып у? >> [Студэнт] Я проста кажу, што гэта паказальнік 2. 849 01:14:34,620 --> 01:14:38,270 Так што калі вы толькі што сказалі у = х, зараз х і ў паказваюць на адно і тое ж. >> [Студэнт] паказваюць на тое ж самае. 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 * х - сапраўды ўсё х захоўвання нешта накшталт ox100, 854 01:15:02,010 --> 01:15:06,490 якія мы, здараецца, якія прадстаўляюць як указанне на блоку захоўваецца 100. 855 01:15:06,490 --> 01:15:19,660 Таму калі я кажу Int * у = х, я проста капіяванне ox100 у у, 856 01:15:19,660 --> 01:15:24,630 якія мы толькі збіраемся прадставіць як у, таксама паказваючы на ​​ox100. 857 01:15:24,630 --> 01:15:39,810 І калі я кажу Int я = (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 Гэта збіраецца быць ліцця Int х ці ліццё Int у? 862 01:16:00,290 --> 01:16:03,700 [Боуден] Што? 863 01:16:03,700 --> 01:16:07,690 [Студэнт] Добра. Пасля гэтых дужках там будзе х ці ау там? 864 01:16:07,690 --> 01:16:11,500 >> [Боуден] Альбо. х і ў з'яўляюцца эквівалентнымі. >> [Студэнт] Добра. 865 01:16:11,500 --> 01:16:14,390 Таму што яны абодва паказальніка. >> Так. 866 01:16:14,390 --> 01:16:21,050 [Студэнт] Таму было б захоўваць шаснаццатковае цэлы лік 100 у форме? >> [Боуден] Так. 867 01:16:21,050 --> 01:16:23,620 Але не значэнне таго, што гэта паказвае. 868 01:16:23,620 --> 01:16:29,940 [Боуден] Так. >> [Студэнт] Такім чынам, толькі адрас у цэлалікавых выглядзе. Добра. 869 01:16:29,940 --> 01:16:34,720 [Боуден] Калі вы хацелі б па некаторай дзіўнай прычыне, 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 ў гэтай адвольнай * Int. 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 падабаецца, калі ў вас ёсць паказальнік, і вы кінулі яго ў выглядзе цэлага ліку? 882 01:17:39,230 --> 01:17:44,860 [Боуден] Вы сапраўды можаце проста друкаваць, выкарыстоўваючы як Printf. 883 01:17:44,860 --> 01:17:50,300 Скажам, у мяне ёсць Int у = 100. 884 01:17:50,300 --> 01:18:02,700 Такім чынам, Е (% г \ п - як вы ўжо ведаеце - друк, што як цэлае, х%. 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]