چرا زبان برنامهنویسی C همچنان حکمرانی میکند
گاهی اوقات یک فناوری به این دلیل که هنوز جایگزینی برای آن پیدا نشده فعال باقی میماند. سیر تکامل و عرضه زبانهای برنامهنویسی در چند دهه گذشته نشان میدهد که برخی از زبانها برای غلبه بر C طراحی شده بودند و برخی دیگر به لطف زبان سی به شهرت رسیدند. شاید پیدا کردن یک جایگزین برای سی کار چندان راحتی نباشد. بیشتر متخصصان دنیای برنامهنویسی به این حقیقت اذعان دارند که برخی از زبانها در انجام یکسری کارها عملکردی بهتر از زبان سی دارند، اما زبان سی به پشتوانه سالها حضور در دنیای برنامهنویسی و سازگاری کم نظیر با محیط پیرامون خود و عملکرد قابل قبول در انجام برخی از وظایف، توانسته است در بیشتر حوزهها با زبانهای برنامهنویسی نوین رقابت کند. چه عواملی به زبان سی اجازه دادهاند از رقبای قدرتمند خود در دنیای برنامهنویسی یک گام جلوتر باشد؟ در ادامه به چند مورد از این عوامل اشارهای خواهیم داشت.
C در برابر ++C
در بیشتر منابع C و ++C با یکدیگر مقایسه میشود، زبانی که همانگونه که از نام آن پیدا است، قرار بود مکملی برای C باشد. تفاوتهای بین C و ++C را میتوان به دو شکل «گسترده» یا «بیش از حد و افراطگونه» توصیف کرد. علیرغم اینکه سی پلاسپلاس به لحاظ قواعد دستوری و رویکرد شبیه به زبان سی است، اما ویژگیهای واقعا مفیدی ارائه کرده که زبان سی فاقد این قابلیتها است. فضای نام، الگوها، استثناعات، مدیریت خودکار حافظه و… از جمله تفاوتهای بین این دو زبان برنامهنویسی هستند. پروژههایی که نیازمند عملکرد بهتری هستند، (همچون پایگاههای داده یا سامانههای یادگیری ماشین) اغلب با سیپلاسپلاس نوشته میشوند تا بتوانند از حداکثر ظرفیت یک سامانه استفاده کنند.
سی پلاسپلاس با شتاب بسیار بیشتری نسبت به سی در حال گسترش است. نسخه جدید C++ 20 امکانات بیشتری از جمله ماژولها، کوروتینها، یک کتابخانه هماهنگکننده و مفاهیمی که باعث میشوند استفاده از الگوها راحتتر شود در اختیار برنامهنویسان قرار داده است. با وجود قابلیتهای ارزشمند و مفید که سی پلاسپلاس به آنها تجهیز شده، کار با سی پلاسپلاس زمانبر است. هر چه بیشتر از قابلیتهای سی پلاسپلاس استفاده کنید با پیچیدگیهای بیشتری روبرو خواهید شد که رسیدن به سر منزل مقصود را دشوارتر و کندتر میکند. به همین دلیل، برخی از توسعهدهندگان برای اجتناب از بروز مشکلات پیچیده خود را به انجام یک زیر مجموعه از کارها با سی پلاسپلاس محدود میکنند، بهطور مثال، توسعهدهندگان هسته لینوکس ترجیح میدهند به سراغ زبان سیپلاسپلاس نروند. در حالی که برخی دیگر اعتقادی به پیچیدگیهای سی پلاسپلاس ندارند و سعی میکنند برای ساخت برنامههای مختلف از سیپلاسپلاس استفاده کنند. بدون تردید، توسعهدهندگان سیپلاسپلاس مجموعهای غنی از قابلیتهای سطح بالا را به دلایل مختلفی در این زبان قرار دادهاند، اما اگر کمینهگرایی (minimalism) برای پروژههای حال حاضر و آینده بهتر جواب میدهد بهتر است از زبان سی استفاده کنید.
C در برابر Java
جاوا رقیب دیرینه سی دست کمی از این زبان ندارد. بعد از گذشت سالهای متمادی، جاوا همچنان به عنوان یک بازیگر اصلی در توسعه نرمافزارهای سازمانی شناخته میشود و بهطور کلی نقشی کلیدی در توسعه نرمافزارها بازی میکند. بسیاری از پروژههای شاخص نرمافزاری سازمانی با جاوا نوشته شدهاند که از آن جمله میتوان به اکثریت قریب به اتفاق پروژههای بنیادی نرمافزار آپاچی اشاره کرد. ساختار دستوری جاوا خیلی از ویژگیهای خود را از سی و سیپلاسپلاس عاریه گرفته است. هر چند برخلاف سی، زبان جاوا بهطور پیشفرض کد محلی را کامپایل نمیکند. در عوض محیط اجرایی جاوا (JVM, JIT) کدهای جاوا را برای اجرا در محیط هدف کامپایل میکند. تحت شرایط مناسب، این کدهای جاوای کامپایل شده این پتانسیل را دارند تا عملکردی در سطح یا حتا فراتر از زبان سی ارائه کنند. همچنین، فلسفه «یک بار بنویس، همه جا اجرا کن» در پسزمینه جاوا به برنامههای جاوا اجازه میدهد با کمی دستکاری برای اجرا در محیط مقصد آماده شوند. در مقابل، اگر چه سی به معماریهای بسیار زیادی منتقل شده، اما یک برنامه سی هنوز هم برای اجرای درست به سفارشیسازی نیاز دارد. ترکیب قابل حمل بودن و عملکرد قوی، همراه با اکوسیستمی عظیم از کتابخانهها و چارچوبهای نرمافزاری باعث شده تا جاوا به یک زبان ایدهآل برای ساخت برنامههای سازمانی تبدیل شود.
نقطهای که جاوا در مقابل سی با ضعف روبرو میشود، محدودهای است که جاوا هرگز برای آن طراحی نشده است: کار مستقیم با سختافزار. کدهای سی به کد ماشین کامپایل شده و بهطور مستقیم توسط پردازنده اجرا میشوند. اما جاوا به بایتکد کامپایل میشود که یک کد واسطه از مفسر JVM است که بعدا به کد ماشین تبدیل میشود. علاوه بر این، اگر چه مدیریت حافظه خودکار جاوا در اکثر شرایط مطلوب عمل میکند، اما سی برای برنامههایی که باید استفاده از منابع محدود حافظه را مدیریت و بهینهسازی کنند مطلوبتر است.
در برخی از حوزهها، سرعت جاوا به سی نزدیک میشود. موتور JIT مطابق با رفتار برنامه جریانهای عادی را بهینهسازی میکند و از آنجایی که جاوا در زمان اجرا بهطور خودکار بر فرآیند مدیریت حافظه نظارت دارد، برخی از برنامههای جدیدتر با این قابلیت سازگاری بیشتری دارند. بهعنوان مثال، آپاچی اسپارک با استفاده از کد مدیریت حافظه سفارشی (با ترفند زدن به JVM) پردازش درون حافظهای را بهینهسازی میکند.
C در برابر #C و Net.
نزدیک به دو دهه از معرفی سیشارپ و چارچوب داتنت میگذرد و این زبان و چارچوب قدرتمند به عنوان دو قطب مهم در حوزه نرمافزارهای سازمانی حضور خود را تثبیت کردهاند. کارشناسان حوزه نرمافزار معتقد هستند که سیشارپ و داتنت، پاسخ مایکروسافت به جاوا بودند (یک سامانه کامپایلر مدیریت شده) و به همین دلیل خیلی از مقایسههای انجام گرفته بین سی و جاوا در مورد سی و سیشارپ/داتنت نیز صدق میکند.
شبیه به جاوا، داتنت هم قابلیت انتقال به طیف گستردهای از زیرساختها و اکوسیستم نرمافزارهای یکپارچه را ارائه میکند. موارد یاد شده، قابلیتهای بزرگی هستند که باعث میشوند توسعه سازمانمحور تا حد زیادی به داتنت وابسته باشد. وقتی شما یک برنامه را با سیشارپ یا داتنت تولید میکنید قادر خواهید بود به مجموعه بزرگی از ابزارها و کتابخانههای موجود دسترسی داشته باشید.
یکی دیگر از مزایای مشابه جاوا در داتنت بهینهسازی JIT است. برنامههای سیشارپ و داتنت میتوانند در زمان کوتاهتری نسبت به سی کامپایل شوند. کامپایلر JIT امکان بهینهسازی همه جانبه برای اجرای یک برنامه داتنت را فراهم میکند، قابلیتی که امکان اجرای آن در سی وجود ندارد.
سیشارپ و داتنت شبیه به سی مکانیزمهای متفاوتی برای دسترسی مستقیم به حافظه فراهم میکنند.Heap ،stack و حافظه سیستمی مدیریت نشده همگی از طریق واسطهای برنامهنوسی و اشیا داتنت در دسترس هستند و توسعهدهندگان میتوانند برای دستیابی به عملکردهای بهتر از حالت unsafe در داتنت استفاده کنند.
هر چند هیچکدام از این امکانات رایگان نخواهد بود. اشیا مدیریت شده و اشیا unsafe را نمیتوان خودسرانه باهم مبادله کرد. بنابراین به حداکثر رساندن عملکرد برنامههای داتنت به معنای به حداقل رساندن جابجایی دائم بین اشیا مدیریت شده و مدیریت نشده است.
هنگامی که بهکارگیری همزمان دو رویکرد حافظه مدیریت شده و مدیریت نشده بیش از اندازه پیچیده است یا وقتی محیط زمان اجرای داتنت یک انتخاب ضعیف برای محیط هدف (بهطور مثال فضای هسته) است یا ممکن است در دسترس نباشد، سی اولین و آخرین انتخاب شما است. برخلاف سیشارپ و داتنت، زبان برنامهنویسی سی بهطور پیشفرض دسترسی مستقیم به حافظه را از حالت قفل خارج میکند.
C در برابر Python
هر زمان صحبت از توسعه نرمافزار در میان باشد، پایتون همیشه یک پای ثابت داستان است. پایتون دومین زبان برتر همه منظوره است و بدون شک با هزاران کتابخانه ثالث در دسترس، یکی از همه کارهترین زبانهای حال حاضر است.
عاملی که پایتون را تا این اندازه برجسته میکند و باعث اختلاف آن با سی شده، سرعت توسعه آن در برابر سرعت اجرای آن است. یک برنامه که برای سرهم کردن آن در یک زبان دیگر ممکن است یک ساعت زمان نیاز باشد، در کمتر از یک دقیقه در پایتون نوشته میشود. اما در آن روی سکه، همین برنامه برای اجرا در پایتون ممکن است به یک دقیقه زمان نیاز داشته باشد، در حالی که در سی ظرف کمتر از چند ثانیه اجرا میشود. برنامههای پایتون عموما با سرعت خیلی کمتری نسبت به همتایان سی خود اجرا میشوند. اما برای انجام خیلی از کارها روی سختافزار مدرن پایتون به اندازه کافی سریع عمل میکند.
یکی دیگر از تفاوتهای عمده این دو زبان برنامهنویسی در نحوه مدیریت حافظه آنها نهفته است. حافظه در برنامههای پایتون توسط محیط زمان اجرای پایتون (Python runtime) بهطور کامل قابل مدیریت است، بنابراین توسعهدهندگان دیگر نگران اختصاص دادن حافظه و آزاد کردن آن نخواهند بود. اما توسعهدهندگان باید این قابلیت را در ازای عملکرد محیط زمان اجرا به دست آورند. درست است که توسعهدهندگان برنامههای سی باید به دقت بر همه جوانب مدیریت حافظه نظارت داشته باشند، اما در مقابل سرعت و عملکرد برنامههای سی بسیار شگفتانگیز است. سی و پایتون در پسزمینه وجود اشتراک زیادی با یکدیگر دارند، بهطور مثال، مرجع محیط (reference enviroment) اجرای پایتون به زبان سی نوشته شده است. این مرجع به برنامههای پایتون اجازه میدهد تا بتوانند از کتابخانههای نوشته شده در سی و سیپلاسپلاس استفاده کنند. جالب آنکه برخی از کتابخانههای ثالث اکوسیستم پایتون به ویژه در بحث یادگیری ماشین تا حد زیادی منطبق با زبان سی آماده شدهاند و در نتیجه با کمی تغییر در هر دو زبان قابل استفاده هستند. اگر سرعت توسعه نرمافزارها اهمیت بیشتری نسبت به سرعت اجرا دارد و اگر بیشتر بخشهای اجرایی برنامه را میتوان به مولفههای جداگانه تفکیک کرد، بهکارگیری پایتون یا ترکیبی از پایتون و کتابخانههای سی انتخاب بهتری نسبت به انتخاب سی است. اگر روال کدنویسی شما اینگونه نیست، زبان سی هنوز هم برگ برنده شما در دنیای برنامهنویسی خواهد بود .