[Powered by Google Translate] [Дел 4 - поудобно]
[Роб Бауден - Универзитетот Харвард]
[Ова е CS50. - CS50.TV]
Имаме квиз утре, во случај да сте момци не го знаев тоа.
Тоа е основа на сè што можеше да се види во класа или треба да се гледа во класата.
Тоа вклучува совети, иако тие се многу свежи тема.
Вие најмалку треба да се разбере високи нивоа на нив.
Нешто што немаше повеќе во класа треба да се разбере за квиз.
Значи, ако имате прашања во врска со нив, можете да ги прашате сега.
Но, ова ќе биде многу предводени од студентите сесија каде вие ​​момци поставуваат прашања,
па се надевам дека луѓето имаат прашања.
Дали некој има прашања?
Да. >> [Студент] можете да одите преку покажувачи повторно?
Јас ќе одам преку покажувачи.
Сите ваши променливи мора да се живее во меморијата,
но обично не се грижите за тоа и ќе речеме x + 2 и y + 3
и компајлерот ќе дознаам каде работите се живее за вас.
Откако ќе бидете занимаваат со покажувачи, сега сте експлицитно користење на овие мемориски адреси.
Значи една променлива ќе само некогаш живее во една адреса во било кое дадено време.
Ако сакаме да се изјасни за покажувач, што е од типот ќе изгледа?
>> Сакам да прогласи покажувачот стр. Што значи типот изгледа?
[Студент] int * стр. >> Да. Значи int * стр.
И како можам да го прават тоа точка да х? >> [Студент] симболот.
[Бауден] Значи симболот е буквално вика адреса на операторот.
Значи, кога велам & х станува меморија адресата на променливата x.
Па сега имам покажувачот p, и насекаде во мојот код можам да користам * P
или би можел да го користите X и тоа ќе биде иста работа.
(* М). Што е тоа го прават? Што значи дека ѕвездата значи?
[Студент] Тоа значи вредност во тој момент. >> Да.
Значи, ако ние се погледне во него, тоа може да биде многу корисно да се извлече дијаграми
кога тоа е мала кутија на меморија за x, што се случува да имаат вредност 4,
тогаш имаме мала кутија на меморија за P,
и така стр поени за x, па ние привлече стрела од стр до x.
Значи, кога велиме * p ние велиме одат во кутија која е p.
Ѕвезда е да се следат стрелките, а потоа правите што сакате со таа кутија право таму.
Па можам да кажам * P = 7; и дека ќе оди во кутија која е x и промена која до 7.
Или би можел да каже int z = * P * 2, тоа е збунувачки, бидејќи тоа е ѕвезда, ѕвезда.
На една ѕвезда е dereferencing стр, другата ѕвезда се размножуваат со 2.
Забележиш јас би можеле да имаат исто како и заменува * P со x.
Можете да ги користите на ист начин.
А потоа подоцна можам да стр точка за нешто сосема ново.
Јас само може да се каже p = &z;
Па сега p повеќе не укажува на x, тоа укажува на ●.
И во секое време јас * P тоа е исто како прави z.
Па корисна работа за ова е еднаш ние започне да добива во функции.
>> Тоа е вид на бескорисни да се изјасни покажувач што укажува на нешто
а потоа сте само да го dereferencing
кога ќе може да се користат оригиналната променлива да почне.
Но кога ќе влезат во функции - па да речеме имаме некои функција, int foo,
кој ги зема покажувач и само не * P = 6;
Како што видовме досега со трампа, не можете да направите ефективен swap и посебна функција
од само поминува цели броеви, бидејќи сè во C е секогаш поминува вредност.
Дури и кога сте донесување совети сте праќање по вредност.
Тоа само така се случува, дека тие вредности се мемориски адреси.
Значи, кога велам foo (P), јас сум полагање на покажувачот во функција foo
а потоа foo е тоа * P = 6;
Па внатрешноста на таа функција, * p е уште еквивалентно на x,
но не можам да го користите X внатрешноста на таа функција, бидејќи тоа не е scoped во рамките на таа функција.
Значи * P = 6 е единствениот начин можам да влезам во локална променлива од друга функција.
Или, добро, показалки се единствениот начин можам да влезам во локална променлива од друга функција.
[Студент] Да речеме дека сака да се врати на покажувачот. Како точно правиш тоа?
[Бауден] Врати покажувач како и во нешто како int y = 3; враќање & Y? >> [Студент] Да.
[Бауден] Во ред. Никогаш не треба да го направите тоа. Ова е лошо.
Мислам дека го видов во овие предавање слајдови сте почнале да гледаат целата оваа дијаграм на меморија
каде се тука имаш меморија адреса 0
и овде имаш меморија адреса 4 свирки или 2 до 32.
Па тогаш имаш некои работи и некои работи, а потоа имате вашиот магацинот
и имаш вашиот грамада, која само што почнав учење за, растат.
[Студент] не е грамада над магацинот?
>> Да. Грамада е на врвот, не е тоа? >> [Студент] Па, тој ја стави 0 на врвот.
[Студент] Ох, тој ја стави 0 на врвот. >> [Студент] О, во ред.
Општи услови: Насекаде со CS50 си оди за да се види тоа на овој начин. >> [Студент] Во ред.
Тоа е само дека кога сте првото гледање Купишта,
како кога ќе помислите на магацинот мислите за редење работи на врвот на една со друга.
Значи ние се стремат да флип оваа околу толку магацинот расте како оџак нормално би
наместо на магацинот виси надолу. >> [Студент] Не купишта технички пораснат премногу, иако?
Тоа зависи од она што го подразбираме под порасне.
Магацинот и грамада секогаш расте во спротивни насоки.
Комплет е секогаш растат во смисла дека тоа е растат
кон повисоки мемориски адреси, и грамада расте надолу
по тоа што постојано расте кон пониска мемориски адреси.
Значи, на врвот е 0 и на дното е висок меморија адреси.
Тие се двете расте, само во спротивни насоки.
[Студент] Јас само значеше дека бидејќи ти рече да се стави магацинот на дното
бидејќи се чини дека повеќе интуитивна, бидејќи за оџакот да се започне на врвот на грамада,
грамада е на врвот на себе, па that's - >> Да.
Можете исто така мислам на грамада како растат и поголеми, но на магацинот повеќе.
Така магацинот е онаа која ние вид на посакате да ја прикажете растат.
Но, насекаде барате друг начин ќе покаже адреса 0 на врвот
и највисока меморија адреса на дното, така што ова е вашата вообичаена слика на меморијата.
>> Дали имате некое прашање?
[Студент] Може ли да ни кажете нешто повеќе за грамада?
Да. Ќе дојдеме до тоа во една секунда.
Прво, да се вратам зошто враќање и y е лоша работа,
на магацинот имате еден куп на магацинот рамки кои претставуваат сите функции
кој се нарекува.
Па игнорирајќи претходните нешта, на врвот на вашиот оџакот е секогаш ќе биде главната функција
бидејќи тоа е првата функција и тоа е се нарекува.
И тогаш кога ќе се јавите друга функција, на магацинот ќе растат надолу.
Значи, ако јас го нарекувам некои функција, foo, а тоа добива свој магацинот рамка,
тоа може да се јавите некоја функција, бар, таа добива свој магацинот рамка.
И бар може да биде рекурзивен а тоа би можело да се јавите,
и така што вториот повик за бар ќе добие свој магацинот рамка.
И така она што се случува во овие магацинот рамки се сите локални променливи
и сите на функцијата аргументи дека -
Секое работи кои се локално scoped на оваа функција одат во овие магацинот рамки.
Па тоа значи дека кога реков нешто како бар е функција,
Јас сум само ќе прогласи цел број, а потоа се врати на покажувачот во тој број.
Значи каде y живеат?
[Студент] y живее во бар. >> [Бауден] Да.
Некаде во оваа мала квадратна на меморија е квадратен littler дека има y во неа.
Кога ќе се вратам & Y, јас сум враќа покажувач кон овој мал блок од меморија.
Но, тогаш кога функцијата се враќа, неговите магацинот рамка добива појави надвор од магацинот.
И затоа се вика оџак.
Тоа е како на магацинот податочна структура, ако знаеш што е тоа.
Или дури и како магацинот на пепелниците е секогаш пример,
Главната се случува да одам на дното, а потоа на првата функција ти се јавам се случува да одам на врвот на тоа,
и не можете да се вратите назад на главната додека не се врати од сите функции кои се нарекуваат
кои биле сместени на врвот на неа.
>> [Студент] Па ако не го правел врати и y, таа вредност е предмет на промена без најава.
Да, it's - >> [студент] Тоа може да бидат препишани. >> Да.
Тоа е целосно - Ако се обидете и -
Ова исто така ќе биде int * бар, бидејќи тоа е враќање на покажувачот,
па нејзиното враќање тип е int *.
Ако се обидете да го користите на повратната вредност на оваа функција, тоа е недефинирано однесување
затоа што покажувач укажува на лоша меморија. >> [Студент] Во ред.
Па што ако, на пример, ќе прогласи int * y = Примерок (sizeof (int))?
Тоа е подобро. Да.
[Студент] Ние разговаравме за тоа како кога ќе повлечете работи на нашите ѓубрето
тие не се всушност избришани, ние само ги загубат своите совети.
Значи во овој случај ние всушност ги избрише вредноста или тоа е сè уште таму во меморијата?
За најголем дел, тоа се случува дека сè уште се таму.
Но, ајде да речеме дека ние се случи да се јавам на некои други функции, Баз.
Баз ќе добие свој магацинот рамка за тука.
Тоа се случува да се пребрише сите на овој материјал,
а потоа ако подоцна се обиде и да ги користите покажувачот што сте ја добиле пред,
тоа нема да биде иста вредност.
Тоа се случува да се промени само поради тоа што се нарекува функцијата baz.
[Студент], но не и ние ќе можеме уште се 3?
[Бауден] Во сите веројатноста, ќе.
Но вие не може да се потпре на тоа. Ц само вели недефинирано однесување.
>> [Студент] О, тоа го прави. Во ред.
Па кога ќе сакаат да се вратат покажувач, ова е местото каде Примерок доаѓа во употреба.
Го пишувам всушност само се врати Примерок (3 * sizeof (int)).
Ние ќе одиме во текот Примерок повеќе во секунда, но идејата за Примерок е сите на вашите локални променливи
секогаш одат на магацинот.
Нешто што е malloced оди на куп, и тоа засекогаш и секогаш ќе биде на грамада
додека не се експлицитно го ослободи.
Значи ова значи дека кога ќе Примерок нешто, тоа се случува да преживее по функција се враќа.
[Студент] Ќе преживее по завршување на програмата ќе престане да работи? >> Бр
Океј, па тоа нема да биде таму до програмата е целиот пат направено трчање. >> Да.
Можеме да одиме над детали за она што се случува кога на програмата ќе престане да работи.
Можеби треба да ме потсетува, но тоа е посебна работа целосно.
[Студент] Значи Примерок создава покажувачот? >> Да.
Примерок - >> [студент] Мислам Примерок означува блок на меморијата која покажувач може да се користи.
[Бауден] Сакам дијаграм повторно. >> [Студент] Значи оваа функција работи, иако?
[Студент] Да, Примерок означува блок од меморија, која може да се користи,
а потоа се враќа на адреса на првиот блок на таа меморија.
>> [Бауден] Да. Па кога ќе Примерок, ти си грабање некои блок од меморија
кој во моментов е во грамада.
Ако грамада е премногу мал, тогаш грамада е само ќе расте и расте во оваа насока.
Па да речеме грамада е премногу мал.
Тогаш тоа е за да расте малку и да се врати покажувач на овој блок кој едноставно се зголеми.
Кога ќе бесплатни работи, ти си прави повеќе простор во грамада,
па потоа подоцна се јавите за да Примерок да повторна употреба дека меморијата што претходно ослободени.
Најважно за Примерок и слободен е во тоа што ви дава комплетна контрола
во текот на животот на овие мемориски блокови.
Глобални променливи се секогаш жив.
Локалните променливи се живи во нивниот делокруг.
Веднаш штом ќе одат минатото голема заграда кадрава, на локални променливи се мртви.
Malloced меморија е жив, кога сакате да се биде жив
а потоа е ослободен кога ќе го кажам да бидат објавени.
Тоа се всушност само 3 типа на меморија, навистина.
Има автоматско управување со меморијата, која е на магацинот.
Работите да се случат за вас автоматски.
Кога ќе се каже int x, меморија се доделува за int x.
Кога x оди надвор од опсегот, меморија е рекултивираните за x.
Потоа, тука е динамичка меморија за управување, што е она што Примерок е,
што е кога имате контрола.
Можете динамички одлучи кога меморија треба и не треба да се распределени.
А потоа, тука е статична, што само значи дека живее засекогаш,
што е она што глобални променливи се.
Тие се само секогаш во меморијата.
>> Прашања?
[Студент] можете да дефинирате блок само со помош на големи загради
но не мора да имаат, ако изјавата или додека изјава или нешто слично?
Можете да дефинирате блок, како и во функција, но кој има кадрави загради премногу.
[Студент] Значи не само да имаат како случаен пар на тркалезните загради во вашиот код
кои имаат локални променливи? >> Да, можеш.
Внатрешноста на int бар може да имаме {int y = 3;}.
Тоа би требало да биде во право тука.
Но, тоа целосно го дефинира обемот на int y.
По тој втор кадрава голема заграда, y не може да се користи веќе.
Можете речиси никогаш не го направи тоа, иако.
Прв назад кон она што се случува кога некоја програма завршува,
таму е вид на заблуда / половина лага дека ние даде со цел само да ги олесни работите.
Ние ти кажам дека кога ќе алоцира меморија
сте распределба некои парче на RAM меморија за таа променлива.
Но вие не сте навистина директно допирање на RAM меморија некогаш во вашите програми.
Ако мислите дека за тоа, како што го изведов -
И всушност, ако одите преку во GDB ќе видите истото.
Без оглед на тоа колку пати ќе се кандидира на вашиот програма или она што програмата си работи,
магацинот е секогаш ќе започне -
ти си секогаш ќе видите променливи околу адреса oxbffff нешто.
Тоа е обично некаде во тој регион.
Но, како може 2 програми можеби имаат совети за истата меморија?
[Студент] Има некои произволни ознаки од каде oxbfff би требало да биде на RAM меморија
кои, всушност, може да биде во различни места во зависност од кога функцијата се нарекува.
Да. Терминот е виртуелна меморија.
Идејата е дека секој процес, секој програма која се извршува на Вашиот компјутер
има свои - да претпоставиме 32 битови - целосно независна просторот за адреси.
Ова е адресата простор.
Таа има своја сосема независни 4 гигабајти за употреба.
>> Значи, ако се кандидира 2 програми истовремено, оваа програма ја гледа 4 гигабајти за себе,
оваа програма го гледа 4 гигабајти за себе,
и тоа е невозможно за оваа програма да Dereference покажувач
и завршуваат со меморија од оваа програма.
И она што виртуелната меморија е е мапирање од процесите на просторот за адреси
на вистинските нешта на RAM меморија.
Па тоа е до вашиот оперативен систем да се знае дека,
еј, кога овој човек dereferences покажувачот oxbfff, тоа навистина значи
дека сака RAM меморија бајт 1000,
а ако оваа програма dereferences oxbfff, тој навистина сака RAM меморија бајт 10000.
Тие можат да бидат произволно далеку.
Ова важи дури и работи во рамките на еден процес на просторот за адреси.
Па како го гледа сите 4 гигабајти за себе, но да речеме -
[Студент] Дали секој процес -
Да речеме имате компјутер со само 4 гигабајти на RAM меморија.
Дали секој процес видите целата 4 гигабајти? >> Да.
Но, 4 гигабајти го гледа е лага.
Тоа е само тоа мисли дека има сето ова меморија, бидејќи таа не знае кој било друг процес постои.
Тоа само ќе го користи како многу меморија, како тоа всушност треба.
Оперативниот систем не се случува да им даде на RAM меморија на овој процес
ако тоа не е користење на било меморија во оваа целиот регион.
Тоа нема да го даде меморија за тој регион.
Но, идејата е дека - Јас се обидувам да мислам на - Јас не можат да мислат на аналогија.
Аналогии се тешки.
Едно од прашањата на виртуелна меморија или една од работите тоа е решавање на
е дека процесите треба да биде свесен за една со друга.
И така можете да напишете било програма со која само dereferences било покажувач,
како само напише програма која се вели * (ox1234)
и тоа е dereferencing меморија адреса 1234.
>> Но тоа е до оперативниот систем за да потоа се преведе она што 1234 средство.
Значи, ако 1234 случува да биде валидна меморија адреса за овој процес,
како што е на магацинот или нешто, тогаш тоа ќе се врати вредноста на таа меморија адреса
што се однесува до процесот знае.
Но, ако 1234 не е валидна адреса, како што тоа се случува да слета
во некои малку парче од меморијата тука дека е надвор од оџакот и надвор од грамада
и не сте навистина се користи тоа, тогаш тоа е кога ќе се работи како segfaults
затоа што ти си допирање меморија дека не треба да се допира.
Ова е исто така точно -
А 32-битен систем, 32 бита значи дека имате 32 бита за да се дефинира мемориска адреса.
Тоа е зошто покажувачи се 8 бајти, бидејќи 32 бита се 8 бајти - 4 бајти.
Покажувачи се 4 бајти.
Па кога ќе видите покажувач како oxbfffff, тоа е -
Во рамките на секоја програма што само може да се изгради какво било произволно покажувач,
насекаде од ox0 да вол 8 f's - ffffffff.
[Студент] не ви велат дека тие се 4 бајти? >> Да.
[Студент] Тогаш секој бајт ќе има - >> [Бауден] Хексадецимално.
Хексадецимален - 5, 6, 7, 8. Значи совети ви се случува да секогаш се види во хексадецимално.
Тоа е само како се класифицираат совети.
Секои 2 цифри од хексадецимални е 1 бајт.
Па таму ќе биде 8 хексадецимални цифри за 4 бајти.
Значи секој покажувач на 32-битен систем ќе биде 4 бајти,
што значи дека во вашиот процес, можете да конструирате какво било произволно 4 бајти
и да се направи покажувачот надвор од неа,
што значи дека колку што е познато, таа може да разреши една цела 2 до 32 бајти меморија.
Иако тоа не навистина имаат пристап до тоа,
дури и ако вашиот компјутер има само 512 мегабајти, тоа мисли дека тоа е дека многу меморија.
И на оперативниот систем е доволно паметни за тоа што само ќе одвои она што всушност треба.
Тоа не само одат, ох, нов процес: 4 свирки.
>> Да. >> [Студент] Што значи вол значи? Зошто ви го пишувам?
Тоа е само симбол за хексадецимален.
Кога ќе видите голем број на проектот со вол, последователни работи се хексадецимален.
[Студент] Вие беа објаснување за она што се случува кога некоја програма завршува. >> Да.
Што се случува кога некоја програма завршува е оперативен систем
само брише мапирање тоа што има за овие адреси, и тоа е тоа.
Оперативниот систем може сега само му даде на меморија на друга програма да го користите.
[Студент] Во ред.
Па кога ќе одвои нешто на грамада или магацинот или глобални променливи или ништо,
сите тие само исчезне штом програмата завршува
затоа што оперативниот систем е сега слободен да му даде на меморија за кој било друг процес.
[Студент] Иако постојат веројатно уште вредностите напишани во? >> Да.
Вредностите се веројатно уште таму.
Тоа е само дека ќе биде тешко да се добие во нив.
Тоа е многу потешко да се добие во нив отколку што е да се добие на избришани датотеки
бидејќи избришани датотеки вид на седи таму за долго време и на хард дискот е многу поголем.
Па затоа се случува да запишувате врз различни делови на меморија
пред тоа се случува да се замени дел од меморија што таа датотека се користи да биде.
Но, главната меморија, RAM меморија, кружите низ многу побрзо,
па затоа се случува да многу брзо да бидат препишани.
Прашања во врска со овој или нешто друго?
[Студент] Имам прашања во врска со различна тема. >> Океј.
Дали некој има прашања за тоа?
>> Во ред. Различна тема. >> [Студент] Во ред.
Ќе одам преку некои од пракса тестови,
а во една од нив беше зборуваме за sizeof
и вредноста која ја враќа или различни променлива видови. >> Да.
И таа рече дека двете int и долго и враќање 4, па и тие се двете 4 бајти долго.
Има ли разлика меѓу int и долго, или тоа е иста работа?
Да, постои разлика.
С стандард -
Јас сум веројатно нема да се плеткаш.
С стандард е исто како она што C е, официјалната документација на В
Ова е она што го кажува.
Значи C стандард само вели дека знак засекогаш и секогаш ќе биде 1 бајт.
Сè што после тоа - краток е секогаш само се дефинирани како е поголема или еднаква на знак.
Ова може да биде строго поголем од, но не и позитивни.
Еден int е само дефинирани како е поголема или еднаква на кратко.
И долго е само дефинирани како е поголема или еднаква на инт.
И долго долго е поголема или еднаква на долг.
Значи единственото нешто на C стандардот дефинира е релативна нарачување на сè.
На реалниот износ на меморија што работи потрае генерално е до имплементација,
но тоа е прилично добро дефинирани во овој момент. >> [Студент] Во ред.
Значи шорцеви се речиси секогаш ќе биде 2 бајти.
Ints се речиси секогаш ќе биде 4 бајти.
Долго копнее се речиси секогаш ќе биде 8 бајти.
И копнее, тоа зависи од тоа дали сте со користење на 32-битна или 64-битен систем.
Па долго ќе одговараат на типот на системот.
Ако користите 32-битен систем како апарати, тоа ќе биде 4 бајти.
Ако сте со користење на 64-битна како многу последниве компјутери, тоа ќе биде 8 бајти.
>> Ints се скоро секогаш 4 бајти во овој момент.
Долго копнее се скоро секогаш 8 бајти.
Во минатото, ints користи за да биде само 2 бајти.
Но забележите дека ова целосно ги задоволува сите овие односи на поголема од и еднаков.
Толку долго се совршено дозволено да бидат со иста големина како цел број,
и тоа е, исто така, е дозволено да бидат со иста големина како долго долго.
И тоа само така се случува да биде дека во 99,999% од системи, тоа ќе биде еднаква на
ниту една int или долго долго. Тоа само зависи од 32-bit или 64-битна. >> [Студент] Во ред.
Во плови, како е на децимална точка назначени во однос на битови?
Како што се бинарни? >> Да.
Вие не треба да се знае дека за CS50.
Вие дури и не научат дека во 61.
Вие не научат дека навистина во секој курс.
Тоа е само претстава.
Заборавам точната малку allotments.
Идејата на подвижна точка е дека доделат одреден број на битови да претставуваат -
Во суштина, сè е во научна нотација.
Така да доделат одреден број на битови да претставува број себе, како 1,2345.
Јас никогаш не може да претставува број со повеќе цифри од 5.
Тогаш исто така додели одреден број на битови, така што тоа се стреми да биде како
можете само да одите до одреден број, како што е најголемиот показател ќе може да има,
а вие само може да оди надолу до одреден степен,
како што е најмалиот експонент можете да го имаат.
>> Јас не се сеќавам на точниот начин битови се доделуваат на сите овие вредности,
но одреден број на битови се посветени на 1,2345,
друг одреден број на битови се посветени на експонент,
и тоа е можно само да се претставува експонент на одредена големина.
[Студент] и двојно? Е дека како екстра долго плови? >> Да.
Тоа е истото како рационален освен сега сте со користење 8 бајти, наместо на 4 бајти.
Сега ќе можете да го користите 9 цифри, или 10 цифри,
и тоа ќе биде во можност да одат до 300 наместо 100. >> [Студент] Во ред.
И плови уште 4 бајти. >> Да.
Па, повторно, тоа веројатно зависи целокупната на општата имплементација,
но плови се 4 бајти, двојки се 8.
Двојки се нарекуваат двојно бидејќи тие се двојно големината на плови.
[Студент] Во ред. И се има двојно двојки? >> Не постојат.
Мислам - >> [студент] Како долго копнее? >> Да. Јас не мислам така. Да.
[Студент] На тест минатата година имаше прашање за главната функција
мора да биде дел од вашата програма.
Одговорот беше дека тоа не мора да биде дел од вашата програма.
Во она ситуација? Тоа е она што го видов.
[Бауден] Се чини - >> [студент] Што ситуација?
Имате проблем? >> [Студент] Да, јас дефинитивно може да го повлече.
Тоа не мора да биде технички, но во основа тоа се случува да биде.
[Студент] видов една на друга година.
Тоа беше како Вистински или лажни: Валидна - >> О, в датотека.?
. [Студент] Секое в датотеката мора да имаат - [двете зборува одеднаш - неразбирливо]
Во ред. Значи тоа е посебен.
>> А. В датотека само треба да содржи функции.
Можете да состави датотека во машина код, бинарен, што,
без да биде извршна уште.
Валидна извршна мора да имаат главната функција.
Можете да напишете 100 функции во 1 датотеки, но не главен
а потоа ги собира дека до бинарни,
потоа напишете друга датотека која има само главните, но тоа бара еден куп на овие функции
во оваа бинарна датотека овде.
И така, кога сте правење на извршна, тоа е она што на linker не
е тоа е комбинација од овие 2 бинарни датотеки во извршна.
Значи. В датотеката не треба да имаат главната функција на сите.
И на големи кодот основи ќе видите илјадници. В датотеки и 1 главната датотека.
Повеќе прашања?
[Студент] Имаше едно друго прашање.
Таа рече направи е компајлерот. Вистински или лажни?
А одговорот беше лажна, а јас разбрав зошто тоа не е како ѕвекот.
Но, она што ние го нарекуваме направи ако тоа не е?
Направи е во основа, само - можам да се види точно она што го нарекува.
Но, тоа само работи команди.
Направи.
Јас може да се повлече ова. Да.
О, да. Направи, исто така, го прави тоа.
Овој вели дека целта на изработка алатка е да се утврди автоматски
кои парчиња голема програма треба да биде recompiled
и издаде команди за да ги прекомпајлирате.
Можете да направите се направи датотеки, кои се апсолутно огромна.
Направете изгледа во времето марки на датотеки и, како што рековме порано,
можете да ги собира поединечни фајлови надолу, и тоа не е се додека не се дојде до linker
дека тие се стави заедно во една извршна.
Значи, ако имате 10 различни фајлови и ќе се направи промена до 1 од нив,
тогаш што марка се случува да направите е само прекомпајлирате дека 1 датотека
а потоа relink сето заедно.
Но тоа е многу dumber од тоа.
Тоа е до вас за да целосно се дефинира дека тоа е она што треба да се прави.
Тоа по правило ја има способноста да го признае ова време печат работи,
но може да се напише направи датотека да се направи нешто.
Можете да напишете направи датотека, така што кога ќе напишете го прават тоа само ЦД-а во друг директориум.
Бев добивање фрустрирани бидејќи јас тактика што во внатрешноста на мојата апарати
а потоа ги видите PDF од Мак.
>> Па одам да Пронаоѓач и јас не може да оди, се поврзам со серверот,
и серверот јас се поврзете со е мојот апарати, а потоа се отвори PDF
кој добива составена од латекс.
Но, јас бев добивање фрустрирани бидејќи секој пат кога ми требаше да се освежи PDF,
Морав да го копирате дадена Директориум дека тоа би можело да пристапите
и тоа беше добивање досадно.
Така, наместо напишав направи датотека, која треба да се дефинира како тоа го прави нештата.
Како да се направи во оваа е PDF LaTeX.
Само како и секој друг направи датотека или - Претпоставувам дека не сте го виделе марка датотеки,
но ние имаме во апаратот глобална марка датотеката која само вели,
Ако сте составувањето на датотека C, користете ѕвекот.
И така тука што можам да направам што велам во мојата направи датотека,
оваа датотека ви се случува да сакаат да ги собере со PDF LaTeX.
И така тоа е PDF LaTeX што го прави на составувањето.
Направете не е составувањето. Тоа е само водење на овие команди во низа јас назначено.
Значи бега PDF LaTeX, го копира во директориумот што сакате тоа да бидат копирани,
тоа ЦД во директориумот и врши други работи,
но сите тоа го прави е признае кога датотека промени,
и ако тоа се менува, тогаш тоа ќе се кандидира на команди кои што би требало да се кандидира
кога датотека промени. >> [Студент] Во ред.
Не знам каде глобалната направи додадени фајлови се за мене да го провериш.
Други прашања? Нешто од минатото квизови? Било покажувач работи?
Постојат суптилни работи со покажувачи како -
Јас не одам за да бидат во можност да се најде квиз прашање на неа -
Но, исто како овој вид на работа.
Бидете сигурни дека ќе се разбере дека кога велам int * x * y -
Ова не е точно ништо тука, претпоставувам.
Но, како и * x * y, тоа се 2 променливи кои се на магацинот.
Кога велам x = Примерок (sizeof (int)), x е уште една променлива на магацинот,
Примерок некои блок над во грамада, и ние сме со х точка за грамада.
>> Значи нешто на магацинот укажува на грамада.
Секогаш кога ќе Примерок ништо, ти си неизбежно чување на тоа во внатрешноста на покажувачот.
Така што покажувачот е на магацинот, на malloced блок е на грамада.
Многу луѓе се збунети и велат int * x = Примерок; x е на грамада.
Па што x укажува е на грамада.
x себе е на магацинот, освен ако за која било причина сте x биде глобална променлива,
во кој случај тоа се случува да биде во друг регион на меморија.
Значи следење, овие кутија и стрела дијаграми се прилично заеднички за квиз.
Или ако тоа не е на квизот 0, тоа ќе биде на квизот 1.
Треба да знаете сите овие, чекорите во составувањето на
бидејќи ќе мораше да одговори на прашања за нив. Да.
[Студент] можеме да одиме над оние чекори - >> Секако.
Пред чекори и составувањето имаме препроцесирачка,
составувањето, монтажа и поврзување.
Препроцесирачка. Што значи дека направам?
Тоа е најлесниот чекор во - добро, а не како -
тоа не значи дека треба да биде очигледна, но тоа е најлесниот чекор.
Вие момци може да се имплементира себе. Да.
[Студент] Земете она што го имате во вашиот вклучува вака и копии, а потоа, исто така, се дефинира.
Изгледа за нешта како # вклучуваат и # define,
и тоа само копии и пасти за она што тие всушност значат.
Значи, кога ќе се каже # вклучуваат cs50.h, на препроцесори е копирање и вметнување cs50.h
во таа линија.
Кога ќе се каже # define на X да биде 4, препроцесори оди преку целата програма
и ги заменува сите случаи на x со 4.
Па препроцесори зема валидна C датотеката и излези валидна Ц датотека
каде работите се копирани и атипичен.
Па сега составувањето. Што значи дека направам?
[Студент] Тоа оди од C до бинарни.
>> [Бауден] Тоа не одат сите на начин да се бинарни.
[Студент] Да машина код тогаш? >> Тоа не е машински код.
[Студент] собрание? >> Собранието.
Тоа оди до Собранието пред да оди на целиот пат до C код,
и повеќето јазици се направи нешто како ова.
Изберете било на високо ниво јазик, и ако ви се случува да го компајлирате,
тоа е веројатно да ги собере во чекори.
Прво тоа се случува да ги собере Пајтон на C, тогаш тоа се случува да ги собере C до Собранието,
а потоа Собранието се случува да се преведени на бинарни.
Па составувањето ќе го донесе од C до Собранието.
Зборот составувањето обично значи доведување од повисоко ниво
на пониско ниво програмскиот јазик.
Значи ова е само чекор во компилација каде што ќе почнете со високо ниво јазик
и завршуваат во ниско ниво на јазикот, и тоа е зошто чекор се нарекува составувањето.
[Студент] За време на составувањето, да речеме дека сте го направиле # вклучуваат cs50.h.
Ќе компајлерот прекомпајлирате cs50.h, како функциите кои се таму,
и да се преведат дека во асемблерски код, како и,
или тоа ќе копирајте го и ставете нешто што беше пред Собранието?
cs50.h ќе прилично никогаш не многу заврши во Собранието.
Работи како функција прототипи и работите се само за тебе да се биде внимателен.
Тоа гарантира дека компајлерот може да се провери работи како сте функции за повикување
со право на враќање видови и правото аргументи и работи.
>> Значи cs50.h ќе биде preprocessed во датотека, а потоа кога е составувањето
Тоа е во основа фрлен по тоа го прави сигурни дека сè е доведена правилно.
Но функции дефинирани во CS50 библиотека, која се одвоени од cs50.h,
оние кои не се посебно ќе се состави.
Кои, всушност, ќе слезе во поврзување чекор, па ние ќе дојдеме до тоа во една секунда.
Но, прво, тоа што е монтажа?
[Студент] собрание на бинарни? >> Да.
Монтажа.
Ние не го нарекуваат составувањето бидејќи Собранието е доста чиста превод на бинарни.
Постои многу малку логика во одење од Собранието на бинарни.
Тоа е исто како да барате во табела, о, имаме оваа настава;
што одговара на бинарни 01110.
И така на датотеки кои монтажа генерално излези се. O датотеки.
И. O датотеки се она што го велеа порано,
како датотеката не треба да имаат главната функција.
Секоја датотека може да биде компајлирана сведува на. O датотека колку што е валидна Ц датотека.
Тоа може да биде компајлирана до. O.
Сега, поврзување е она што всушност носи еден куп. O датотеки и ги доведува до извршната датотека.
И така она што ги поврзува не е може да се мисли на CS50 библиотека како. O датотека.
Тоа е веќе Составувач бинарна датотека.
И така, кога ќе компајлирате вашиот датотеки, вашиот hello.c, која повикува GetString,
hello.c добива Составувач до hello.o,
hello.o е сега во бинарна.
Таа користи GetString, па затоа треба да се оди во текот на cs50.o,
и линкерот ги smooshes заедно и копии GetString во оваа датотека
и излегува со извршна кој ги има сите функции што треба.
Значи cs50.o не е всушност O датотека, но тоа е доволно блиску дека не постои фундаментална разлика.
Значи поврзува само носи еден куп на датотеки заедно
кои одделно содржат сите функции што треба да се користи
и создава извршна кои, всушност, ќе се кандидира.
>> И така тоа е, исто така, она што велеа пред
каде што може да има 1000. в датотеки, можете собере сите нив да. o датотеки,
која, најверојатно, ќе потрае некое време, а потоа го промените 1. в датотека.
Вие само треба да го прекомпајлирате дека 1. В датотека, и потоа relink сè друго,
линк се врати заедно.
[Студент] Кога ние ги поврзува ние пишуваме lcs50?
Да, така lcs50. Тоа знаме сигнали до linker дека треба да се поврзува во таа библиотека.
Прашања?
Дали сме поминале над бинарни освен дека 5 секунди во првата лекција?
Јас не мислам така.
Треба да знаете сите големи Os дека ние сме поминале над,
и треба да бидете во можност да се, ако ви даде функција,
треба да бидете во можност да се каже дека е голема О, грубо. Или добро, големи O е грубо.
Така да ако гледате вгнездени јамки looping во текот на истиот број на нештата,
како int i, i <n; int j, ѕ > [студент] n квадрат. >> Тоа се стреми да биде n квадрат.
Ако имате тројно вгнездени, се стреми да биде n коцки.
Значи тој вид на работа треба да бидат способни да се истакне веднаш.
Вие треба да знаете вметнување сортирање и меур сортирање и спојување сортирање и сите од нив.
Тоа е полесно да се разбере зошто тие се оние n квадрат и n се најавите n и сето тоа
бидејќи мислам дека беше на квизот една година каде што во основа ќе даде
имплементација на меурот вид и рече: "Што е трчање време на оваа функција?"
Значи, ако го признае како меур вид, тогаш веднаш може да се каже n квадрат.
Но, ако само погледнете во него, можете дури и не треба да се реализира тоа е балон вид;
можете само да кажеме дека ова го прави ова и ова. Ова е N квадрат.
[Студент] Дали има некои тешки примери може да излезе со,
како слична идеја на пронајдат?
>> Јас не мислам дека ние ќе ви даде тешки примери.
Меур вид работа е толку тешко како што ние би оделе,
па дури и дека, колку што ви е јасно дека сте процесирањето преку низа
за секој елемент во низата, која ќе биде нешто што е n квадрат.
Постојат општи прашања, како право тука имаме - О.
Само пред некој ден, Даг тврди, "Јас сум измислил алгоритам што може да се најде низа
"На n броеви во О (log n) време!"
Па, како да знаеме дека е невозможно?
[Нечујни студент одговор] >> Да.
Во најмала рака, треба да допре секој елемент во низа,
така што е невозможно да го решите низа на -
Ако се е во несортиран цел, тогаш ви се случува да се допира сè во низа,
така што е невозможно да го направи тоа за помалку од О од n.
[Студент] Вие ни покажа дека пример за да бидат во можност да го стори тоа во О од n
ако се користи многу меморија. >> Да.
И that's - го заборавам она што that's - Дали е пребројување вид?
Hmm. Тоа е цел број сортирање алгоритам.
Јас барав за посебно име за ова што не можев да се сетам минатата недела.
Да. Тоа се видови на сорти кои може да се оствари нешто во голема О од n.
Но, постојат ограничувања, како можете да користите само цели броеви до одреден број.
Плус ако сте се обидува да најде нешто that's -
Ако вашиот низа е 012, 12, 151, 4 милиони евра,
тогаш тоа еден елемент се случува да целосно го уништи целиот сортирање.
>> Прашања?
[Студент] Ако имаш рекурзивен функција и тоа само прави рекурзивен повици
во враќање изјава, тоа е опашка рекурзивен,
и така не би кои користат повеќе меморија за време на траење
или барем ќе се користи споредливи меморија како итеративен решение?
[Бауден] Да.
Тоа, најверојатно, ќе биде малку побавен, но навистина не.
Опашка рекурзивен е прилично добар.
Овде сум повторно во магацинот рамки, да речеме имаме главните
и ние имаме int бар (int x) или нешто.
Ова не е совршен рекурзивен функција, но се врати бар (x - 1).
Значи очигледно, тоа е недостатоци. Ви треба база случаи и работи.
Но, идејата е дека ова е опашка рекурзивен,
што значи кога главната повици бар тоа се случува да добие магацинот рамка.
Во овој магацинот рамка таму ќе биде малку блок од меморија
која одговара на нејзиниот аргумент x.
И така да речеме главната случува да се јавите бар (100);
Значи x се случува да се започне како 100.
Доколку компајлерот признава дека ова е опашката рекурзивна функција,
тогаш кога бар прави своите рекурзивен повик да се забрани,
наместо за правење на нова магацинот рамка, која е местото каде што магацинот почнува да расте во голема мера,
на крајот таа ќе се кандидира во грамада, а потоа ќе добиете segfaults
бидејќи меморија започнува судир.
>> Така, наместо за правење на своја магацинот рамка, тоа може да се реализира,
еј, никогаш не сум навистина треба да се врати на оваа магацинот рамка,
па наместо јас само ќе го замени овој аргумент со 99, а потоа започнете бар цела.
И тогаш тоа ќе го направи тоа повторно и ќе стигнат до враќање бар (x - 1),
и наместо за правење на нова магацинот рамка, тоа само ќе ја замени сегашната расправија со 98
а потоа скок назад во самиот почеток на бар.
Овие операции, заменувајќи дека 1 вредноста на магацинот и скокање назад кон почетокот,
се доста ефикасни.
Затоа, не само што е ова истиот употребата на меморијата како посебна функција која е итеративен
затоа што ти си само со користење на 1 магацинот рамка, но вие не сте болни од downsides
на да се јавите функции.
Повикувајќи функции може да биде малку скапи, бидејќи тоа треба да го направите сето ова подесување
и teardown и сето тоа работи.
Значи ова опашка рекурзија е добро.
[Студент] Зошто не ја креирате нови чекори?
Поради тоа што сфатил дека тоа не треба да се.
Повикот за бар е само враќање на рекурзивен повик.
Така што не треба да правите ништо со враќањето вредност.
Тоа е само случува веднаш да се врати.
Значи тоа е само ќе го замени свој аргумент и да почне одново.
И, исто така, ако немаат опашка рекурзивен верзија,
тогаш ќе ги добиете сите овие барови, каде, кога овој бар се враќа
таа мора да се врати на неговата вредност на оваа, тогаш тоа бар веднаш се враќа
и го враќа неговата вредност со нив, тогаш тоа е само ќе веднаш се врати
и да се врати на неговата вредност на оваа.
Па ти си заштеда на овој пукање сите овие работи надвор од магацинот
од вратената вредност е само ќе биде усвоен по целиот пат назад до секој случај.
Па зошто да не само замени нашиот аргумент со ажурирани аргумент и да почне одново?
Ако функцијата не е опашка рекурзивен, ако се направи нешто како -
[Студент] ако бар (x + 1). >> Да.
>> Значи, ако го стави во состојба, тогаш правиш нешто со враќањето вредност.
Или дури и ако само се враќа 2 * бар (x - 1).
Па сега бар (x - 1) треба да се вратат во цел таа да се пресмета 2 пати поголема од таа вредност,
па сега тоа не треба свој посебен магацинот рамка,
и сега, без разлика колку е тешко да се обиде, сте ќе треба да -
Ова не е опашка рекурзивен.
[Студент] јас ќе се обиде да донесе рекурзија да се стремите кон опашка рекурзија -
[Бауден] Во еден идеален свет, но во CS50 немате да.
Со цел да се добие опашка рекурзија, генерално, ќе постави дополнителен аргумент
каде бар ќе се int x во y
и y одговара на крајната нешто што сакате да се вратат.
Па тогаш ова ви се случува да се врати бар (x - 1), 2 * y.
Значи тоа е само на високо ниво, како ви се трансформира работите да бидат опашка рекурзивен.
Но на дополнителен аргумент -
А потоа на крајот кога ќе стигнат до својата база случај, само се вратат y
бидејќи сте се акумулира за целото време на повратната вредност што сакате.
Можете вид на се тоа го правам iteratively но со користење на рекурзивен повици.
Прашања?
[Студент] Можеби за покажувачот аритметика, како при користење на жици. >> Секако.
Покажувачот аритметика.
Кога се користи низи тоа е лесно, бидејќи жиците се знак ѕвезди,
знаци се засекогаш и секогаш еден бајт,
и така покажувачот аритметичка е еквивалентно на редовна аритметички кога си имаш работа со стрингови.
Да речеме char * s = "здраво".
Значи имаме еден блок во меморија.
Потребно е 6 бајти затоа што секогаш треба на нула терминатор.
И char * s ќе укаже на почетокот на оваа низа.
Па ги упатува таму.
Сега, ова е во основа како било низа работи,
без оглед на тоа дали станува збор за враќање од Примерок или дали тоа е на магацинот.
Секоја низа е всушност покажувачот на почетокот на низата,
а потоа било низа операција, било индексирање, е само случува во таа низа одредена офсет.
>> Па кога ќе кажам нешто како на [3]; ова ќе ги и пребројување на гласовите 3 карактери внатре
Значи s [3], имаме 0, 1, 2, 3, па и [3] се случува да се однесуваат на оваа л.
[Студент] И ние би можел да достигне истата вредност со тоа и + 3, а потоа загради ѕвезда?
Да.
Ова е еквивалентно на * (а + 3);
а тоа е засекогаш и секогаш еквивалент без разлика што правиш.
Вие никогаш не треба да се користи заграда синтакса.
Секогаш можете да го користите * (а + 3) синтакса.
Луѓето имаат тенденција да ја сакам заградата синтакса, иако.
[Студент] Па сите низи се всушност само покажувачи.
Постои мала разлика кога велам int x [4]; >> [студент] Дали тоа создаде меморија?
[Бауден] Тоа се случува да се создаде 4 ints на магацинот, па 16 бајти во целина.
Тоа се случува да се создаде 16 бајти на магацинот.
x не е зачувана насекаде.
Тоа е само симбол се однесува на почетокот на работа.
Затоа што прогласи низа во внатрешноста на оваа функција,
што компајлерот ќе направите е само да ги замени сите случаи на променливата x
со, каде што се случи да изберат да се стави овие 16 бајти.
Тоа не може да го направи тоа со char * s, бидејќи s е вистински покажувач.
Тоа е слободен да потоа се упати на други работи.
x е константа. Вие не може да го имаат точка на различни низа. >> [Студент] Во ред.
Но оваа идеја, оваа индексирање, е иста без оглед на тоа дали тоа е традиционален низа
или ако тоа е покажувач кон нешто или ако е покажувач кон malloced низа.
И всушност, тоа е толку еквивалент дека тоа е исто така истото.
Тоа, всушност, само преведува она што е внатре во заградите и она што остана од голема заграда,
додава нив заедно, и dereferences.
Значи ова е само како валиден како * (а + 3) или S [3].
[Студент] Дали можете да имате совети укажува на 2-димензионални низи?
>> Тоа е потешко. Традиционално, бр.
А 2-димензионална низа е само 1-димензионална низа со некои практични синтакса
бидејќи кога велам int x [3] [3], ова е навистина само 1 низа со 9 вредности.
И така, кога јас индекс, компајлерот знае што мислам.
Ако кажам x [1] [2], таа знае дека сакаат да одат на вториот ред, па затоа се случува да го прескокнете првите 3,
а потоа сака Втората работа во тоа, па затоа се случува да се добие оваа.
Но, тоа е уште само еден-димензионална низа.
И така, ако сакав да доделите покажувачот во тој низа,
Јас би рекол int * P = x;
Тип на x е само -
Тоа е груба велејќи тип на x, бидејќи тоа е само симбол и тоа не е вистински променлива,
но тоа е само int *.
x е само покажувач на почетокот на оваа. >> [Студент] Во ред.
И така јас не ќе бидат во можност да пристапите [1] [2].
Мислам дека постои специјална синтакса за прогласување покажувач,
нешто смешно како int (* P [-. нешто апсолутно смешно јас дури и не знаат.
Но, постои синтакса за прогласување совети како со голема заграда и работи.
Тоа дури и не може да го направите тоа.
Јас би можеле да се погледне назад на нешто што ќе ми кажеш вистината.
Јас ќе се погледне за неа подоцна, ако постои синтакса за точка. Но, вие никогаш не ќе го видите.
Па дури и синтаксата е толку архаични дека ако го користиш, луѓето ќе бидат збунети.
Мултидимензионална низа се доста ретки како што е.
Можете доста -
Па, ако правиш матрица работите не се случува да се ретки,
но во C си ретко ќе биде со користење мултидимензионална низа.
Да. >> [Студент] Да речеме дека имаат навистина долго низа.
>> Значи во виртуелна меморија би се чини дека се сите последователни,
како елементи веднаш до едни со други,
но во физичката меморија, тоа ќе биде можно тоа да се подели? >> Да.
Како виртуелна меморија работи тоа е само дели -
Единицата на распределба е страница, која има тенденција да биде 4 килобајти,
и така кога процесот вели, еј, сакам да го користите овој меморија,
оперативниот систем ќе го распредели 4 килобајти за тоа малку блок од меморија.
Дури и ако само ги користат еден малку бајт во целиот блок од меморија,
оперативниот систем ќе го даде целосна 4 килобајти.
Значи она што ова значи јас би можеле да имаат - да речеме ова е мојот оџак.
Оваа оџакот може да се одвојат. Мој оџакот може да биде мегабајти и мегабајти.
Мој оџакот може да биде огромна.
Но магацинот себе треба да се подели на одделни страници,
кој ако гледаме овде да речеме ова е нашата RAM меморија,
ако имам 2 гигабајти RAM меморија, ова е вистинската адреса 0 како 0. бајт од моите RAM меморија,
и ова е 2 гигабајти на целиот пат овде.
Значи оваа страница може да одговараат на овој блок овде.
Оваа страница може да одговараат на овој блок овде.
Ова би можело да одговараат на овој овде.
Така што оперативниот систем е слободен да доделите виртуелна меморија
на било кој поединец страница произволно.
А тоа значи дека ако оваа граница се случува да разкрачвам низа,
низа се случува да бидат оставени на овој и правото на оваа цел на страницата,
тогаш таа низа ќе бидат поделени во физичка меморија.
И тогаш кога ќе ја завршите програмата, кога процесот завршува,
овие мапирање се избришани, а потоа тоа е бесплатно да ги користат овие малку блокови за други работи.
Повеќе прашања?
[Студент] На покажувачот аритметика. >> Oh yeah.
Стрингови се полесно, но гледајќи нешто како ints,
па назад кон int x [4];
Дали ова е низа или дали тоа е покажувач кон malloced низа од 4 броеви,
тоа се случува да бидат третирани на ист начин.
[Студент] Значи низи се на куп?
[Бауден] низи не се на куп. >> [Студент] О.
>> [Бауден] Овој вид на низа има тенденција да биде на магацинот
освен ако не го прогласи во - игнорирање на глобални променливи. Не користете глобални променливи.
Внатрешноста на функција велам int x [4];
Тоа ќе создаде 4-број блок на магацинот за оваа низа.
Но, ова Примерок (4 * sizeof (int)); се случува да одам на грамада.
Но, по овој момент можам да користам x и стр во прилично ист начин,
освен исклучоците што реков пред околу можете да преназначаване стр.
Технички, нивните големини се малку различни, но тоа е сосема неважно.
Вие никогаш всушност ги користат нивните големини.
На стр можев да кажам p [3] = 2; или x [3] = 2;
Можете да ги користите токму на ист начин.
Значи покажувачот аритметички сега - Да.
[Студент] Не што треба да направите p * ако имате голема заграда?
Во загради се имплицитно Dereference. >> Океј.
Всушност, исто така, она што си ти што зборуваш со можете да добиете мултидимензионална низа
со покажувачи, што можете да направите е нешто како, да речеме, int ** п.п. = Примерок (sizeof (int *) * 5);
Јас само ќе напише сето тоа во прв план.
Јас не сакам таа една.
Во ред.
Она што го правеше тука е - Тоа треба да биде п.п. [i].
Значи п.п. е покажувач кон покажувач.
Ти си mallocing п.п. укажуваат на низа од 5 int ѕвезди.
Значи во меморија имате на магацинот стр
Тоа се случува да укажуваат на низа од 5 блокови кои се самите совети.
И тогаш кога ќе Примерок долу тука, јас Примерок дека секој од тие поединечни совети
треба да укажуваат на посебен блок од 4 бајти на грамада.
Значи ова поени до 4 бајти.
И ова укажува на различните 4 бајти.
>> И сите од нив укажуваат на своите 4 бајти.
Ова ми дава начин на вршење на мултидимензионална работи.
Јас може да се каже п.п. [3] [4], но сега тоа не е истото како мултидимензионална низа
бидејќи мултидимензионална низа го преведе [3] [4] во единечен свиткан во низа х.
Ова dereferences p, пристапи третиот индекс, потоа dereferences дека
и пристапи - 4 ќе биде валиден - вториот индекс.
Каде што, кога имавме int x [3] [4] пред како мултидимензионална низа
и кога ќе се удвои заграда тоа е навистина само еден Dereference,
ти си по еден покажувач, а потоа офсет,
ова е навистина 2D референци.
Ќе го следат 2 одделни совети.
Па ова, исто така, технички ви овозможува да имате мултидимензионална низа
каде што секој поединец низа е различни големини.
Па мислам дека грапав мултидимензионална низа е она што се вика
бидејќи навистина првото нешто може да укаже на нешто што има 10 елементи,
втората работа може да укаже на нешто што има 100 елементи.
[Студент] Дали има ограничување на бројот на покажувачи ќе може да има
што укажува на други совети? >> Бр
Можете да имаат int ***** стр.
Вратете се на покажувачот аритметички - >> [студент] О. >> Да.
[Студент] Ако имам int *** p и тогаш јас се направи dereferencing и велам p * е еднакво на оваа вредност,
Дали е тоа само ќе направи 1 ниво на dereferencing? >> Да.
Значи, ако сакам да пристапите на нешто што последните покажувачот е да се покажува во -
Тогаш го правите *** стр. >> Океј.
Значи ова е p поени 1 блок, укажува на друга блок, поени на друг блок.
Тогаш ако не * P = нешто друго, тогаш се менуваат овој
до сега укажуваат на различни блок. >> Океј.
>> [Бауден] И ако тие беа malloced, тогаш сте сега протекоа меморија
освен ако не се случи да имаат различни референци од овие
бидејќи не можете да се вратам на оние кои само фрли.
Покажувачот аритметика.
int x [4]; ќе одвои низа од 4 броеви
каде што x се случува да се укаже на почетокот на низата.
Па кога ќе кажам нешто како x [1]; Сакам да значи одат во вториот број во низа,
која ќе биде оваа.
Но, навистина, тоа е 4 бајти во низа од овој број зазема 4 бајти.
Значи офсет од 1 навистина значи поместување од 1
пати поголема од големината на она што тип на низата е.
Ова е низа од цели броеви, па тоа знае да се направи 1 пати големината на int кога сака да надомести.
Од друга синтакса. Запомнете дека ова е еквивалент на * (x + 1);
Кога велам покажувач + 1, она што се враќа е адресата која покажувачот се чување
плус 1 пати поголема од големината на типот на покажувачот.
Значи, ако x = ox100, тогаш x + 1 = ox104.
И можете да го злоупотребуваат ова и каже нешто како char * C = (char *) x;
и сега в ќе биде иста адреса како x.
в ќе биде еднаква на ox100,
но в + 1 ќе биде еднаква на ox101
од покажувачот аритметички зависи од типот на покажувачот дека сте додавање.
Значи C + 1, изгледа во в, тоа е знак покажувач, па затоа се случува да додадете 1 пати големина на знак,
кој секогаш ќе биде 1, па ќе го добиете 101,
а ако го правам X, кој е исто така уште 100, x + 1 ќе биде 104.
[Студент] можете да го користите C + +, со цел да ги унапредат својата покажувачот од 1?
Да, можеш.
Вие не може да го направи тоа со x бидејќи x е само симбол, тоа е постојана, вие не можат да сменат х.
>> Но в случува да биде само покажувач, па C + + е совршено валидни и ќе прираст од 1.
Ако в беа само int *, тогаш C + + ќе биде 104.
+ + Прави покажувачот аритметички само како C + 1 би го сторил покажувачот аритметика.
Ова е всушност како многу нешта како логирате вид -
Наместо за создавање копии на нештата, наместо да помине -
Како и ако сакав да го помине овој половина од низа - Да се ​​избрише некои од ова.
Да речеме дека сакав да помине оваа страна на низа во функција.
Што би се пренесат и на таа функција?
Ако јас помине x, јас сум минува оваа адреса.
Но јас сакам да помине оваа адреса. Значи она што треба да помине?
[Студент] Покажувач + 2?
[Бауден] Значи x + 2. Да.
Тоа ќе биде оваа адреса.
Ќе исто така многу често го гледаат како x [2], а потоа и адресата на тоа.
Значи треба да се земе адресата на него, бидејќи заградата е имплицитна Dereference.
x [2] се однесува на вредност која е во ова поле, а потоа ќе сакате адресата на тоа поле,
така да се каже и x [2].
Значи тоа е тоа како нешто логирате вид, каде што сакате да помине половина од листата на нешто
навистина, само поминуваат и x [2], а сега колку што е рекурзивен повик е загрижен,
мојата нова низа почнува таму.
Последен момент прашања.
[Студент] Ако ние не се стави симболот или - што е тоа вика? >> Star?
[Студент] ѕвезда. >> Технички, Dereference оператор, но - >> [студент] Dereference.
>> Ако ние не се стави една ѕвезда или симболот, она што се случува ако речеме y = x и x е покажувачот?
Што е тип на y? >> [Студент] јас само ќе кажам тоа е покажувачот 2.
Значи, ако речеме y = x, сега x и y точка за истото. >> [Студент] Точка до истото.
И ако x е int покажувачот? >> Тоа ќе се жалат бидејќи не можете да доделите совети.
[Студент] Во ред.
Запомнете дека покажувачи, иако ние ги привлече како стрели,
навистина сите тие продавница - int * x - навистина сите x е чување е нешто како ox100,
кои се случи да претставуваат како укажува на блок чуваат на 100.
Значи, кога велам int * y = x, јас сум само копирање ox100 во y,
кои ние сме само ќе претставуваат како y, исто така, укажува на ox100.
И ако кажам int i = (int) x; тогаш јас ќе ја запази она што вредноста на ox100 е
во него, но сега тоа се случува да се толкува како цел број, наместо на покажувачот.
Но, вие треба леано или на друго место ќе се жалат.
[Студент] Значи сакаш да кажеш да го дадат -
Е тоа ќе биде кастинг int на x или кастинг int на y?
[Бауден] Што?
[Студент] Во ред. По овие загради е таму ќе биде x или ay таму?
>> [Бауден] или. x и y се еквивалентни. >> [Студент] Во ред.
Бидејќи тие се двете насоки. >> Да.
[Студент] Значи тоа ќе ја зачувате хексадецимален 100 во цел број форма? >> [Бауден] Да.
Но не и вредноста на она што укажува.
[Бауден] Да. >> [Студент] Па само ја адресата во цел број форма. Во ред.
[Бауден] Ако си сакал да за некои бизарни причини,
можете само може да се справи со покажувачи и никогаш не се справи со цели броеви
и само да биде како int * x = 0.
Тогаш ви се случува да се навистина збунета еднаш покажувачот аритметички започнува случува.
Значи броеви кои тие се чуваат се бесмислени.
Тоа е само како ќе заврши толкување нив.
Па јас сум слободен да го копирате ox100 од int * до int,
и јас сум слободен да доделите - Ти си веројатно нема да се викна на за да не леење -
Јас сум слободен да доделите нешто како (int *) ox1234 во оваа произволна int *.
Значи ox123 е само како валиден меморија адреса како што е и y.
И y се случува да се врати нешто што е доста ox123.
[Студент] Тоа ќе биде навистина кул начин да се оди од хексадецимални во децимална форма,
како ако имате покажувач и ќе го фрли како int?
[Бауден] Вие навистина само да печатите со користење како printf.
Да речеме дека имам int y = 100.
Значи printf (% d \ n - како што веќе треба да знаете - печати дека како цел број,% х.
Ние само ќе печати како хексадецимални.
Значи покажувач не се чуваат како хексадецимален,
и број не се чуваат како децимална.
Сè што се чуваат како бинарни.
Тоа е само дека ние се стремат да ја прикажете совети како хексадецимални
затоа што мислам на нештата во овие 4-бајт блокови,
и мемориски адреси имаат тенденција да бидат запознаени.
Ние сме како, ако тоа започнува со bf, тогаш тоа се случува да биде на магацинот.
Значи тоа е само наша интерпретација на совети како хексадецимални.
Во ред. Последни прашања?
>> Јас ќе бидам тука за малку по ако имате било што друго.
И тоа е крајот на тоа.
>> [Студент] Yay! [Аплауз]
>> [CS50.TV]