[Powered by Google Translate] [CS50 کتابخانه]
[مقابله Hardison] [دانشگاه هاروارد]
[این CS50 است. CS50.TV]
کتابخانه CS50 یک ابزار مفید است که در حال حاضر بر روی دستگاه نصب شده
به آن را آسان تر برای شما برای نوشتن برنامه های که سریع کاربران برای ورودی.
در این فیلم، ما جلو و پشت پرده و به دنبال آنچه که دقیقا در کتابخانه CS50.
>> در این ویدئو در کتابخانه های C، ما در مورد چگونگی # شامل فایل های header
از کتابخانه در کد منبع خود را،
و پس از آن شما با یک فایل باینری کتابخانه در طول مرحله ارتباط را لینک کنید
فرآیند تدوین است.
این فایل های سرآیند مشخص رابط از کتابخانه است.
این است که، آنها با جزئیات همه از منابعی که کتابخانه در دسترس را برای شما به استفاده از،
مانند اظهارات تابع، ثابت ها و انواع داده.
کتابخانه فایل های باینری شامل پیاده سازی از کتابخانه،
است که از فایل های هدر کتابخانه و کتابخانه C فایل های کد منبع وارد شده است.
>> کتابخانه فایل های باینری بسیار جالب است که به دنبال در از آن، به خوبی، در باینری نیست.
بنابراین، اجازه دهید یک نگاهی به فایل های هدر برای کتابخانه به جای.
در این مورد، تنها یک فایل سرآیند به نام cs50.h. وجود دارد
ما آن را در کاربر نصب شامل دایرکتوری
همراه با فایل های سرآیند کتابخانه های سیستم های دیگر.
>> یکی از اولین چیزهایی که شما متوجه خواهید شد این است که cs50.h # شامل فایل های هدر از کتابخانه های دیگر -
شناور، محدودیت، استاندارد بولی، و معاونت استاندارد.
دوباره، پس از اصل اختراع دوباره چرخ،
ساخته شده های کتابخانه CS0 با استفاده از ابزار هایی که برای ما فراهم کرده ایم.
>> چیزی که بعد از شما در کتابخانه را ببینید این است که تعریف یک نوع جدید به نام "رشته است."
این خط واقعا فقط ایجاد یک نام مستعار برای نوع char *،
پس از آن سحر و جادو نیست رسوخ نوع رشته ای جدید با ویژگی های
به طور معمول با رشته اشیاء در زبان های دیگر همراه است،
مانند طول.
به این دلیل است که ما انجام داده ایم این است برای محافظت از برنامه نویسان جدید از جزئیات لخته
از اشاره گر تا زمانی که آنها آماده شده است.
>> قسمت بعدی فایل هدر اعلامیه از توابع است
که کتابخانه CS50 فراهم می کند همراه با مستندات.
توجه کنید که سطح جزئیات در نظرات اینجا.
این فوق العاده مهم است، به طوری که مردم می دانند که چگونه به استفاده از این توابع.
ما اعلام می کنیم، به نوبه خود، توابع به بی درنگ کاراکتر کاربر و بازگشت، دو برابر، شناور، نوع داده int،
طولانی مشتاق، و رشته ها، با استفاده از نوع رشته خود ما است.
به دنبال اصل پنهان کردن اطلاعات،
در حال حاضر تعریف ما را در یک فایل جداگانه پیاده سازی C قرار داده است - cs50.c -
واقع در منبع راهنمای کاربر.
ما فایل به طوری که شما می توانید یک نگاهی به آن را ارائه کرده است که،
یادگیری از آن و کامپایل مجدد آن را در دستگاه های مختلف اگر می خواهید،
حتی اگر ما فکر می کنم بهتر است به کار بر روی لوازم خانگی برای این کلاس است.
به هر حال، اجازه دهید نگاهی به آن در حال حاضر است.
>> از توابع GetChar، GetDouble، GetFloat، GetInt، و GetLongLong
همه در بالا از تابع GetString ساخته شده است.
به نظر می رسد که همه آنها در اصل همان الگوی.
آنها با استفاده از یک حلقه در حالی که به سریع کاربر برای یک خط از ورودی است.
آنها یک مقدار را برگرداند در صورتی که کاربر ورودی یک خط خالی است.
آنها تلاش برای تجزیه ورودی کاربر را به عنوان نوع مناسب،
می شود آن را یک کاراکتر، دو، شناور، و غیره
و سپس آنها را یا در نتیجه اگر ورودی با موفقیت تجزیه شد بازگشت
یا آنها reprompt کاربر.
>> در سطح بالا، هیچ چیز واقعا مشکل در اینجا وجود دارد.
شما ممکن است نوشته اند به همین ترتیب ساختار کد خود را در گذشته است.
شاید بخش مرموز، به دنبال تماس sscanf که تجزیه ورودی کاربر است.
Sscanf بخشی از خانواده تبدیل فرمت های ورودی می باشد.
در io.h استاندارد زندگی می کند، و کار آن است که برای تجزیه یک رشته C،
با توجه به یک فرمت خاص، ذخیره نتایج تجزیه در متغیر
ارائه شده توسط تماس گیرنده.
از آنجا که توابع تبدیل فرمت ورودی بسیار مفید می باشد، به طور گسترده ای استفاده می شود توابع
که در ابتدا فوق العاده حسی نیست،
خواهیم به بیش از sscanf کار می کند.
>> اولین آرگومان به sscanf * کاراکتر می باشد - یک اشاره گر به یک شخصیت است.
برای تابع به درستی کار نکند،
است که شخصیت باید اولین کاراکتر از یک رشته C،
فسخ با تهی \ 0 کاراکتر است.
این رشته برای تجزیه است
آرگومان دوم به sscanf یک رشته فرمت،
به طور معمول به عنوان یک ثابت رشته گذشت،
و ممکن است شما را دیده اند، یک رشته مانند این قبل از زمانی که با استفاده از printf است.
علامت درصد در رشته فرمت تعیین تبدیل را نشان می دهد.
شخصیت بلافاصله پس از علامت درصد،
را نشان می دهد نوع C که ما می خواهیم sscanf برای تبدیل به.
در GetInt، شما می بینید که٪ D و C٪ وجود دارد.
این به این معنی که sscanf به بین المللی اعشاری را امتحان کنید - درصد د - و کاراکتر -٪ C است.
برای هر یک از تعیین تبدیل در رشته فرمت،
sscanf مربوط به بحث انتظار دارد بعد از آن در لیست استدلال خود را.
استدلال باید به یک مکان مناسب تایپ
که در آن برای ذخیره نتیجه از تبدیل.
>> روش معمول برای انجام این کار این است که برای ایجاد یک متغیر را بر روی پشته قبل از تماس sscanf
برای هر مورد را که می خواهید از رشته تجزیه
علامت - - به تصویب اشاره گرها و سپس عملگر آدرس استفاده کنید
به کسانی که متغیرها را به تماس sscanf.
شما می توانید ببینید که در GetInt ما دقیقا این است.
درست قبل از تماس sscanf، از نوع int به نام N و C تماس کاراکتر در پشته ما اعلام می کنیم،
و ما عبور اشاره گر آنها را به تماس sscanf.
قرار دادن این متغیرها را بر روی پشته بیش از با استفاده از فضای اختصاص داده شده ترجیح داده است
در پشته با malloc، از سربار تماس malloc جلوگیری از،
و شما لازم نیست که به نگرانی در مورد نشت حافظه.
حرف با علامت درصد پیشوند تبدیل سریع نیست.
بلکه آنها فقط به مشخصات قالب اضافه کنید.
>> به عنوان مثال، در صورتی که رشته فرمت در GetInt D٪ به جای آن،
sscanf نامه بین المللی نگاه کنید،
و در حالی که آن را تلاش بین المللی برای تبدیل، آن را به هر چیز دیگری نیست.
تنها استثنا در این فضای خالی می باشد.
کاراکترهای فضای خالی در رشته فرمت در نظر گرفتن هر مقدار از فضای خالی -
حتی هیچ کدام در همه.
بنابراین، به همین دلیل است که نظر اشاره احتمالا با پیشرو و / یا عقبی فضای خالی است.
بنابراین، در این نقطه آن را مانند تماس sscanf ما به نظر می رسد، سعی خواهد کرد که به تجزیه رشته ورودی کاربر
برای چک کردن ممکن است فضای خالی پیشرو،
به دنبال بین المللی است که خواهد شد و در متغیر از نوع int N تبدیل شده و ذخیره می شود
به دنبال آن مقداری از فضای خالی، و به دنبال یک شخصیت
ذخیره شده در C کاراکتر متغیر است.
>> در مورد مقدار بازگشتی؟
Sscanf خط ورودی از شروع تجزیه را به پایان برساند،
توقف زمانی که آن را به پایان می رسد و یا هنگامی که یک شخصیت در ورودی
یک شخصیت فرمت مطابقت ندارد و یا وقتی که آن را می توانید تبدیل را ندارد.
مقدار بازگشتی این است که استفاده می شود تا تنها زمانی که از آن متوقف شد.
اگر از آن متوقف شد، چرا که آن را به پایان رشته ورودی
قبل از هر گونه تبدیل و قبل از به دلیل عدم مطابقت با بخشی از رشته فرمت،
سپس EOF خاص ثابت است، بازگشته است.
در غیر این صورت، آن را برمی گرداند تعدادی از موفق تبدیل،
که می تواند 0، 1، 2، از آنجایی که ما خواسته که به مدت دو تبدیل شده است.
در مورد ما، ما می خواهیم اطمینان حاصل کنید که کاربر در یک int است و تنها یک int تایپ.
>> بنابراین، ما می خواهیم sscanf به بازگشت 1. ببینید که چرا؟
اگر sscanf بازگشت 0، آنگاه هیچ تبدیل شد ساخته شده است،
به طوری که کاربر تایپ، چیزی به غیر از یک int در ابتدای ورودی است.
اگر sscanf برمی گرداند 2، کاربر به درستی آن را در تایپ در ابتدای ورودی،
اما آنها پس از آن در برخی از شخصیت بدون فاصله تایپ بعد از آن
از آنجا که٪ C تبدیل موفق.
وای، که کاملا توضیح طولانی مدت تماس یک تابع است.
به هر حال، اگر شما می خواهید اطلاعات بیشتر در مورد sscanf و خواهر و برادر خود را،
چک کردن صفحات مرد، گوگل، یا هر دو.
هستند بسیاری از گزینه های رشته قالب وجود دارد،
و این می تواند به شما مقدار زیادی از کار دستی صرفه جویی در زمانی که در تلاش برای تجزیه و تحلیل رشته ها در C.
>> تابع نهایی در کتابخانه در نگاه به GetString است.
به نظر می رسد که GetString یک تابع از روی حیله و تزویر به نوشتن درست،
حتی اگر آن را مانند به نظر می رسد چنین ساده، کار مشترک است.
چرا این مورد؟
خوب، اجازه دهید فکر می کنم در مورد چگونه ما در حال رفتن به مغازه های خط که کاربر در انواع ...
از آنجا که یک رشته، دنباله ای از کاراکتر ها است،
ما ممکن است بخواهید آن را در یک آرایه ذخیره بر روی پشته،
اما ما نیاز به دانستن چه مدت طول آرایه است تا زمانی که آن را ما اعلام می کنیم.
به همین ترتیب، اگر ما می خواهیم به آن را در پشته قرار داده است،
ما باید برای تصویب به malloc تعداد کلمه در ادامه متن ما به رزرو می خواهید،
اما این غیر ممکن است.
در حال حاضر هیچ ایده چگونه بسیاری از کاراکتر کاربر را در تایپ
قبل از اینکه کاربر در واقع آنها را تایپ کنید.
>> یک راه حل ساده و بی تکلف برای این مشکل این است که فقط به رزرو یک تکه بزرگ از فضا، می گویند،
یک بلوک از 1000 کاراکتر ورودی کاربر،
فرض کنید که کاربر هرگز به تایپ در یک رشته که مدت ها است.
این یک ایده بد است به دو دلیل است.
اول، فرض کنید که کاربران معمولا در رشته های تایپ که طولانی،
شما می توانید مقدار زیادی از حافظه را تلف.
ماشین آلات مدرن، این ممکن است یک مسئله اگر شما این کار
در یک یا دو نمونه جدا شده،
اما اگر شما در حال گرفتن ورودی کاربر در یک حلقه و ذخیره برای استفاده های بعدی،
شما به سرعت می تواند تا خورد یک تن از حافظه است.
علاوه بر این، در صورتی که برنامه شما در حال نوشتن یک کامپیوتر کوچک است -
یک دستگاه مانند گوشی های هوشمند و یا چیز دیگری با حافظه محدود -
این راه حل مشکلات بسیار سریعتر می شود.
دوم، جدی تر دلیلی برای این کار این است که آن را برگ و برنامه شما را در مقابل
به آنچه که به نام حمله سرریز بافر.
در برنامه نویسی، یک بافر حافظه مورد استفاده قرار گیرد به طور موقت ذخیره داده های ورودی یا خروجی،
که در این مورد 1000 کاراکتر بلوک است.
سرریز بافر رخ می دهد که داده های گذشته است در پایان از بلوک نوشته شده است.
>> برای مثال، اگر یک کاربر در واقع در بیش از 1000 کاراکتر می باشد.
شما ممکن است را تجربه کرده اند به طور تصادفی در هنگام برنامه نویسی را با آرایه.
اگر شما مجموعه ای از 10 نوع داده int، هیچ چیز شما را از تلاش برای خواندن و یا نوشتن
هوشمند 15.
بدون اخطار یا خطاهای کامپایلر وجود دارد.
این برنامه فقط اشتباهات راست جلو و دسترسی به حافظه
که در آن فکر می کند که از INT 15 خواهد بود، و این می تواند متغیر دیگر خود را بازنویسی.
در بدترین حالت، شما می توانید برخی از داخلی برنامه های خود را بازنویسی
مکانیسم کنترل، ایجاد برنامه های خود را به واقع دستورالعمل های مختلف اجرا
از شما در نظر گرفته شده است.
>> در حال حاضر، آن را برای انجام این کار به طور تصادفی نیست،
اما این یک روش نسبتا شایع است که بچه های بد در استفاده از برنامه برای شکستن است
قرار داده و کد های مخرب بر روی کامپیوتر افراد دیگر.
بنابراین، ما فقط نمی تواند استفاده از راه حل های ساده و بی تکلف ما.
ما نیاز به یک راه برای جلوگیری از برنامه های ما را از خطر
حمله سرریز بافر.
برای انجام این کار، ما نیاز به مطمئن شوید که بافر ما می تواند به رشد ما به عنوان خوانده شده
ورودی از کاربر است.
راه حل؟ ما با استفاده از پشته بافر اختصاص است.
از آنجا که ما می توانیم تغییر اندازه آن را با استفاده از تغییر اندازه تابع بازتخصیص،
و ما پیگیری از دو عدد - شاخص اسلات خالی بعدی در بافر
و طول و ظرفیت بافر.
ما در کاراکتر از یک کاربر در یک زمان با استفاده از تابع fgetc خواندن.
آرگومان تابع fgetc طول می کشد - STDIN - مرجع به رشته ورودی استاندارد است.
که یک کانال ورودی preconnected است که برای انتقال ورودی کاربر استفاده شده است
از ترمینال به برنامه است.
>> هر زمان که کاربر در یک شخصیت جدید، ما چک کنید اگر شاخص
اسلات آزاد بعدی به همراه 1 بیشتر از ظرفیت بافر است.
+1 می آید چرا که اگر شاخص بعدی رایگان است (5)،
سپس طول بافر ما باید 6 تا 0، نمایه سازی.
اگر ما رو از فضا در بافر اجرا شود، پس از آن ما در تلاش برای آن را تغییر اندازه،
دو برابر آن را به طوری که ما را بر روی کاهش تعداد بار که ما تغییر اندازه
در صورتی که کاربر در حال تایپ کردن در یک رشته واقعا طولانی است.
اگر رشته بدست بیش از حد طولانی و یا اگر ما از حافظه پشته،
ما آزاد بافر و پوچ بازگشت.
>> در نهایت، ما اضافه کاراکتر به بافر است.
به محض بازدید های کاربر را وارد کنید و یا بازگشت، سیگنالینگ یک خط جدید،
یا کاراکتر ویژه - کنترل د - که سیگنال های ورودی، ماوس، کیبورد،
ما می توانم در یک بررسی برای دیدن در صورتی که کاربر در واقع در هر چیزی تایپ در همه.
اگر نه، ما بازگشتی NULL است.
در غیر این صورت، به دلیل بافر ما این است که احتمالا بزرگتر از آنچه ما نیاز داریم،
در بدترین حالت آن را تقریبا دو برابر بزرگ که ما نیاز داریم
از آنجا که هر زمان ما تغییر اندازه دو برابر،
ما را به یک نسخه جدید از رشته فقط با استفاده از مقدار فضای است که ما نیاز داریم.
اضافه می کنیم 1 اضافی به تماس malloc،
به طوری که فضا برای تهی ترمیناتور شخصیت خاص وجود دارد - \ 0،
که ما آن را به رشته اضافه در زمانی که ما در بقیه شخصیت ها را کپی کنید،
با استفاده از strncpy به جای استفاده از strcpy
به طوری که ما می توانید مشخص کنید که دقیقا چه بسیاری از کاراکتر های ما می خواهید کپی کنید.
Strcpy کپی تا آن را بازدیدها \ 0.
سپس بافر ما آزاد و بازگشت به کپی را به تماس گیرنده.
>> که می دانستم که چنین تابع ساده ظاهری می تواند بسیار پیچیده؟
در حال حاضر شما می دانید چه می رود به کتابخانه CS50.
>> نام من مقابله Hardison است، و این CS50.
[CS50.TV]