[Powered by Google Translate] [CS50 ბიბლიოთეკა] [Nate Hardison] [ჰარვარდის უნივერსიტეტის] [ეს არის CS50. CS50.TV] CS50 ბიბლიოთეკა სასარგებლო ინსტრუმენტი, რომელიც ჩვენ დამონტაჟებული ელექტრო მოწყობილობების რათა გაუადვილოს ჩემზე პროგრამების სწრაფი მომხმარებლებს შეყვანის. ამ ვიდეო, ჩვენ უკან დახევის ფარდა და შევხედოთ რა არის CS50 ბიბლიოთეკაში. In ვიდეო C ბიბლიოთეკა, ვსაუბრობთ თუ როგორ # მოიცავს სათაურებში ფაილები ბიბლიოთეკის თქვენს კოდებს, და მაშინ კავშირი ორობითი ბიბლიოთეკა ფაილი დროს აკავშირებს ფაზა საქართველოს compilation პროცესში. Header ფაილი დააკონკრეტა ინტერფეისი ბიბლიოთეკა. ანუ, ისინი დეტალურად ყველა რესურსი, რომ ბიბლიოთეკას აქვს ხელმისაწვდომია გამოიყენოთ, მოსწონს ფუნქცია დეკლარაციების, მუდმივები და მონაცემთა ტიპები. ორობითი ბიბლიოთეკა ფაილი შეიცავს განხორციელების ბიბლიოთეკა, რომელიც დგება საწყისი ბიბლიოთეკის header ფაილი და ბიბლიოთეკის. გ კოდის ფაილი. ორობითი ბიბლიოთეკა ფაილი არ არის ძალიან საინტერესო შევხედოთ რადგან, ისევე, როგორც ორობითი. ასე რომ, მოდით, შევხედოთ header ფაილების ბიბლიოთეკა ნაცვლად. ამ შემთხვევაში, მხოლოდ ერთი header ფაილი სახელად cs50.h. ჩვენ დაყენებული ის მომხმარებლის მოიცავს დირექტორია ერთად სხვა სისტემის ბიბლიოთეკების 'header ფაილი. ერთი პირველი რამ თქვენ შეამჩნევთ არის, რომ cs50.h # მოიცავს header ფაილი სხვა ბიბლიოთეკების - float, ლიმიტები, სტანდარტული bool, და სტანდარტული lib. ერთხელ, შემდეგ პრინციპი არ ხელახლა იბრუნებს საჭე, ჩვენ ავაშენეთ CS0 ბიბლიოთეკის გამოყენებით ინსტრუმენტები, სხვა მოწოდებული ჩვენთვის. შემდეგი რაც თქვენ ნახავთ ბიბლიოთეკაში არის, რომ ჩვენ განსაზღვროს ახალი ტიპის მოუწოდა "string." ეს ხაზი ნამდვილად უბრალოდ ქმნის alias for char * ტიპის, ასე რომ არ magically imbue ახალი string ტიპის ატრიბუტები ჩვეულებრივ ასოცირდება სიმებიანი ობიექტების სხვა ენებზე, როგორიცაა სიგრძე. მიზეზი ჩვენ გავაკეთეთ ეს საფარველად ახალი პროგრამისტების საწყისი გორის დეტალები საქართველოს პოინტერები სანამ ისინი მზად. შემდეგი ნაწილი header ფაილი დეკლარაცია ფუნქციები რომ CS50 ბიბლიოთეკა უზრუნველყოფს ერთად დოკუმენტაცია. გაითვალისწინეთ დონეზე დეტალურად კომენტარი აქ. ეს არის სუპერ მნიშვნელოვანია იმდენად, რომ ადამიანმა იცის როგორ გამოიყენოს ეს ფუნქციები. ჩვენ ვაცხადებთ, თავის მხრივ, ფუნქციების შეეკითხება მომხმარებელს და დაბრუნების სიმბოლო, ორადგილიანი, მოძრავი, ints, ხანგრძლივი longs და სიმები, გამოყენებით ჩვენი საკუთარი string ტიპის. შემდეგ პრინციპი ინფორმაცია მალვის, ჩვენ დააყენა ჩვენი განმარტება ცალკე. გ განხორციელების ფაილი - cs50.c-- მდებარეობს მომხმარებლის წყაროს დირექტორია. ჩვენ იმ პირობით, რომ ფაილის ასე რომ თქვენ შეგიძლიათ შევხედოთ მას, ვისწავლოთ, და recompile იგი სხვადასხვა მანქანები, თუ თქვენ გაქვთ სურვილი, მიუხედავად იმისა, რომ ჩვენ მიგვაჩნია, რომ ეს უკეთესი მუშაობა ელექტრო ამ კლასში. ყოველ შემთხვევაში, მოდით შევხედოთ ეს არის. ფუნქციების GetChar, GetDouble, GetFloat, GetInt და GetLongLong ყველა აგებული ზევით GetString ფუნქცია. თურმე ისინი ყველა დაიცვას არსებითად იგივე ნიმუში. ისინი იყენებენ ხოლო loop to შეეკითხება მომხმარებელს ერთი ხაზი შეყვანის. ისინი დაბრუნდებიან მასივები, თუ მომხმარებლის საშუალებებით ცარიელი ხაზი. ისინი ცდილობენ გარჩევის მომხმარებლის შეყვანის როგორც შესაბამისი ტიპის, იქნება ეს char, ორმაგი, float და ა.შ. შემდეგ კი არც დაბრუნების შედეგი თუ შეყვანის წარმატებით გაანალიზება ან ისინი reprompt მომხმარებლის. მაღალ დონეზე, არაფერია მართლაც სახიფათო აქ. ალბათ წერილობითი ანალოგიურად სტრუქტურირებული კოდი თავის წარსულში. ყველაზე cryptic ორიენტირებული ნაწილი sscanf მოწოდება, რომ parses მომხმარებლის შეყვანის. Sscanf ნაწილია შეყვანის ფორმატი კონვერტაციის ოჯახს. იგი ცხოვრობს სტანდარტული io.h და მისი საქმეა გარჩევის C სიმებიანი, შესაბამისად კონკრეტულ ფორმატის, შენახვა გარჩევის შედეგების ცვლადი გათვალისწინებული Caller. წლიდან შეყვანის ფორმატი კონვერტაციის ფუნქციები ძალიან სასარგებლო, ფართოდ გამოიყენება ფუნქციები რომ არ ვართ სუპერ ინტუიციური თავდაპირველად, ჩვენ წავიდეთ მეტი როგორ sscanf მუშაობს. პირველი არგუმენტი sscanf არის char * - მომცეთ ხასიათი. იყიდება ფუნქცია იმუშავებს, რომ ხასიათი უნდა იყოს პირველი ხასიათი C სიმებიანი, შეწყვეტილად ერთად null \ 0 ხასიათი. ეს არის სიმებიანი გარჩევის მეორე არგუმენტი sscanf არის სტრიქონში, ჩვეულებრივ გადავიდა როგორც სიმებიანი მუდმივი, და თქვენ ალბათ არ უნახავს სიმებიანი მოსწონს ეს ადრე, როდესაც გამოყენებით printf. პროცენტი შესვლა სტრიქონში მიუთითებს კონვერტაციის specifier. ხასიათი მაშინვე შემდეგ პროცენტს ნიშანი, მიუთითებს C ტიპის, რომ ჩვენ გვინდა sscanf კონვერრტაციისთვის. In GetInt, ხედავთ, რომ არსებობს% d და% გ. ეს ნიშნავს, რომ sscanf შეეცდება ათობითი int -% d - და char -% გ. თითოეული კონვერტაციის specifier სტრიქონში, sscanf მოელის შესაბამისი არგუმენტი მოგვიანებით მისი არგუმენტი სიაში. ეს არგუმენტი უნდა აღვნიშნო, რომ სათანადოდ აკრეფილი საიდან რომელშიც შესანახად შედეგად კონვერტაცია. ტიპიური გზა ამით შევქმნათ ცვლადი on დასტის სანამ sscanf ზარის თითოეული ნივთი, რომ გსურთ გარჩევის საწყისი სიმებიანი და შემდეგ გამოიყენოთ მისამართი ოპერატორი - ampersand - გავლა პოინტერები იმ ცვლადები sscanf ზარი. თქვენ ხედავთ, რომ GetInt ვაკეთებთ სწორედ ეს არის. მარჯვენა ადრე sscanf ზარის ვაცხადებთ, int მოუწოდა N და char ზარის გ შესახებ დასტის, და ჩვენ გავლა მითითებას მათი sscanf ზარი. ჩვენ ამ ცვლადის შესახებ დასტის სასურველია მეტი გამოყენებით სივრცეში გამოყოფილი on ბევრი ერთად malloc, რადგან თქვენ თავიდან ოვერჰედის of malloc ზარი, და თქვენ არ ინერვიულოთ შესახებ ჩამოდის მეხსიერება. ჩარი არ prefixed მიერ პროცენტს ნიშანი არ შეეკითხება კონვერტაცია. პირიქით, უბრალოდ დაამატოთ ფორმატის სპეციფიკაცია. მაგალითად, თუ სტრიქონში წელს GetInt იყო% d ნაცვლად, sscanf რომ ვეძებოთ წერილს მოჰყვა int, და სანამ ეს იქნებოდა ცდილობენ კონვერტირება int, რომ ის არ გააკეთებს არაფერი ერთად. ერთადერთი გამონაკლისი ამ არის whitespace. თეთრი სივრცეში სიმბოლოების სტრიქონში დაემთხვა რომელიმე თანხის whitespace - კი არა ყველა. ასე რომ, ამიტომ კომენტარი აღნიშნავს შესაძლოა წამყვან ან / და გადმოკიდული whitespace. ასე რომ, ამ ეტაპზე გამოიყურება ჩვენი sscanf ზარის შეეცდება გარჩევის მომხმარებლის შეყვანის სიმებიანი მიერ შემოწმების შესაძლო წამყვანი whitespace, მოჰყვა int რომ იქნება მოაქცია და შენახული int ცვლადი N მოჰყვა რამდენიმე თანხის whitespace, და მოჰყვა ხასიათი შენახული char ცვლადი გ. რაც შეეხება დაბრუნებული მნიშვნელობა? Sscanf იქნება გარჩევის შეყვანის ხაზის დასაწყისიდან დასრულებამდე, შეჩერების, როდესაც იგი აღწევს ბოლოს ან როცა პერსონაჟი შეყვანის არ შეესაბამება ფორმატის სიმბოლოს ან როდესაც მას არ შეუძლია მიიღოს კონვერტაცია. მისი დაბრუნების ღირებულება გამოიყენება ერთი როდესაც იგი შეაჩერა. თუ ეს შეჩერდა, რადგან ეს მიაღწიეს ბოლომდე შეყვანის სიმებიანი მიღების წინ ნებისმიერი კონვერტაციები და ადრე ვერ ემთხვევა ნაწილი სტრიქონში, მაშინ სპეციალური მუდმივი EOF უბრუნდება. წინააღმდეგ შემთხვევაში, ის დააბრუნებს ხმების წარმატებული კონვერტაციის, რაც შეიძლება იყოს 0, 1, ან 2, რადგან ჩვენ ვთხოვე ორი კონვერტაციის. ჩვენს შემთხვევაში, ჩვენ გვინდა დავრწმუნდეთ, რომ მომხმარებლის აკრეფილი int და მხოლოდ int. ასე რომ, ჩვენ გვინდა sscanf დაბრუნებას 1. თუ რატომ? თუ sscanf დაბრუნდა 0, მაშინ არ კონვერტაციის შევიდა, ასე მომხმარებლის აკრეფილი რაღაც გარდა int დასაწყისში შეყვანის. თუ sscanf ბრუნდება 2, მაშინ მომხმარებლის საერთოდ სწორად აკრიფოთ ის დასაწყისში შეყვანის, მაგრამ მაშინ აკრეფილი ზოგიერთი არასამთავრობო whitespace ხასიათი შემდგომ წლიდან% C კონვერტაციის შედგა. Wow, რომ საკმაოდ ხანგრძლივი ახსნა ერთი ფუნქცია ზარი. ყოველ შემთხვევაში, თუ გსურთ მეტი ინფორმაციის sscanf და მისი ძმა, შეამოწმეთ კაცი გვერდებზე, Google, ან ორივე ერთად. უამრავი სტრიქონში პარამეტრები, და ეს შეგიძლიათ შეინახოთ თქვენი უამრავი სახელმძღვანელო შრომის, როდესაც ცდილობს გარჩევის სიმებისათვის C. საბოლოო ფუნქცია ბიბლიოთეკა შევხედოთ არის GetString. თურმე GetString არის სახიფათო ფუნქციის დაწერა სწორად, მიუხედავად იმისა, რომ როგორც ჩანს, ასეთი მარტივი, საერთო ამოცანაა. რატომ არის ამ შემთხვევაში? კარგად, მოდით ვიფიქროთ, თუ როგორ ვაპირებთ შესანახად ხაზი მომხმარებლის ტიპის სისტემაში მას შემდეგ, string არის თანმიმდევრობა სიმბოლო, ჩვენ დაგვჭირდება ჩაწერს მას მასივი on დასტის, მაგრამ ჩვენ უნდა ვიცოდეთ, რამდენი ხანი მასივი იქნება, როდესაც ვაცხადებთ, რომ ეს. ანალოგიურად, თუ გვინდა Put It On ბევრი, ჩვენ გვჭირდება გადავიდეთ malloc ბაიტების რაოდენობას გვინდა რეზერვი, მაგრამ ეს შეუძლებელია. ჩვენ არ გვაქვს იდეა რამდენი chars მომხმარებელი აკრიფოთ ადრე მომხმარებლის რეალურად ამჯამად აკრიფოთ მათ. გულუბრყვილო აღნიშნული პრობლემის მოსაგვარებლად არის მხოლოდ ვიტოვებთ დიდ ბლოკი სივრცის, ვთქვათ, მრავალბინიანი 1000 chars ამისთვის მომხმარებლის input, თუ ვივარაუდებთ, რომ მომხმარებლის არასოდეს აკრიფოთ სიმებიანი რომ ხანგრძლივი. ეს არის ცუდი იდეა ორი მიზეზის გამო. პირველი, თუ ვივარაუდებთ, რომ მომხმარებლებს როგორც წესი არ აკრიფოთ სტრიქონები რომ ხანგრძლივი, თქვენ შეიძლება ნარჩენების მეხსიერების დიდ ნაწილს. თანამედროვე მანქანები, ეს არ შეიძლება იყოს საკითხის თუ ამ ერთი ან ორი იზოლირებული შემთხვევაში, მაგრამ თუ თქვენ აღების მომხმარებლის input in loop და შენახვის მოგვიანებით გამოყენება, თქვენ შეგიძლიათ სწრაფად suck up ტონა მეხსიერება. გარდა ამისა, თუ პროგრამა თქვენ წერილობით არის პატარა კომპიუტერი - მოწყობილობის სმარტფონის მსგავსი ან რაღაც შეზღუდული მეხსიერება - ამ გადაწყვეტა გამოიწვევს პრობლემებს ბევრი უფრო სწრაფად. მეორე, უფრო სერიოზული მიზეზი, რომ აღარ არის, რომ ის დატოვებს თქვენს პროგრამაში დაუცველი თუ რა ე.წ. ბუფერული overflow თავდასხმა. პროგრამირებაში, ბუფერული არის მეხსიერების გამოიყენება დროებით შესანახად შეყვანის ან გამომავალი მონაცემები, რაც ამ შემთხვევაში არის ჩვენი 1000-char ბლოკი. ბუფერული overflow ხდება, როდესაც მონაცემები წერია წარსულში ბოლოს ბლოკი. მაგალითად, თუ მომხმარებლის რეალურად აკეთებს ტიპის ზე მეტ 1000 სიმბოლო. ალბათ გამოცდილი ამ შემთხვევით, როდესაც პროგრამირების ერთად მასივები. თუ თქვენ გაქვთ მასივი 10 ints, არაფერი აჩერებს თქვენ წაკითხვის მცდელობისას ან ჩაწერის 15 int. არ არის შემდგენელი გაფრთხილებებისა და შეცდომები. პროგრამა მხოლოდ შეცდომების სწორი წინ და ხელმისაწვდომი მეხსიერება სადაც მას მიაჩნია, 15 int იქნება, და ეს შეიძლება ჩაანაცვლებს სხვა ცვლადები. ყველაზე ცუდ შემთხვევაში, შეგიძლიათ გადავაწერო ზოგიერთი თქვენი პროგრამის შიდა კონტროლის მექანიზმების, რამაც თქვენი პროგრამის რეალურად შეასრულოს სხვადასხვა მითითებებს ვიდრე თქვენ განკუთვნილი. ახლა, ეს არ საერთო ამის შემთხვევით, მაგრამ ეს საკმაოდ გავრცელებული ტექნიკა რომ ცუდები გამოიყენოთ შესვენება პროგრამები და დააყენა მუქარის კოდი სხვა ხალხის კომპიუტერები. აქედან გამომდინარე, ჩვენ არ შეგვიძლია ისარგებლეთ ჩვენი გულუბრყვილო გადაწყვეტა. ჩვენ გვჭირდება თავიდან აცილების საუკეთესო საშუალებაა ჩვენი პროგრამების მიმდინარეობს დაუცველი დან ბუფერული overflow თავდასხმა. ამისათვის, ჩვენ უნდა დავრწმუნდეთ, რომ ჩვენი ბუფერული შეგიძლიათ იზრდება როგორც ვკითხულობთ მეტი შეიტანენ მომხმარებლის. გამოსავალი? ჩვენ ვიყენებთ ბევრი გამოყოფილი ბუფერული. მას შემდეგ, რაც ჩვენ შეგვიძლია შემცირება მისი გამოყენება Resize realloc ფუნქცია, და ჩვენ ტრეკზე ორი ნომერი - მაჩვენებელი მომდევნო ცარიელ ჭრილში ბუფერული და სიგრძის ან მოცულობა ბუფერული. ვკითხულობთ chars საწყისი მომხმარებლის ერთ დროს გამოყენებით fgetc ფუნქცია. არგუმენტი fgetc ფუნქცია იღებს - stdin - არის მინიშნება სტანდარტული input სიმებიანი, რაც preconnected შეყვანის არხი, რომელიც გამოიყენება გადასცეს მომხმარებლის შეყვანის საწყისი ტერმინალის პროგრამა. როდესაც მომხმარებლის ტიპის ახალი ხასიათის, ჩვენ შეამოწმეთ, რომ ინდექსი მომდევნო უფასო სლოტი Plus 1 მეტია მოცულობა ბუფერული. +1 მოდის რადგან თუ მომავალი უფასო ინდექსი არის 5, მაშინ ჩვენი ბუფერული მისი სიგრძე უნდა იყოს 6 წყალობით 0 ინდექსირებას. თუ ჩვენ ამოიწურა სივრცეში ბუფერული, მაშინ ჩვენ ცდილობენ შეცვლის მას, გააორმაგოს ისე, რომ ჩვენ მოჭრილი რაოდენობის შესახებ ჯერ რომ ჩვენ ზომის შეცვლა თუ მომხმარებელს აკრეფით მართლაც ხანგრძლივი string. თუ სიმებიანი აქვს მიღებული ძალიან გრძელი ან თუ ჩვენ ამოიწურა ბევრი მეხსიერება, ჩვენ გასათავისუფლებლად ჩვენი ბუფერული და დაბრუნების null. საბოლოოდ, ჩვენ დამატება char რომ ბუფერული. ერთხელ მომხმარებლის ჰიტები შევა ან დაბრუნების, სასიგნალო ახალი ხაზი, ან სპეციალური char - კონტროლი დ - რომელიც გვიჩვენებს ბოლომდე შეყვანა, ვაკეთებთ შეამოწმეთ, რომ მომხმარებლის რეალურად აკრეფილი არაფერი ყოფილა. თუ არა, ვბრუნდებით null. წინააღმდეგ შემთხვევაში, რადგან ჩვენი ბუფერული ალბათ უფრო დიდი ვიდრე ჩვენ გვჭირდება, ყველაზე ცუდ შემთხვევაში ეს თითქმის ორჯერ დიდი, როგორც ჩვენ გვჭირდება რადგან ჩვენ გაორმაგდეს ყოველ ჯერზე ჩვენ შემცირება, ჩვენ ახალი ასლი string გამოყენებით მხოლოდ თანხის სივრცეში, რომ ჩვენ გვჭირდება. ჩვენ დაამატოთ Extra 1 დან malloc ზარი, ასე, რომ არც ერთ ფართი სპეციალური null terminator ხასიათი - \ 0, რომელიც ჩვენ დამატება to string ერთხელ ჩვენ ასლი დანარჩენი გმირები, გამოყენებით strncpy ნაცვლად strcpy ასე, რომ ჩვენ შეგვიძლია მიუთითოთ ზუსტად რამდენი chars გვინდა ასლი. Strcpy აკოპირებს სანამ ჰიტები \ 0. მაშინ ჩვენ გასათავისუფლებლად ჩვენი ბუფერული და დააბრუნოს ასლი Caller. ვინ იცოდა ასეთი მარტივი მოჩვენებითი ფუნქცია შეიძლება ასე რთული? ახლა თქვენ იცით, რა შედის CS50 ბიბლიოთეკაში. ჩემი სახელი არის Nate Hardison, და ეს არის CS50. [CS50.TV]