>> DAVID Malan: Добре, добре дошъл отново.
Това е CS50.
Това е началото на седмицата седем.
Така че това е било известно време, така че аз смятахме, че ще се вихрушка обиколка на къде сме
спрели и къде сме сега ще.
>> Така че това нещо тук може да има причинила тревога на първо време.
Но се надяваме, че сте започнали да аклиматизира към какво означава тук -
звезден представлява показалеца, който е точно това, от гледна точка по точка на лаик?
Така че това е един адрес.
>> Така че това е адресът на нещо в паметта.
И ние започнахме да Обелете слоеве а преди няколко седмици, такива неща
GetString и други такива функции през цялото това време са били връщане
Адресите на нещата в паметта, като адрес на първия знак в
някои последователност.
>> Така че ние също така въведе valgrind, които ще започне да се използва за този проблем
настроен, особено за следващия Проблемът определени, както добре.
И valgrind какво прави за нас?
Тя проверява за изтичане на памет, и да го също проверява за злоупотреба с памет.
>> Той може с известна вероятност, откриване, ако вашия код ще докосне памет
че просто не трябва.
Така че не е задължително на течове, но ако надхвърля границите на някои
масив, и всъщност тече valgrind и принуди поведение по време на
valgrind работи във вашата програма е работи вътре в него, вие ще получите
съобщения като тази - "невалиден напиши на размер 4 ", което, припомни няколко
седмици означаваше, че имах случайно като на един Int твърде далеч
извън границите на масив.
И така, размер 4 означава тук размера на конкретната вътр.
>> Така че да успокоение във факта, че valgrind на продукцията, формата на играта,
е просто отвратителен.
Наистина е трудно да се види през бъркотия за интересна информация.
Така че това, което сме направили тук, е само откъс някои от няколко по-
интересни линии.
Но осъзнавам, че 80% от valgrind на продукция ще бъде доста голяма
разсейване.
>> Просто се търсят модели като тези - невалиден право, невалидни прочетете, 40 байта
а някои брой блокове са определено загуби, ключови думи като това.
И това, което ще видите, е надявам се някои вид и следа от това, което функционира на
грешка е всъщност инча
В този случай тук, в линията на моя код е грешката очевидно?
>> 26 във файл, наречен memory.c, което беше примера си играехме с
по това време.
Така че това вероятно не е в изчистване.
Вероятно беше в моя код вместо това.
Така че ще видим това отново и отново скоро.
>> Така scanf, това дойде в Няколко форми до този момент.
Видяхме sscanf кратко.
Това беше нещо много Вие се гмурна в в
подготовката за тест.
И scanf е всъщност това, което CS50 библиотеката са използвали под
качулка от доста време, за да за да получите информация от страна на потребителя.
>> Например, ако се насочат към CS50 Уредът тук, позволете ми да се отворят един
Например днес, че се нарича scanf-0.c И това е супер проста.
Това е само няколко реда код.
Но това показва наистина колко getInt работи всичко това време.
>> В тази програма тук, в съответствие 16 , Забележете, че I обявява вътр.
Така че не указатели, нищо магическо там, просто Int.
След това в ред 17, I подтикне потребител за брой, моля.
След това в края на 18, аз използвам scanf тук.
И съм посочил, нещо като ФОРМАТ, че аз очаквам цитат
във файловите процента аз.
>> Така че процента, разбира се, означава Int.
Забележете какво втората аргумент на scanf е.
Как бихте описали секунди аргумент след запетаята?
Какво е това?
>> Това е адреса на х.
Това е полезно, тъй като осигурява scanf с адреса на х, какво прави
, които дават тази функция да направя?
Не само там, но и какво?
>> Извършване на промени в него.
Защото ти може да отиде там, това е нещо като като карта на място в паметта.
И така, стига да предоставят scanf, или всяка функция с такава карта, че
функция може да отиде там, а и не само Посетете форума на стойност, но може да
промените тази стойност, което е полезно, ако целите в живота на scanf е да
сканирате принос от страна на потребителя, по-специално от клавиатурата.
И е форматиран означава, точно като ФОРМАТ, на F означава форматиран
низ, който искате да отпечатате.
>> Така че, накратко, тази линия 18 казва просто: Опитвам се да чета едно цяло число от потребителя
клавиатура и го съхранява вътре в X, в каквото адрес х случва да живеят в.
И тогава накрая, ред 19 просто казва, благодаря за ПНА, в този случай.
>> Така че нека да вървим напред и да направи това.
Така че се scanf 0.
Позволете ми да отида напред и да увеличите инча
Ще отида да изпълня този с точки, наклонена черта scanf 0.
Номер, моля?
50.
Благодаря за 50.
Така че това е много прост.
>> Сега това, което не го прави?
Той не прави цял куп от проверка за грешки.
Например, ако аз не си сътрудничат, и аз не въвеждайте в брой, но
вместо да пиша нещо като "здравей" това е просто странно.
И така, едно от нещата, на CS50 библиотеката е правил за нас за някои
време е, че reprompting и reprompting.
>> Повторен опит фраза изземване беше в cs50.c, и това е причината, че в getInt
библиотеката CS50 всъщност е цяло куп линии дълги, защото сме
проверка за глупави неща като това.
Още не дават на потребителя ни, в действителност, едно цяло число?
Дали той или тя ни даде нещо подобно на буква?
Ако е така, ние искаме да се открие че и крещи по тях.
>> Но нещата стават по-интересно в следващия пример.
Ако отида в-1, буква в scanf, какво е едно нещо, което се промени из основи в
следващия пример?
Аз съм с Чар *, разбира се, вместо Int.
>> Така че това е интересно, защото Чар *, спомням, е наистина само на
същото като низ.
Така че тя се чувства като може би това е супер просто изпълнение на GetString.
Но аз съм отлепи назад слой на CS50 библиотека, така че аз съм
призовава този знак * сега.
Така че нека да видим къде, ако навсякъде, ние да се обърка.
>> Ред 17 -
Аз отново казвам, моля да ми даде нещо, В този случай, низ.
И след това в следващия ред, призовавам scanf, отново, като го формат код,
но това време и процента.
И тогава този път, аз съм което му буфер.
>> Нека видим, аз не съм с амперсанд.
Но защо е, че вероятно OK тук?
Защото това, което е буфер вече?
Той вече е на показалеца.
Той вече е на адрес.
>> И нека тази дума "обърка", нека просто го наричат ​​лидер, например, за
простота.
Но аз съм го нарича буфер, тъй като в Като цяло, в програмирането, ако имате
парче от паметта, която низ наистина Просто е, може да го наречем буфер.
Това е място за съхранение на информация.
>> Подобно на неща като YouTube, когато те буфериране, така да се каже, че
просто означава, че е бита от изтегляне интернет и ги съхранява в
местно масив, местен парче памет, така че можете да го гледате по-късно, без да
го прескочите или виси на ви по време на възпроизвеждане.
>> Така че има проблем тук обаче, защото ви казвам scanf, очакват
низ от потребителя.
Тук е адреса на парче памет.
Остави това низ там.
Защо е този, свързан даде ни проблеми, все пак?
>> Какво е това?
Позволено ли ми е да имат достъп че част от паметта?
Знаеш ли, аз не знам.
Защото е буфер е инициализирана към нещо?
Не съвсем.
И така, това е, което ние Звъня боклук стойност, която
не е официална дума.
Това просто означава, че ние нямаме представа какво бита са вътре в четири байта, че
I са разпределени като буфер.
>> Не съм нарича изчистване.
Аз определено не съм наречен GetString.
Така че кой знае какво е всъщност вътрешността на буфер?
И все пак казвам scanf сляпо, там и отбеляза, независимо от потребителя написали.
>> Така че това, което може да причини В кода ако го изпълните?
Вероятно segfault.
Може би не, но вероятно segfault.
И аз казвам може би не, защото понякога и да правите, понякога
не получи segfault.
Понякога просто късмет, но тя все пак ще бъде
бъг в нашата програма.
>> Така че нека да вървим напред, и въвежда тази.
Аз ще го направя старата школа начин.
Така звън тире 0, scanf-1, scanf-1.в, Enter.
Опа, твърде стар училище.
Нека да видим.
Къде да отида?
О, Чар * буфер.
О, благодаря ви -
Запази, OK -
много старо училище.
Добре, това е било известно време.
>> Така че аз току-що записахте файла след вземане на това временно
промени преди малко.
И сега съм го компилиран ръчно с звъня.
И сега аз ще вървим напред и тичам scanf-1, Enter.
String моля.
Ще напишете "здравей".
>> И сега, тук е мястото, където, честно казано, ФОРМАТ може да е малко досадно.
Това не е всъщност ще segfault в този случай.
ФОРМАТ е малко по-специален, защото това е толкова супер често се използва, че
същество ФОРМАТ прави ни услуга и осъзнават,
Това не е валиден показалеца.
Нека вземем върху себе си да го разпечатате в скоби нула, дори
макар че не е задължително това, което ние се очаква.
>> Така че ние не можем наистина лесно да предизвика segfault с това, но очевидно това
не е поведение, което исках.
Така че каква е просто решение?
Е, в scanf-2, позволете ми да предложа вместо действително просто разпределяне на
Чар *, нека да е малко по-умни това и да ме разпределят буфер
като последователност от 16 знака.
>> Така че мога да направя това по няколко начина.
Мога да използвате абсолютно изчистване.
Но аз мога да се върна до седмица две, когато Просто ми трябваше цял куп
героите.
Това е просто масив.
Така че нека вместо предефинират буфер да бъде масив от 16 символа.
>> И сега, когато минавам буфер -
и това е нещо, което не говорим за по седмица две -
но вие може да лекува масив като че това е един адрес.
Технически, както видяхме, те са малко по-различно.
Но scanf няма да се притесняват, ако го давате името на масива, защото това, което
Звъня ще направи за нас е по същество лечение на името на този масив като
адрес на парче от 16 байта.
>> Така че това е по-добре.
Това означава, че сега мога да се надяваме направете следното.
Позволете ми да намалите за момент и направи направи scanf-2, съставен OK.
Сега нека да се има наклонена черта scanf-2.
String моля. "Hello". И това изглежда да работи този път.
>> Но някой може да предложи сценарий , в която той не може да продължи да работи?
Да?
Нещо по-дълъг от 16 символа.
И действително, ние може да бъде малко по-точни.
Нещо по-дълъг от 15 символа, , защото наистина ние трябва да се има предвид
че имаме нужда, че наклонена черта нула имплицитно в края на низа,
което е настрана scanf ще обикновено се грижи за за нас.
>> Така че нека да направим нещо подобно -
понякога ние просто може да го оставите така.
ОК, така че ние сме сега индуцирана нашата сегментация вина.
Защо?
Защото аз напечатани на повече от 15 героите, и така всъщност сме
докосна памет, която аз всъщност не трябва да има.
>> Така че това, което е наистина решение тук?
Ами, ако имаме нужда от по-дълъг низ?
Е, може би направи 32 байта.
Ами ако това не е достатъчно дълго?
Как около 64 байта?
Ами ако това не е достатъчно дълго?
Какво ще кажете за 128 и 200 байта?
Това, което наистина е решението тук, в общия случай, ако ние не знаем в
предварително това, което потребителят ще объркате?
>> Това е просто вид голям трън в задника, трябва да бъда честен, поради което
CS50 библиотека има няколко линии на дузина код, който колективно изпълнение
GetString низ по начин, който не го правим трябва да се знае предварително какво
потребителя ще се объркате.
В частност, ако погледнете назад към cs50.c от преди две седмици, ще видите
че GetString всъщност прави Не използвайте scanf по този начин.
Вместо това, тя чете един символ в даден момент.
>> Тъй като едно хубаво нещо за четене на един герой е възможно
гарантира се, че винаги да има поне един знак.
Не мога просто да обяви Чар, а след това се тези наистина малки стъпки до просто
прочете един символ в най- време от клавиатурата.
И след това, което ще видите GetString прави, е всеки път, когато тя свърши,
да речем, 16 байта памет, тя използва изчистване, или от него братовчед, да
отдели повече памет, копиране на стария памет в новия, а след това пълзене
заедно с удар един символ в даден момент, и когато тя свърши, че
парче от паметта, тя изхвърля, грайфери по-голяма парче на паметта, копира стария
с нови, и се повтаря.
И това е наистина една болка действително изпълнение нещо толкова просто като
получаване на данни от потребителя.
>> Така че можете да използвате scanf.
Можете да използвате и други подобни функции.
И много от учебниците и онлайн примери направя, но всички те са
уязвими към проблеми като този.
И в крайна сметка, получаване на segfault е малко досадно.
Не е добре за потребителя.
>> Но в най-лошия случай, това, което прави това фундаментално сложиш
код на риск от?
Някакъв вид атака, потенциално.
Ние говорихме за едно такова нападение - прелива стека.
Но като цяло, ако ти е позволено да препълване на буфер, както направихме с
Преди няколко седмици, само с писмено над "здравей" на стека, вие
наистина може да поеме, потенциално, компютър, или поне да получите най-данни, които
не принадлежи на вас.
>> Така че, накратко, това е защо трябва тези помощни колела.
Но сега, ние започваме да ги свали, тъй като нашите програми не е необходимо,
непременно, принос от страна на потребителя.
Но в случай на проблем определени шест, вашият принос ще дойде от огромно
речник файл с 150 някои нечетни хиляда думи.
>> Така няма да се налага да се притеснявате за произволно на потребителя вход.
Ние ще ви даде някои предположения за този файл.
Въпроси по указатели или scanf или приноса на потребителите като цяло?
>> Добре, един бърз поглед след това при едно зад гърба тема от преди две седмици.
И това беше тази идея на структурата.
Не че - тази идея на структура, която е какво?
Какво структура направи за нас?
>> Дефиниране -
Моля?
Дефиниране на променлива тип.
Така че някак.
Ние всъщност комбиниране на две теми.
Така че с typedef, припомни, че можем обяви вид сами, като
синоним, като низ за Чар *.
Но използвайки typedef и структура, ние можем създаде истински собствени структури от данни.
>> Например, ако се върна в Gedit тук само за миг, и аз давай напред
и да направим нещо подобно, нека да ме спаси това като, да речем, structs.c
временно, аз съм просто ще да вървим напред и включва
standardio.h, вътр основната невалидни.
И след това в тук, предполагам, че аз искам да се напише програма, която съхранява
множество студенти от множествена къщи, например.
Така че това е като registrarial база данни от някакъв вид.
>> Така че, ако имам нужда от име на един ученик, I може да направи нещо като знак * име,
и аз ще направя нещо подобно -
Всъщност, нека да използват CS50 библиотека само за миг, за да има
малко по-опростена, така че ние може да заеме тези десетки реда код.
И нека просто да го прости.
Ние ще я държи низ, а сега GetString.
>> Така че аз твърдя сега, че съм съхраняват името на някои студент, а домът на
някои студент, просто да се използват променливи както направихме и в една седмица.
Но предполагам, че сега искат да подкрепят множество студенти.
Добре, така че инстинктите ми са да се направи низ NAME2, получава GetString, низ
house2 получава GetString.
И тогава нашата трети ученик, нека да направим NAME3 GetString.
>> Всички права, така че това е надяваме поразително вие като много глупаво,
тъй като този процес е много никога ще свърши, и тя просто ще
направи ми код изглежда по-зле и по-лошо и по-лошо.
Но решихме това също в две седмици.
Какво беше нашето сравнително чист разтвор , когато имахме множество променливи на
същия тип данни, че са свързани, но ние не искаме този отвратителен бъркотия
на подобно име променливи?
Какво сме направили, а?
>> Затова мисля, че чух няколко места.
Имахме масив.
Ако искате няколко екземпляра на нещо, защо да не се почисти всички
и само да кажа, дай ми масив наречен имена?
>> И за сега, нека трудно 3 код.
И след това да ми даде друг масив нарича къщи, и ме пусна за
сега трудно код 3.
И аз съм масово Пречистихме обърквам, че аз току-що създадохте.
Сега, аз съм все още твърди кодирани 3, но дори 3 може динамично да дойдат от
потребителя, или ARGV, или други подобни.
Така че това вече е чиста.
>> Но това, което е досадно за това е, че Сега, въпреки че името е по някакъв начин
основно свързани с на студента къща -
това е студент, че наистина искам да представляват -
Сега имам два масива, които са успоредни в смисъл, че те са
същия размер, както и имена на скобата 0 да се предполага, карти за къщи скоба 0,
и имената скоба 1 карти до къщи скоба 1.
С други думи този ученик живее в тази къща, и тази друга студент
живее в тази друга къща.
Но със сигурност това може да бъде направи още по-чисто.
>> Е, може, в действителност.
И нека да вървим напред и да се отворят до structs.h, и ще
виж тази идея тук.
Забележете, че аз съм използвал typedef, както намекна за миг преди да заявяваме
собствен тип данни.
Но аз също така да използвате тази друга дума нарича структурата, която ми дава нов
структурата на данните.
>> И тази структура от данни I регистрирайте ще да има две неща вътре
това - низ наречен име, и низ наречен къщата.
А името Отивам да дам на тези данни структура ще
да се нарече ученик.
Мога да го наречем нещо искам, но това семантично направи
смисъл за мен в съзнанието ми.
>> Така че сега, ако се отвори по-добра версия на програмата започнах да пиша
там, нека да преминете към върха.
А има и още няколко реда код тук, но нека да се съсредоточи за
момента на един.
Аз бях обявен постоянна наречените студенти и твърди кодирани 3 за сега.
Но сега, забележете как чисти моя код започва да се получат.
>> В ред 22, Декларирам масив от студенти.
И забележи, че ученикът е очевидно сега е тип данни.
Тъй като в горната част на този файл, забележите Включили сме, че заглавния файл
че спрях точно преди малко.
И това заглавния файл просто трябваше Това определение на един студент.
>> Така че сега, аз създадох моя собствена персонализирана данни вид, че авторите на години C
Преди не мислех, че от по-рано.
Но никакъв проблем.
Мога да го направя сам.
Така че това е масив наречен студенти, всеки от членовете на която
е студент структура.
И аз искам три от тези в масива.
>> И сега, какво ще свърши останалото на тази програма да направя?
Имах нужда от нещо малко произволно.
Така че от онлайн 24 нататък, I превъртите 0-3.
След това поиска от потребителя за на студента име.
И след това да използвам GetString както преди.
Тогава аз питам за къщата на студента, и аз използвам GetString както преди.
>> Но забележете - леко нова парче синтаксис -
Все още мога да се индексът на аз-ти студент, Но как мога да получа най-конкретните данни
областта вътрешността на структурата?
Е, това, което е очевидно нова част от синтаксиса?
Това е само на точка оператор.
>> Ние не си бях виждала преди.
Вие сте го виждали в PSET пет ако сте хвърли в вече с растерни файлове.
Но точката означава само вътре в този структура или няколко полета, даде точка
име, или да ми даде точка къщата.
Това означава, че влизаме на структурата и да получите тези конкретни области.
>> Какво означава останалата част от тази програма да направя?
Това не е всичко, което секси.
Забележете, че обхождане от 0 до 3 отново, и аз просто се създаде English
фраза като така и така е в такава и такава къща, която минава през точката име от
-тото студентите и тяхната къща, както добре.
>> И тогава на последно място, сега ще започнем да получите анален за това, че сега сме
запознати с това, което изчистване и други функции са
прави през цялото това време.
Защо трябва да се освободи и двамата име и къща, въпреки че
Не се обади изчистване?
>> GetString направих.
И това беше мръсна малка тайна за няколко седмици, но има GetString
е изтичане на паметта целия поставите всички семестър до този момент.
И най-накрая ще valgrand разкрие това на нас.
>> Но това не е голяма работа, защото знам, че може просто да освободи името
и къщата, макар и технически, за да бъде супер, супер безопасен, че трябва да съм
правят някои проверка за грешки тук.
Какви са вашите инстинкти ви казвам?
Какво трябва да се проверява за преди да освободи това, което е
низ, известен още която Чар *?
>> Наистина трябва да се провери дали учениците скоба I точка име не
равен нула.
След това тя ще бъде ОК, за да вървим напред и безплатно че показалеца и съща или друга
такъв.
Ако учениците скоба точка аз къща не е равна на нула, това сега ще защитава
срещу ъгъла случай, в който GetString връща нещо като нищожна.
И видяхме преди малко, ще ФОРМАТ ни пази тук от просто казвам
нула, което ще изглежда странно.
Но поне няма да segfault, както видяхме.
>> Е, нека да направим още нещо тук. structs-0 е нещо като глупава програма
защото въведете всички тези данни, и след това той е загубил след като програмата завърши.
Но нека да вървим напред и да направите това.
Позволете ми да направя на терминала прозорец, малко по-големи.
Позволете ми да направя structs-1, който е нова версия на този.
>> Ще я увеличите малко.
А сега нека да тече точка наклонена черта structs-1.
Студентски име -
David Mather, нека да направим Rob Къркланд, нека да направим Lauren Leverett.
Интересното сега е бележка -
и аз знам само това, защото Написах програма -
има един файл сега на моя ток директория, наречена students.csv.
Някои от вас може да са видели тези в реалния свят.
>> Какво е файл CSV?
Разделени със запетаи стойности.
Това е нещо като бедняка версия на файла Excel.
Това е таблица от редове и колони, които можете да отворите в програма като Excel,
или номера на Mac.
>> И ако отворите този файл тук на Gedit, бележка - и цифрите не са там.
Това е просто Gedit казвам ми номерата на редовете.
Забележете, на първа линия на тази Файлът е Давид и Mather.
Следващият ред е Rob запетая Къркланд.
И на третия ред е Lauren запетая Leverett.
>> Така че това, което съм създал?
Сега съм написал програма на С, че ефективно може да генерира електронни таблици
които могат да се отварят в програма като Excel.
Не много убедителни на набор от данни, но ако имате много по-големи парчета
данни, които действително искат да манипулират и правят графики на и
харесва, това е може би един начин за създаване на тези данни.
Освен това, CSVs са всъщност супер общата само за съхранение на данни прости -
Yahoo Finance например, ако получите борсови котировки чрез своите т. нар.
API, безплатна услуга, която ви позволява получаването на текущата в крак с най-датата наличност
котировките на компаниите, те даде на данни обратно в
супер прост формат CSV.
>> И така, как да го направим?
Е забележите, повечето от тази програма почти същото.
Но забележете тук, а не печат студентите проверки от линия 35
нататък, аз твърдя, че аз съм спестяване на учениците на диск, така спестиха файл.
>> Така че забележите аз съм за обявяване на FILE * -
Сега, това е вид аномалия в C. По някаква причина, файла е с главни букви,
, която не е като повечето други типове данни в C. Но това е вграден в
тип данни, FILE *.
И аз съм за обявяване на показалеца към файл, е как можеш да мислиш за това.
>> FОтваряне на означава отворен файл.
Какво файл искате да отворите?
Искам да отворите файл, който ще произволно се обадя students.csv.
Мога да се обадя, че всичко, което искам.
>> И след това да вземе предположение.
Какво прави втория аргумент да FОтваряне на вероятно означава това?
Да, w за запис, може R е за четене.
Има за добавяне, ако искате да добавите редове, а не
презапишете цялото нещо.
>> Но аз просто искате да създадете този файл веднъж, така че ще използвам цитат кавички вата
И знам, че само след като прочетох документацията, или на страницата човек.
Ако файлът не е нула - с други думи, ако нищо не се обърка там -
нека обхождане на студенти от 0 до 3.
>> И сега забелязвам, че има нещо все така малко по-различен
за линия 41 тук.
Това не е ФОРМАТ.
Това е fprintf за файла ФОРМАТ.
Така, че ще пиша във файла.
Кой файл?
Онзи, чието показалеца укажете като първи аргумент.
>> Тогава ние зададени низ формат.
Тогава ние се уточни какво низ искаме да включите за първи и процента, и
после още една променлива или втората и процента.
След това затворете файла с неуспешно.
Than I освободите памет, както и преди, макар и Аз трябва да се върна и да добавите
някои проверки за нищожна.
>> И това е всичко.
FОтваряне на, fprintf, неуспешно ми дава възможност за създаване на текстови файлове.
Сега, вие ще видите в проблем набор пет, , която включва изображения, което ще се използва
двоични файлове вместо това.
Но в основата си, идеята е същата, въпреки че функциите, които ще
виж са малко по-различно.
>> Така вихрушка турне, но вие ще получите твърде запознат с файл I/O--
вход и изход - с PSET пет.
И някакви въпроси относно първоначалните основите тук?
Да?
>> Какво става, ако се опитате да освободите нулева стойност?
Вярвам, освен безплатно е намерила малко по-лесен за употреба, можете да
потенциално segfault.
Минавайки го нула е лошо, защото не вярвам безплатно притеснява да се провери за вас,
защото това потенциално би било загуба от време, за да се направи за
всички хора по света.
Добър въпрос, все пак.
>> Добре, така че този вид получава от нас да интересна тема.
Темата на проблема в стаята пет е съдебна медицина.
Най-малко това е част на проблема в стаята.
Съдебна медицина обикновено се отнася до събиране на информация, която може или
може да не са изтрити умишлено.
И така, реших да ви дам един бърз вкуса на това, което наистина се случва всичко
този път под капака на компютъра.
>> Например, ако имате вътрешната страна на лаптоп или работния плот на компютъра на
твърд диск, то е или механична устройство, което всъщност се върти -
има кръгли неща наречени плочи , които изглеждат доста харесва това, което
Просто трябваше на екрана тук, въпреки че това е все по-старата школа.
Това е три и половина инча твърд диск.
И три и половина инча позовава на с на нещо, когато го инсталирате
в компютъра.
>> Много от вас в лаптопи с предприятието имат твърди дискове или SSD дискове,
които нямат движещи се части.
Те са по-скоро като RAM и по-малко като тези механични устройства.
Но идеите са си все същите, със сигурност, тъй като те са свързани
да зададете пет проблем.
>> И ако мислите, че за сега е твърд диск означава, че е кръг, който
Ще изготвя така тук.
Когато създадете файл на вашия компютър, дали това е SSD, или в
този случай, по-старо училище твърд диск, този файл съдържа няколко бита.
Да кажем, че това е този 0 и 1, цял куп 0s и 1s.
Така че това е целият ми хард диск.
Това е очевидно доста голям файл.
И това е с помощта на на 0s и 1s в този част от физическата поднос.
>> Е, това, което е, че физическата част?
Е, оказва се, че на твърдия диск, най-малко от този тип, има
тези миниатюрни магнитни частици.
И те по същество имат север и Южният полюс към тях, така че ако сте
се превърне един от тези магнитни частици По този начин ще може да се каже, че това е
представлява 1.
И ако това е с главата надолу на юг до северно, може да се каже, че това е
представлява 0.
>> Така че в реалния физически свят, това е как бихте могли да представляват нещо в
двоичен състоянието на 0 и 1.
Така че това е всичко файла е.
Има цял куп магнитна частици, които са им по този начин, или
този начин се създаде модели на 0s и 1s.
>> Но се оказва, когато записвате файл, част от информацията се записва отделно.
Така че това е малка масичка, директория, така да се каже.
И аз ще се обадя на това име на колона, и Ще се обадя на това място колона.
>> И аз ще кажа, предполагам, това е моята автобиография.
My resume.doc се съхранява при място, да кажем 123.
Аз винаги отивам за този номер.
Но е достатъчно да се каже, че точно като в RAM, можете да вземете един твърд диск
Това е гигабайт или 200 гигабайта или терабайт, и можете да
броят на всички байта.
Можете да номерирате всички парчета на 8 бита.
>> Затова ще кажа, че това е място 123.
Така че тази директория вътрешността на моята работа системата си спомня, че ми
резюме е в населено място 123.
Но става интересно, когато изтриете даден файл.
>> Така например -
и за щастие, по-голямата част на света има уловени върху това - какво се случва, когато
плъзнете файла на вашия Mac OS Trash или вашия Windows Recycle Bin?
Каква е целта на това, че?
Това е очевидно за да се отървете от файла, но това, което прави акта на плъзгане и
пуснете в кошчето ви или вашия Recycle Bin направи на компютър?
>> Абсолютно нищо, наистина.
Това е точно като папка.
Това е специална папка, за да сте сигурни.
Но дали това наистина изтриете файла?
>> Е, не, защото някои от вас вероятно да бъде като, о, по дяволите, не си
исках да го направя.
Значи щракнете два пъти върху Trash или Recycle Bin.
Ти бавно бръкна и сте възстановени файла само като го плъзнете
от там.
Така че очевидно, това не е задължително изтриване на него.
>> ОК, ти си по-умен от това.
Вие знаете, че просто го плъзнете в Trash или Recycle Bin не означава,
сте го изпразвате.
Така че и да отидете до менюто, а вие казвате, Empty Trash или Empty Recycle Bin.
Тогава какво се случва?
>> Да, той ще бъде изтрит и повече.
Но всичко, което се случва, е това.
Компютърът забравя къде resume.doc беше.
>> Но това, което не се е променило очевидно на снимката?
Битовете, на 0s и 1s, че аз твърдя, са на мястото на някои физически аспект
хардуера.
Те са все още там.
Това е просто компютърът има забравили какво са те.
>> Така че това е същество остави на файла бита, така че те могат да бъдат използвани.
Но не, докато не се създадат повече файлове, и още много други файлове, и повече файлове ще
вероятностно, тези 0s и 1s, тези магнитни частици, се използват повторно,
нагоре или надясно, нагоре, за други файлове, 0s и 1s.
>> Така че имате този прозорец от време.
И това не е на предвидима дължина, наистина.
Тя зависи от размера на вашия твърд диск и броя на файловете, които имате и
колко бързо ще направи нови.
Но има и този прозорец от време, през които този файл все още е напълно
подлежат на възстановяване.
>> Така че, ако някога използват програми като McAfee Norton или да се опита да се възстанови
данни, всичко, което правят се опитва да възстановяване на тази така наречена директория
разбера, когато файла е.
И понякога Norton и ще каже: файл е 93% възстановяване.
Е, какво значи това?
Това просто означава, че някой друг файл случайно стигна до използване на, да речем,
тези битове от вашите оригиналния файл.
>> Така че това, което действително се състоеше във възстановяването на данни?
Е, ако не е нужно нещо подобно Norton предварително инсталиран на вашия компютър,
най-доброто което понякога може да направите, е да погледнете в целия твърд диск търсите
модели на битове.
И една от темите на проблема в стаята пет е, че ще търси в
еквивалент на твърдия диск, съдебно- изображение на един компактен флаш карта от
Цифрови фотоапарати, търсейки 0s и 1S, че обикновено, с висока
вероятността, представляват начало на изображението JPEG.
>> И вие може да възстанови тези снимки от поема, ако видя, че този модел на
бита на съдебномедицински образ, с висока степен на вероятност, че марки
началото на JPEG.
И ако видя същия модел отново, че най-вероятно е началото на
друг JPEG, и друга JPEG, JPEG и друг.
И това е типично как за възстановяване на данни ще работи.
Какво е хубаво за JPEGs е, въпреки че самия файл формат е малко
Комплексът, в началото на всеки такъв файл всъщност е доста разпознаваеми
и просто, както ще видите, ако не сте вече.
>> Така че нека да погледнем по-отблизо под качулката представа каква точно е бил
става, и какви са тези 0s и 1s са, за да ви дам малко повече от една
контекста на тази намеса.
>> [VIDEO PLAYBACK]
>> -Къде си PC съхранява най- от постоянните данни.
За да направите това, данните пътува от RAM заедно с софтуерни сигнали, които разказват
на твърдия диск как да съхраняват тези данни.
Твърдите вериги диск Превод тези сигнали в напрежение
колебания.
Те, от своя страна, се контролира твърдия диск движещи се части, някои от малкото
движещи се части, останали в модерен компютър.
>> Някои от сигнали за управление на моторно която върти покрити с метал плата.
Данните ви са действително складираното на тези плочи.
Други сигнали се премести на четене / запис главите за четене или
записва данни на плата.
Тази техника толкова точни, че човек коса дори не можеше да мине между
глави и въртящите се плочи.
Но всичко това работи в страхотни скорости.
>> [END възпроизвеждане на видео]
>> DAVID Malan: Zoom в малко по-дълбоко в това, което е сега
всъщност на тези плочи.
>> [VIDEO PLAYBACK]
>> -Нека да разгледаме това, което току-що видях на забавен каданс.
Когато един бърз импулс на електроенергия е изпраща на четене / запис на главата, ако обръща
на малък електромагнитен за За частица от секундата.
Магнитът създава поле, което промените полярността на малка, малка
част от метални частици, които Герб всяка повърхността на плочите.
>> A модел серия от тези малки, зарядна до района на диск
представлява единична малко данни в двоично число
система, използвана от компютри.
Сега, ако токът се изпраща по един начин чрез четене / запис на главата, на площ
поляризация в една посока.
Ако токът се изпраща в обратна посока,
поляризация се отпише.
>> Как можете да получите данни на разстояние от твърдия диск?
Само обръщане на процеса.
Така че това е частиците на диска че да получите на тока в
четене / запис на главата се движи.
Взети заедно тези милиони магнитни сегменти, и
имаш файл.
>> Сега, тези части на един файл могат бъдат пръснати навсякъде по задвижването
плочи, нещо като каша на документи на бюрото си.
Така специален допълнителен файл следи на, където всичко е.
Да не ти се иска да имаше нещо такова?
>> [END възпроизвеждане на видео]
>> DAVID Malan: OK, може би не.
Така че, колко от вас момчета израснал с тези?
ОК, така че е все по-малко ръцете всяка година.
Но се радвам, че си най-малко запознати с тях, защото това и нашата собствена
книга демо, за съжаление, умират много бавна смърт тук за познаване.
>> Но това е, което най-малко през гимназията, използвани използване за архивиране.
И беше невероятно, защото може да съхранява 1.4 мегабайта на
този диск.
И това е най-висока версия плътност, както е посочено от HD, която има
означава преди видеота днешните HD.
>> Standard плътност е 800 килобайта.
А преди това, имаше 400-килобайт дискове.
А преди това имаше 5 и 1/4 инчови дискове, които са били наистина флопи,
и малко по-широко и по-високи от тези неща тук.
Но всъщност можете да видите така наречения флопи аспект на тези дискове.
>> И функционално, те са всъщност доста подобен на твърди дискове от най-
поне този тип.
Отново, SSD дискове в по-новите компютри работят малко по-различно.
Но ако се преместите, че раздела метал, всъщност можете да видите малко бисквитка,
или поднос.
>> Това не е метал като този.
Това е всъщност някаква по-евтино пластмасов материал.
И вие можете да вид го мърдам.
И сте trully просто изтрива някои броят на битовете, или магнитни частици
от този диск.
>> Така че, за щастие, няма нищо по него.
Ако това нещо е в пътя - и покриване очите си и тези на ближния си -
може просто да дръпнете този вид цялата обвивка от такова.
Но там е малко пролетта, така че бъдете наясно, че с очите си.
Така че сега имате наистина дискета.
>> И това, което е забележително в този е, че, доколкото това е
дребния представителство на по-голям твърд диск, тези неща са супер,
супер проста.
Ако захванете дъното на това, че сега този метал нещо е изключен, и кори
ги отворите, всичко, което трябва е две парчета филц и така наречената дискета
с парче метал от вътрешната страна.
>> И там отива половината от ми диска съдържание.
Има отива друг половината от тях.
Но това е всичко, което се въртеше в на компютъра в недалечното минало.
>> И отново, за да приложат това на гледна точка, Колко е голям-голямата част от
твърди дискове тези дни?
500 гигабайта, а терабайт, може би в настолен компютър, 2 терабайта, 3
терабайта, 4 терабайта, нали?
Това е един мегабайт, или да се даде, който дори не може да се вмести в типичен MP3
вече тези дни, или някои подобен музикален файл.
>> Така че малко сувенири за вас днес, и също да помогне в контекст какво
ще бъде като за даденост сега в проблем зададете пет.
Така че тези, които са твой да запазите.
Така че нека преход до мястото, където ще бъде прекара следващите PSET, както добре.
Така че ние вече е определен за тази страница - о, Няколко съобщения бързо.
>> Този петък, ако искате да се присъединят CS50 за обяд, отидете на обичайното място,
cs50.net/rsvp.
И окончателен проект -
така на учебната програма, ние сме публикувал окончателен проект спецификация вече.
Осъзнайте, че това не означава, това е поради по-специално най-скоро.
Той е публикувал, наистина, само за да се момчета мисля за това.
И наистина, супер значително процент от вас ще бъде справянето
окончателните проекти върху материал, който ние дори не са стигнали до в класа,
но ще най-рано следващата седмица.
>> Забележете обаче, че спец. призовава за няколко различни компоненти на
окончателен проект.
Първият, в рамките на няколко седмици, е предварително предложение, доста случайни имейл, за да
си TF да му кажа или какво сте мисля за за вашия проект, с
не се ангажират.
Предложението ще бъде вашето специално ангажимент, като каза, тук, това е, което
Бих искал да направя за моя проект.
Какво мислите?
Твърде голям?
Твърде малък?
Дали е управляем?
И вие виждате спец. за повече подробности.
>> Няколко седмици след това е състояние доклад, който е подобен
случайни имейл, за да ви TF да се каже точно колко далеч зад себе си в крайна
проекта изпълнение, следвани от на CS50 Hackathon който всеки
е поканен, който ще бъде събитие от 20:00 от едната вечер до 07:00
Ч. на следващата сутрин.
Pizza, както може да са споменати в седмицата нула, ще се запазят се сервира в 21:00,
Китайска храна в 1:00 AM.
И ако все още сте будни в 5:00 AM, ние ще ви отведе до ИХОП за закуска.
>> Така Hackathon е един от най- незабравими преживявания в класа.
След изпълнението се дължи и тогава кулминационната CS50 Fair.
Повече подробности за всички тези в идните седмици.
>> Но нека се върнем към нещо старата школа -
отново масив.
Така масив е хубаво, защото това решава проблеми като видяхме само
преди малко със студентските структури става малко извън контрол, ако ние
искат да имат един студент, ученик две, студент три, студент точка точка точка,
някои произволен брой студенти.
>> Така масиви, преди няколко седмици, се спусна в и решават всичките ни проблеми, на не
знаейки предварително, колко неща на някакъв вид да ни се иска.
И видяхме, че structs може да ни помогне допълнителна организира нашия код и да
концептуално подобни променливи, като име и къща, заедно, така че да можем
може да се отнасяме към тях като едно цяло, вътре от които са по-малки парчета.
>> Но масиви имат някои недостатъци.
Какви са някои от недостатъците ние сме срещали
с масиви до този момент?
Какво е това?
Фиксиран размер - така, въпреки че може да може да бъде заделена памет за
масив, след като знаете колко студенти имате колко знака имате
от страна на потребителя, след като веднъж сте разпределени масива, вие сте вид боядисани
себе си в ъгъла.
>> Защото не можеш да се вмъкват нови елементи в средата на масив.
Вие не можете да поставите повече елементи в края на масив.
Наистина, трябва да се прибегне до създаването на изцяло нов масив, както говорихме,
копиране на стария в новия.
И отново, това е главоболие, което GetString сделки с за вас.
>> Но отново, не може дори да вмъкнете нещо в средата на масива
ако размерът не е изцяло запълнени.
Например, ако този масив тук на площ шест има само пет неща в нея,
добре, можеш да халс нещо към края.
Но какво, ако желаете да вмъкнете нещо в средата на
масив, въпреки че може да има Пет от шест неща в него?
>> Е, какво правим, когато сме имали всички от нашите доброволци на сцената в
седмица миналото?
Ако искахме да поставите някой тук, или тези хора как да продължи този
начин, или тези хора как да се движи този начин, и че става скъпо.
Преместването на хора в на масив в крайна сметка сумиране и остойностяване
ни време, поради което много от нашите п квадрат използвате пъти като вмъкване вид, за
Например, в най-лошия случай.
Така масиви са големи, но трябва да знае предварително колко големи ги искате.
>> Така OK, ето едно решение.
Ако не знаете предварително колко учениците може да имам, и знам, че веднъж
Реша, все пак, аз съм остана с тази много ученици, защо не правя просто винаги
разпределят два пъти по-голямо пространство колкото и да мисля, че трябва?
Това не е ли разумно решение?
>> Реално, аз не мисля, че ние сме ще се нуждаят от повече от 50 слота
в масив за средни клас, така че нека просто закръгли в посока нагоре.
Ще направя 100 слотове в моя масив, просто така че определено може да получите
Броят на студентите очаквам да да бъде по някакъв среден клас.
Така че, защо просто не закръглят и да заделят повече памет, като цяло, за масив
отколкото си мислиш, че може дори да трябва?
Какво е това просто отпор за тази идея?
>> Просто си губиш паметта.
Буквално всяка програма ви пиша след това е може би използва два пъти повече памет
действително имате нужда.
А това просто не се чувствам като особено елегантно решение.
Освен това само намалява вероятността от проблем.
Ако се случи да има популярна разбира се един семестър и имате 101
студенти, програмата ви е все още фундаментално са изправени пред същия проблем.
>> Така че, за щастие, има решение да Тази реклама на всички наши проблеми под формата
на структурата на данните, които са по-сложни от тези
сме виждали до този момент.
Това, смея да твърдя, е свързан списък.
Това е списък от числа -
9, 17, 22, 26, и 34 -
, които са свързани помежду си чрез от това, което съм изготвен като стрели.
>> С други думи, ако исках да представляват масив, което можех да направя
нещо като това.
И аз ще сложа тази на въздушната Само след минута.
Не можех да направя -
Здравей, добре.
Готовност.
New компютъра тук, ясно -
Добре.
>> Така че, ако имам тези числа в масив -
9, 17, 22, 26, 24 -
не е задължително да мащаб.
Добре, така че тук е моят масив -
О, Боже мой.
Добре, така че тук е моят масив.
О, Боже мой.
>> [СМЯХ]
>> DAVID Malan: преструвам.
Това е твърде много усилия, за да се върнете и да определи, че, така че -
26.
Така че ние имаме този набор от 9, 17, 22, 26, и 34.
За тези от вас, да видите неудобно грешка Току-що направи,
то е там.
>> Така че аз твърдя, че това е много ефективно решение.
Аз бях разпределени както много цели числа като Имам нужда - един, два, три,
четири, пет, или шест -
и аз след това се съхраняват цифрите вътре в този масив.
Но представете си, а след това, искам да вмъкнете стойност, като номер 8?
Е, къде отиде?
Да предположим, че искате да вмъкнете редица като 20.
Е, къде отиде?
Някъде там в центъра, или номера 35 трябва да отиде
някъде в края.
Но аз съм на пространството.
>> И така, това е основно предизвикателство на масиви, които са се разтвора.
I твърди преди малко, GetString решава този проблем.
Ако искате да вмъкнете шести номер в този масив, това, което е най-малко една
разтвор може да падне обратно на сигурно, точно както правим с GetString?
Какво е това?
>> Е, да я направи голяма е лесно да се каже отколкото да се направи.
Ние не винаги могат да направят масив по-големи, но това, което можем да направим?
Направете нов масив, който е по-голям, на площ 6, или може би размер 10, ако искаме
да напреднат на нещата, и след това да копирате стария масив в новата и след това
освободи стария масив.
>> Но каква е времето за работа сега на този процес?
Това е голяма O М, защото е копирал ще ви струва някои звена на
време, така че да не толкова идеална, ако ние трябва да разпредели на нов масив, който ще
да консумират два пъти повече памет временно.
Копирай стария в новия -
Искам да кажа, че това е просто главоболие, което е, отново, защо ние написахме
GetString за вас.
>> И така, какво може да правим, а?
Ами, ако данните ни структура действително има пропуски в нея?
Да предположим, че аз се отпуснете моята цел като съседни блокове памет, където 9
е в непосредствена близост до 17, което е в непосредствена близост до 22, и така нататък.
>> И предполагам, че 9 може да бъде тук в RAM и 17 може да е тук в RAM,
и 22 може да е тук в RAM.
С други думи, аз не се нуждаят от тях дори Насрещен вече.
Просто трябва по някакъв начин да вдявам игла през всяка от тези номера, или всяка
на тези възли, както ще го наричаме правоъгълници, както съм ги изготвени, до
Спомням си как да стигнем до последния като възел от първата.
>> И така, какво е програмиране изграждане видяхме съвсем наскоро, с които съм
може да реализира тази нишка, или съставен тук, с които мога да
прилагане на тези стрели?
Така указатели, нали?
Ако не се разпределят само Int, но възел - и от
възел, аз просто означава контейнер.
И визуално, искам да кажа на правоъгълник.
Така възел очевидно трябва да съдържа две стойности -
самата Int, и след това, както се предлага от долната половина на правоъгълника,
достатъчно място за едно цяло число.
>> Така си мислех преди тук, Колко е голям този възел, този
въпросният контейнер?
Колко байта за Int?
Предполага се, че 4, ако това е същото, както обикновено.
И тогава колко байта за показалеца?
4.
Така че този контейнер, или този възел, е ще бъде 8-байтов структура.
О, и това е едно щастливо съвпадение, че ние просто въведе това понятие за
на структура, или структура, C.
>> Така че аз твърдя, че искам да направим стъпка към тази по-сложни
прилагането на списък с числа, а свързан списък от числа, трябва да се направи
малко повече мислене отпред и декларират не само едно цяло число, а структурата
че ще се обадя, конвенционално Оттук възел.
Бихме могли да го наречем нещо, което искаме, но възел ще бъде тематично в много
от нещата, които да започнат да търсят в момента.
>> Вътре в този възел е едно цяло число N.
И след това синтаксис, малко странно на пръв поглед -
структурата възел * следващия.
Е картинно, какво е това?
Това е долната половина на правоъгълника, която видяхме
само преди миг.
>> Но защо казвам структура възел * за разлика от само възел *?
Защото ако това показалеца сочи в друг възел, това е просто
адрес на възел.
Това е в съответствие с това, което сме обсъдени насоки за този момент.
Но защо, ако аз твърдя, тази структура е нарича възел, трябва ли да се каже, структура
възел вътре тук?
>> Точно така.
Това е нещо като глупав реалността на C. The typedef, така да се каже, не е
случило все още.
C е супер буквално.
Той гласи кода отгоре отдолу, отляво надясно.
И докато не го удари, че точка и запетая на долния ред, предполагам, какво не
съществуват като тип данни?
Node, цитирам цитата възел.
>> Но тъй като на по-многословен декларация, което направих на първа линия -
typedef структура възел -
защото това е първо, преди фигурни скоби, че е нещо като
предварително обучение звъня, че сте Знаете ли какво, дай ми структура
нарича структура възел.
Честно казано, не ми харесва наричат ​​нещата структурата възел, структурата възел всички
през целия ми код.
Но аз ще я използва само веднъж, само вътре, така че мога да ефективно
създаде нещо като кръгова препратка, не, указател към себе си само по себе си, но
указател към друг на един и същ вид.
>> Така се оказва, че в структурата на данните по този начин, има няколко
операции, които могат да бъдат от интерес за нас.
Ние може да искате да вмъкнете в списък, подобен на този.
Ние може да искате да изтриете от списък, подобен на този.
Ние може да искаме да търсите в списъка за стойност, или по-общо, да се обходи.
И ход е просто луксозен начин на казвайки старт в ляво и да се премести всички
пътя в дясно.
>> И забележете, дори и с тази малко по- сложна структура от данни, да
ми предложи, че ние може да заеме някои от идеите на последните две седмици и
изпълнение функция, наречена търсите по този начин.
Това ще върне вярно или фалшиви, което показва, да или
Не, п е в списъка.
Второто му аргумент е указател на самия списък, така че
указател към възела.
>> All Отивам да направя след това е декларират временна променлива.
Ще го наречем PTR от Конвенцията, за показалеца.
И аз я зададете равен на началото на списъка.
>> А сега забележи контур време.
Докато показалецът не е равно до нула, аз отивам да се провери.
Стрелката е п равен н, че се пропуска в?
И чакай малко - нов парче синтаксис.
Какво е стрелката изведнъж?
Да?
>> Точно така.
И докато преди няколко минути, ние използвахме тази с точка за достъп до нещо
вътрешността на на структурата, ако променливата сте не е структура
себе си, но указател към структура, За щастие, част от синтаксиса, че
най-накрая прави интуитивен смисъл.
Стрелката означава да следват показалеца, като нашите стрели обикновено означава
картинно, и отидете в Полето за данни вътре.
Така че стрелката е същото като точка, но го използвате, когато имате показалеца.
>> Така че просто да обобщим тогава, ако областта н вътрешността на структурата нарича показалеца
равнява се равнява N, връщане вярно.
В противен случай, тази линия тук - показалка равнява показалеца следващия.
Така че какво е това, забележете, е ако аз съм в момента, сочещи за структурата
съдържащ 9 и 9 не е броят Търся - Предполагам, че аз търся
за п достига 50 -
Отивам да актуализирам данните си за временно показалеца да не посоча този възел
вече, но показалеца стрелката, която ще ме остави тук.
>> Сега, аз осъзнах, е вихрушка въвеждане.
В сряда, ние действително ще направи това с някои хора и с повече
код с по-бавни темпове.
Но осъзнавам, ние сме сега правят нашите данни -сложни структури, така че нашата
алгоритми могат да получат по-ефективно, което ще бъде предпоставка за
PSET шест, когато заредите отново, тези, 150 000 думи, но трябва да го направят
ефективно, а в идеалния случай, да създадете програма, която работи за нашите потребители не в
линейна, а не в п квадрат, но константно време, в идеалния.
>> Ние ще се видим в сряда.
>> Лектор: На следващото CS50, David забрави своя база случай.
>> DAVID Malan: И това е, как ви изпрати текстови съобщения с C. Какво по -
>> [VARIOUS текстово съобщение УВЕДОМЛЕНИЕ SOUNDS]