۲۹ شهریور ۱۴۰۳

Techboy

اخبار و اطلاعات روز تکنولوژی

چرا زبان برنامه نویسی C همچنان حاکم است؟

زبان C برای چندین دهه جزء اصلی برنامه نویسی بوده است. در اینجا نحوه انطباق آن با C++، Java، C#، Go، Rust، Python و جدیدترین بچه موجود در بلوک-Carbon آمده است.

زبان C برای چندین دهه جزء اصلی برنامه نویسی بوده است. در اینجا نحوه انطباق آن با C++، Java، C#، Go، Rust، Python و جدیدترین بچه موجود در بلوک-Carbon آمده است.

زبان برنامه نویسی C از سال ۱۹۷۲ زنده و رواج یافته است و هنوز هم به عنوان یکی از اجزای اساسی دنیای نرم افزاری ما حاکم است. اما در مورد ده ها زبان جدیدتری که در چند دهه اخیر ظهور کرده اند، چه می توان گفت؟ برخی به صراحت برای به چالش کشیدن سلطه C طراحی شده بودند، در حالی که برخی دیگر آن را به عنوان محصول جانبی محبوبیت خود حذف کردند.

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

C در مقابل C++

C اغلب با C++ مقایسه می‌شود، زبانی که -همانطور که از نامش مشخص است- به‌عنوان پسوند C ایجاد شده است. بسته به اینکه تفاوت‌های بین C++ و C را می‌توان به‌عنوان گسترده یا بیش از حد توصیف کرد. از چه کسی می‌پرسید.

در حالی که C++ همچنان از نظر نحو و رویکرد خود مانند C است، بسیاری از ویژگی‌های واقعاً مفیدی را ارائه می‌کند که به صورت بومی در C در دسترس نیستند: فضاهای نام، قالب‌ها، استثناها، مدیریت خودکار حافظه و غیره. پروژه هایی که نیاز به عملکرد سطح بالایی دارند – مانند پایگاه های داده و سیستم های یادگیری ماشینی – اغلب در C++ نوشته می شوند و از این ویژگی ها برای حذف هر افت عملکرد از سیستم استفاده می کنند.

علاوه بر این، C++ با شدت بیشتری نسبت به C به گسترش خود ادامه می‌دهد. C++ 23 آینده حتی موارد بیشتری از جمله ماژول‌ها، برنامه‌ها و یک کتابخانه استاندارد مدولار شده برای کامپایل سریع‌تر و کدهای موفق‌تر را به جدول می‌آورد. در مقابل، نسخه برنامه‌ریزی‌شده بعدی به استاندارد C، C2x، چیز کمی اضافه می‌کند و بر حفظ سازگاری به عقب تمرکز دارد.

موضوع این است که همه نکات مثبت در C++ می توانند به عنوان منفی نیز کار کنند. بزرگ ها هر چه بیشتر از ویژگی های C++ استفاده کنید، پیچیدگی بیشتری معرفی می کنید و رام کردن نتایج دشوارتر می شود. توسعه دهندگانی که خود را به زیرمجموعه ای از C++ محدود می کنند، می توانند از بسیاری از بدترین مشکلات آن جلوگیری کنند. اما برخی از مغازه ها می خواهند از این پیچیدگی به طور کلی محافظت کنند. برای مثال، تیم توسعه هسته لینوکس از C++ اجتناب می‌کند و در حالی که اکنون با توجه به Rust به عنوان زبانی برای افزودن هسته های آینده، اکثر لینوکس همچنان به زبان C نوشته می شود.

انتخاب C به جای C++ راهی برای توسعه‌دهندگان و کسانی است که کد خود را حفظ می‌کنند تا از مینیمالیسم اجباری استقبال کنند و از درهم‌تنیدگی با افراط‌های C++ اجتناب کنند. البته، C++ دارای مجموعه ای غنی از ویژگی های سطح بالا به دلایل خوبی است. اما اگر مینیمالیسم برای پروژه‌های فعلی و آینده – و تیم‌های پروژه – مناسب‌تر باشد، C منطقی‌تر است.

C در مقابل جاوا

پس از دهه‌ها، جاوا به عنوان یکی از اصلی‌ترین بخش‌های توسعه نرم‌افزار سازمانی باقی می‌ماند—و به طور کلی جزء اصلی توسعه است. نحو جاوا مقدار زیادی از C و C++ وام گرفته است. با این حال، برخلاف C، جاوا به طور پیش‌فرض به کد بومی کامپایل نمی‌شود. در عوض، کامپایلر JIT جاوا (فقط در زمان) کد جاوا را برای اجرا در محیط هدف کامپایل می کند. موتور JIT روال‌ها را در زمان اجرا بر اساس رفتار برنامه بهینه می‌کند، و به کلاس‌های بهینه‌سازی بسیاری اجازه می‌دهد که با C کامپایل‌شده پیش از زمان امکان‌پذیر نیست. ج.

و در حالی که زمان اجرا جاوا مدیریت حافظه را خودکار می کند، می توان در اطراف آن کار کرد. به عنوان مثال، Apache Spark با استفاده از بخش‌های “ناامن” از زمان اجرا جاوا برای تخصیص مستقیم و مدیریت حافظه و جلوگیری از سربار سیستم جمع‌آوری زباله JVM، پردازش درون حافظه را تا حدی بهینه می‌کند.

7 ویژگی کلیدی برای Kubernetes و امنیت کانتینر

فلسفه جاوا “یک بار بنویس، هر جا اجرا شود” همچنین این امکان را برای برنامه های جاوا فراهم می کند که با تغییرات نسبتا کمی برای معماری هدف اجرا شوند. در مقابل، اگرچه C به بسیاری از معماری‌ها منتقل شده است، هر برنامه C مفروض ممکن است همچنان برای اجرای درست روی ویندوز، مثلاً در لینوکس، نیاز به سفارشی‌سازی داشته باشد.

این ترکیبی از قابلیت حمل و عملکرد قوی، همراه با اکوسیستم عظیمی از کتابخانه‌ها و چارچوب‌های نرم‌افزاری، جاوا را به یک زبان و زمان اجرا برای ساخت برنامه‌های سازمانی تبدیل می‌کند. جایی که کمتر از C است، منطقه ای است که این زبان هرگز برای رقابت در نظر گرفته نشده است: دویدن نزدیک به فلز، یا کار مستقیم با سخت افزار.

کد C در کد ماشین کامپایل می شود که توسط فرآیند مستقیماً اجرا می شود. جاوا به بایت کد کامپایل می شود که کد میانی است که مفسر JVM سپس به کد ماشین تبدیل می کند. علاوه بر این، اگرچه مدیریت خودکار حافظه جاوا در بیشتر شرایط یک موهبت است، اما C برای برنامه‌هایی که باید از منابع حافظه محدود استفاده بهینه کنند، بهتر است، زیرا ردپای اولیه آن کم است.

C در مقابل C# و .NET

نزدیک به دو دهه پس از معرفی، C# و .NET بخش‌های اصلی دنیای نرم‌افزار سازمانی باقی مانده‌اند. گفته شده است که C# و .NET پاسخ مایکروسافت به جاوا بودند – یک سیستم کامپایلر کد مدیریت شده و زمان اجرا جهانی – و بسیاری از مقایسه‌های بین C و جاوا برای C و C#/.NET نیز قابل انجام است.

مانند جاوا (و تا حدودی پایتون)، دات نت قابلیت حمل در پلتفرم های مختلف و اکوسیستم وسیعی از نرم افزارهای یکپارچه را ارائه می دهد. با توجه به میزان توسعه سازمانی در دنیای دات نت، اینها مزیت های کوچکی نیستند. هنگامی که شما برنامه ای را به زبان سی شارپ یا هر زبان دات نت دیگری توسعه می دهید، می توانید از مجموعه ای از ابزارها و کتابخانه های نوشته شده برای زمان اجرا دات نت استفاده کنید.

یکی دیگر از مزیت های دات نت شبیه جاوا، بهینه سازی JIT است. برنامه‌های C# و .NET را می‌توان پیش از موعد بر اساس C کامپایل کرد، اما آنها عمدتاً به‌موقع توسط زمان اجرا دات‌نت کامپایل شده و با اطلاعات زمان اجرا بهینه‌سازی می‌شوند. کامپایل JIT انواع بهینه‌سازی‌های در محل را برای یک برنامه دات‌نت در حال اجرا امکان می‌دهد که در C قابل انجام نیستند.

C# و .NET مانند C (و تا حدی جاوا)، مکانیسم‌های مختلفی را برای دسترسی مستقیم به حافظه فراهم می‌کنند. هیپ، پشته و حافظه سیستم مدیریت نشده همگی از طریق APIها و اشیاء دات نت قابل دسترسی هستند. و توسعه دهندگان می توانند از حالت ناامن در دات نت برای دستیابی به عملکرد بیشتر استفاده کنند.

هر چند هیچ کدام از اینها به صورت رایگان ارائه نمی شود. اشیاء مدیریت شده و اشیاء ناامن را نمی توان خودسرانه رد و بدل کرد و مارشال کردن بین آنها هزینه عملکردی را به همراه دارد. بنابراین، به حداکثر رساندن عملکرد برنامه‌های NET به معنای به حداقل رساندن حرکت بین اشیاء مدیریت‌شده و مدیریت‌نشده است.

وقتی نمی توانید جریمه حافظه مدیریت شده در مقابل حافظه مدیریت نشده را بپردازید، یا زمانی که زمان اجرا دات نت انتخاب ضعیفی برای محیط هدف است (مثلاً فضای هسته) یا ممکن است اصلاً در دسترس نباشد، C آنچه شما نیاز دارید و برخلاف سی شارپ و دات نت، C به طور پیش فرض دسترسی مستقیم به حافظه را باز می کند.

C در مقابل Go

نحو Go مدیون C است – پرانتزهای فرفری به‌عنوان جداکننده و عباراتی که با نقطه ویرگول خاتمه می‌یابند فقط دو نمونه هستند. برنامه‌نویسان مسلط به C معمولاً می‌توانند بدون مشکل زیاد وارد Go شوند، حتی با در نظر گرفتن ویژگی‌های جدید Go مانند فضاهای نام و مدیریت بسته.

Deno runtime اکنون با Jupyter Notebook ادغام می شود

کدهای قابل خواندن یکی از اهداف طراحی راهنمای Go بود: به توسعه‌دهندگان کمک کنید تا با هر پروژه Go سرعت خود را بالا ببرند و در کوتاه‌مدت با پایگاه کد مهارت پیدا کنند. ایجاد پایگاه‌های کد C می‌تواند سخت باشد، زیرا مستعد تبدیل شدن به لانه‌ای از ماکروها و #ifdef‌های مختص یک پروژه و یک تیم خاص هستند. سینتکس Go و ابزارهای قالب‌بندی کد و مدیریت پروژه داخلی آن، به منظور جلوگیری از این نوع مشکلات سازمانی است.

Go همچنین دارای ویژگی‌های اضافی مانند گوروتین‌ها و کانال‌ها، ابزارهای سطح زبان برای مدیریت همزمانی و ارسال پیام بین مؤلفه‌ها است. C به چنین چیزهایی نیاز دارد که به صورت دستی یا توسط یک کتابخانه خارجی عرضه شوند، اما Go آنها را خارج از جعبه فراهم می کند و ساختن نرم افزارهایی را که به آنها نیاز دارد بسیار آسان تر می کند.

جایی که Go بیشتر با C زیر هود تفاوت دارد در مدیریت حافظه است. اشیاء Go به طور خودکار مدیریت می شوند و به طور پیش فرض زباله جمع آوری می شوند. برای اکثر مشاغل برنامه نویسی، این بسیار راحت است. اما این بدان معناست که هر برنامه ای که نیاز به مدیریت قطعی حافظه دارد، نوشتن سخت تر خواهد بود.

Go شامل بسته ناامن برای دور زدن برخی از ایمنی‌های مدیریت نوع Go است، مانند خواندن و نوشتن حافظه دلخواه با نوع Pointer. اما ناامن با هشداری همراه است مبنی بر اینکه برنامه‌های نوشته شده با آن “ممکن است غیرقابل حمل باشند و توسط دستورالعمل‌های سازگاری Go 1 محافظت نشده باشند.”

Go برای ساختن برنامه هایی مانند ابزارهای خط فرمان و خدمات شبکه مناسب است، زیرا به ندرت به چنین دستکاری های دقیقی نیاز دارند. اما درایورهای دستگاه سطح پایین، اجزای سیستم عامل فضای هسته، و سایر وظایفی که نیاز به کنترل دقیق روی چیدمان و مدیریت حافظه دارند، بهتر است در C ایجاد شوند.

C در مقابل زنگ

از برخی جهات، Rust پاسخی است به معماهای مدیریت حافظه ایجاد شده توسط C و C++، و همچنین به بسیاری از کاستی های دیگر این زبان ها. Rust به کد ماشین بومی کامپایل می شود، بنابراین از نظر عملکرد با C همتراز است. با این حال، ایمنی حافظه به طور پیش فرض نقطه فروش اصلی Rust است.

قوانین نحوی و کامپایل Rust به توسعه دهندگان کمک می کند از اشتباهات رایج مدیریت حافظه اجتناب کنند. اگر برنامه ای مشکل مدیریت حافظه داشته باشد که از دستور Rust عبور کند، به سادگی کامپایل نمی شود. تازه واردان به این زبان – به خصوص از زبانی مانند C که فضای زیادی برای چنین اشکالاتی فراهم می کند – مرحله اول آموزش Rust خود را به یادگیری نحوه دلجویی از کامپایلر می گذرانند. اما طرفداران Rust استدلال می کنند که این درد کوتاه مدت نتیجه بلندمدتی دارد: کد ایمن تر که سرعت را قربانی نمی کند.

ابزار Rust در C نیز بهبود می‌یابد. مدیریت پروژه و مؤلفه بخشی از زنجیره ابزاری است که به طور پیش‌فرض با Rust عرضه می‌شود، که مشابه Go است. یک راه پیش‌فرض و توصیه‌شده برای مدیریت بسته‌ها، سازمان‌دهی پوشه‌های پروژه، و رسیدگی به بسیاری از موارد دیگر وجود دارد که در C در بهترین حالت موقتی هستند و هر پروژه و تیم به طور متفاوتی آنها را مدیریت می‌کنند.

با این حال، آنچه در Rust به عنوان یک مزیت تبلیغ می شود، ممکن است برای یک توسعه دهنده C به نظر نرسد. ویژگی‌های ایمنی زمان کامپایل Rust را نمی‌توان غیرفعال کرد، بنابراین حتی پیش پا افتاده‌ترین برنامه Rust باید با محدودیت‌های ایمنی حافظه Rust مطابقت داشته باشد. C ممکن است به طور پیش فرض کمتر ایمن باشد، اما در صورت لزوم بسیار انعطاف پذیرتر و بخشنده تر است.

اخبار در fediverse

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

C در مقابل پایتون

این روزها، هر زمان که صحبت در مورد توسعه نرم افزار است، به نظر می رسد پایتون همیشه وارد گفتگو می شود. از این گذشته، پایتون “دومین زبان بهترین برای همه چیز” و بدون شک یکی از همه کاره ترین ها است، با هزاران کتابخانه شخص ثالث در دسترس است.

آنچه پایتون بر آن تاکید دارد و در جایی که بیشتر با C تفاوت دارد، ترجیح دادن سرعت توسعه بر سرعت اجرا است. برنامه ای که ممکن است یک ساعت طول بکشد تا در یک زبان دیگر – مانند C – جمع شود، ممکن است در چند دقیقه در پایتون مونتاژ شود. از طرف دیگر، اجرای آن برنامه در C ممکن است چند ثانیه طول بکشد، اما اجرای آن در پایتون یک دقیقه طول می کشد. (به عنوان یک قانون سرانگشتی خوب، برنامه‌های پایتون معمولاً نسبت به همتایان C خود کندتر اجرا می‌شوند.) اما برای بسیاری از مشاغل روی سخت‌افزار مدرن، پایتون به‌اندازه کافی سریع است، و این امر کلیدی برای آن بوده است. جذب.

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

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

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

C در مقابل کربن

یکی دیگر از رقبای احتمالی اخیر برای C و C++ Carbon است، زبان جدیدی که در حال حاضر در حال توسعه شدید.

هدف Carbon این است که جایگزینی مدرن برای C و C++ باشد، با یک نحو ساده، ابزار مدرن و تکنیک‌های سازماندهی کد، و راه‌حل‌هایی برای مشکلاتی که برنامه‌نویسان C و C++ مدت‌هاست با آن مواجه بوده‌اند. همچنین به منظور ایجاد تعامل با پایگاه های کد C++ است، بنابراین کد موجود می تواند به صورت تدریجی منتقل شود. همه اینها یک تلاش خوشایند است، زیرا C و C++ در طول تاریخ دارای ابزارها و فرآیندهای ابتدایی در مقایسه با زبان‌های اخیراً توسعه‌یافته‌اند.

پس جنبه منفی آن چیست؟ در حال حاضر کربن یک پروژه آزمایشی است که از راه دور برای استفاده در تولید آماده نیست. حتی یک کامپایلر کار وجود ندارد. فقط یک کاوشگر کد آنلاین. مدتی طول می کشد تا کربن به یک جایگزین عملی برای C یا C++ تبدیل شود، اگر چنین شود.