ترفندهای ++C (سری ۱)

1641

در این مقاله قصد داریم چند تکنیک در برنامه‌نویسی با زبان ++C را مرور کنیم. این تکنیک‌ها بعضاً با اصول کدنویسیِ تمیز مغایرت دارند، ولی:

  • باعث ‌جمع‌وجورتر شدن برنامه‌های شما می‌شوند. بنابراین در مسابقات می‌توانید سریع‌تر پیاده‌سازی کنید.
  • برخی از این نکات روی زمان اجرای برنامه‌ی شما و خطاهای احتمالی مؤثر هستند.

اگر شما هم از نکات و ترفندهای دیگری استفاده می‌کنید، خوشحال می‌شویم که آن‌ها را در قسمت نظراتِ این مقاله برای ما بنویسید تا بتوانیم در مقالات بعدی از پیشنهادهای شما هم استفاده کنیم.

دستور ios_base::sync_with_stdio(false)

دستور زیر را در خط اول تابع main بنویسید:

 ios_base::sync_with_stdio(false);

توجه کنید اگر در برنامه‌ی خود با استفاده از ابزارهای زبان C مثل ‍‍scanf و printf ورودی می‌گیرید، از این دستور استفاده نکنید، زیرا:

همان طور که می‌دانید دستورات زبان C در زبان ++C قابل استفاده هستند. یعنی می‌توانید هم با استفاده از ‍scanf (دستوری در زبان C) و هم با استفاده از cin (دستوری در زبان ++C) ورودی بگیرید. استفاده‌ی هم‌زمان از این دو دستور و خواندن ورودی به‌صورت یکپارچه، نیاز به هماهنگی (Synchronized) دارد. به‌صورت ساده‌تر وقتی یکی از این دستورها ورودی را خواند، دستور دیگر باید خودش را با آن هماهنگ کند و بداند که ورودی تا کجا خوانده شده است. خواندن ورودی بخش مهمی از زمان اجرای یک برنامه را به خود اختصاص می‌دهد و اگر این هماهنگی را حذف نکنید، زمان خواندن ورودی را افزایش می‌دهید (تقریباً دوبرابر زمان لازم).

همان‌طور که انتظار می‌رود، بسیاری از برنامه‌نویسانی که در مسابقات مختلف شرکت می‌کنند، کم‌و‌بیش این تجربه را داشته‌اند که اگر از این دستور استفاده نکنند، برنامه‌ی آن‌ها با خطای محدودیت زمان (time limit exceeded) مواجه می‌شود و تنها با اضافه کردن این دستور، مشکل برطرف می‌شود.

برای مطالعه‌ی بیشتر، این پیوند را بررسی کنید.

تفاوت بین endl و n\

زمانی که یک دستور درخواست چاپ‌کردن چیزی را دارد، برنامه‌ی شما آن را در یک بافر (buffer) قرار می‌دهد و در پردازش‌های موازی خود، در فرصتی مناسب تمام آن‌ها را به‌صورت یکجا چاپ می‌کند. به دستوری که باعث نمایش محتوای ذخیره‌شده در این بافر می‌شود، فلاش (flush) گفته می‌شود.

فرق بین endl و n\ در همین فلاش است. یعنی endl یک دستور فلاش درون خود دارد ولی \n فلاش ندارد. به همین دلیل پیشنهاد می‌کنیم زمانی که تعداد خروجی‌ها زیاد است از n\ استفاده کنید تا برنامه شما سریع‌تر شود. همچنین اگر خودتان نیاز به اجرای فلاش دارید، می‌توانید آن را به روش‌های مختلف فراخوانی کنید.

با این حال، به همان اندازه که n\ باعث کاهش سرعت خروجی‌دادنِ برنامه می‌شود، ممکن است در چاپ‌ِ خطاهایی که برای دیباگ‌کردن به آن‌ها احتیاج دارید، دردسرساز شود. به عنوان مثال، اگر برنامه، چاپ مواردی که برای فهمیدن روند اجرای برنامه ضروری هستند را به انتهای کار موکول کند، ممکن است در زمان‌هایی که برنامه با خطای «زمانِ اجرا» مواجه می‌شود، این خطا چاپ نشود.

برای مطالعه‌ی بیشتر، این پیوند را بررسی کنید.

دستور cin.tie(NULL)

دستور زیر را در خط اول تابع main بنویسید.

cin.tie(NULL);

شرط استفاده از این دستور این است که سؤال به‌صورت تعاملی (intractive) نباشد. در حال حاضر، هیچ سؤالی در کوئرا به این صورت نیست، بنابراین به‌راحتی می‌توانید از این دستور استفاده کنید. به‌طور کلی زمانی که ورودی‌گرفتن و خروجی‌دادن‌ها در میان یکدیگر انجام می‌شوند، نباید از این دستور استفاده کرد. اما در حالتی که ورودی به‌صورت یکجا به برنامه داده می‌شود و خروجی نیز به‌صورت یکجا بررسی می‌شود، می‌توان از این دستور استفاده کرد.

یک اشتباه رایج در میان شرکت‌کنندگانِ مسابقات، این است که ابتدا همه‌ی ورودی‌ها را می‌خوانند و سپس همه‌ی خروجی‌ها را چاپ می‌کنند. توجه کنید چه از این دستور استفاده کنید و چه نکنید، نیازی به این کار نیست و شما می‌توانید در میان ورودی‌گرفتن‌ها خروجی بدهید. این دستور صرفاً باعث می‌شود که ورودی‌گرفتن و خروجی‌دادن در میان یکدیگر، باعث کندی برنامه‌ی شما نشود.

برای مطالعه‌ی بیشتر، نظراتِ این قسمت را بخوانید.

آموزش برنامه نویسی با کوئرا کالج
امین انوری سرور

اشتراک در
اطلاع از
guest

4 دیدگاه‌
قدیمی‌ترین
تازه‌ترین بیشترین واکنش
بازخورد (Feedback) های اینلاین
View all comments
علی زمانی
علی زمانی
2 سال قبل

لطفا ترفند های سریع شدن برای C هم بزارید

امیر
امیر
3 ماه قبل

سلام آقای انوری وقتتون بخیر
اگر که یک دوره مقدماتی یا پیشرفته بهینه سازی کد در زبان C++ بذارید ممنون میشم. چون بهبود عملکرد برنامه ای که می نویسیم به خیلی فاکتورها بستگی داره، یه دوره جامع می تونه خیلی مفید باشه.
با تشکر

reyhaneh karami
ادمین
2 ماه قبل
پاسخ به  امیر

لزوماً بهینه‌سازی کردن راه‌های کند منجر به رسیدن به راه‌حل‌های درست نمی‌شه.

در بعضی از موارد شاید باید به کل از یک روش کارآمدتری استفاده کرد.

برای این منظور کوئرا دوره‌ی الگوریتم‌های پیشرفته رو در نظر گرفته.