لغة البرمجة سي

لغة C هي لغة برمجة عامة الأغراض، ابتكرها دينيس ريتشي في سبعينيات القرن الماضي . تتيح لغة C للمبرمجين الوصول المباشر نسبيًا إلى خصائص بنى المعالجات المركزية النموذجية، مع تخصيصها لمجموعة التعليمات المستهدفة . وقد استُخدمت، ولا تزال تُستخدم، لتنفيذ أنظمة التشغيل (وخاصة النواة [ 10 ]وبرامج تشغيل الأجهزة ، وحزم البروتوكولات ، على الرغم من انخفاض استخدامها في برامج التطبيقات . [ 11 ] تُستخدم لغة C على أجهزة حاسوب تتراوح من الحواسيب العملاقة إلى المتحكمات الدقيقة والأنظمة المدمجة .

طُوِّرت لغة C في البداية كخليفة للغة البرمجة B في مختبرات بيل على يد ريتشي بين عامي 1972 و1973. وكان الغرض الأساسي منها بناء أدوات مساعدة تعمل على نظام يونكس ، ثم استُخدمت لاحقًا لإعادة تنفيذ نواة نظام التشغيل يونكس. [ 12 ] خلال ثمانينيات القرن العشرين، اكتسبت لغة C شعبية تدريجية، ما جعلها إحدى أكثر لغات البرمجة استخدامًا ، [ 13 ] [ 14 ] مع توفر مُجمِّعات C لجميع بنى الحواسيب وأنظمة التشغيل الحديثة تقريبًا. وقد شكّل كتاب "لغة برمجة C" ، الذي شارك في تأليفه مصمم اللغة الأصلي، معيارًا فعليًا للغة لسنوات عديدة . [ 15 ] [ 1 ] وقد تم توحيد لغة C منذ عام 1989 من قِبَل المعهد الوطني الأمريكي للمعايير (ANSI)، ولاحقًا بشكل مشترك من قِبَل المنظمة الدولية للمعايير (ISO) واللجنة الكهروتقنية الدولية (IEC).

لغة C هي لغة إجرائية حتمية ، تدعم البرمجة الهيكلية ، ونطاق المتغيرات المعجمي ، والاستدعاء الذاتي ، مع نظام أنواع ثابت . صُممت لتُترجم لتوفير وصول مباشر إلى الذاكرة وبنى لغوية تُطابق تعليمات الآلة بكفاءة ، كل ذلك بأقل قدر من دعم وقت التشغيل . على الرغم من إمكانياتها المباشرة، صُممت اللغة لتشجيع البرمجة متعددة المنصات. يمكن ترجمة برنامج C متوافق مع المعايير ، مكتوب مع مراعاة قابلية النقل، لمجموعة واسعة من منصات الحاسوب وأنظمة التشغيل مع تغييرات طفيفة في شفرته المصدرية.

على الرغم من أن لغة C ومكتبتها القياسية لا توفران بعض الميزات الشائعة الموجودة في لغات أخرى، إلا أنها تتمتع بمرونة كافية لدعمها. فعلى سبيل المثال، يتم توفير البرمجة الكائنية وجمع البيانات المهملة بواسطة مكتبتين خارجيتين هما GLib Object System و Boehm garbage collector على التوالي.

منذ عام 2000، احتلت لغة C عادةً المرتبة الأولى أو الثانية من حيث الشعبية في مؤشر TIOBE . [ 16 ]

صفات

دينيس ريتشي (على اليمين)، مخترع لغة البرمجة سي، مع كين تومسون

لغة C هي لغة إجرائية ذات بنية مصدرية حرة . تُنهى التعليمات بفواصل منقوطة وتُجمع في كتل باستخدام أقواس معقوفة . جميع التعليمات البرمجية القابلة للتنفيذ موجودة في دوال بدلاً من التعليمات الرئيسية. تحتوي اللغة على عدد قليل نسبيًا من الكلمات المفتاحية، ولا يتم تمييز المعرفات المُعرّفة من قِبل المستخدم عن الكلمات المفتاحية بأي رمز .

تُمرر المعاملات بالقيمة، بينما يُمرر بالمرجع باستخدام المؤشرات . يمكن تجاهل القيمة المُعادة من الدالة، وعلى الرغم من أنه لا يمكن عادةً تضمين دالة داخل دالة أخرى، إلا أن بعض المترجمات تدعم ذلك. تدعم لغة C الاستدعاء الذاتي ، ويمكن تحقيق تعدد الأشكال أثناء التشغيل باستخدام مؤشرات الدوال. يتم التحكم في تدفق البيانات من خلال بنيات مثل if`input` forو` doinput` و` whileinput` و`input` . switchتوفر اللغة عوامل حسابية ومنطقية ، بما في ذلك ` input` و` input` و`input`، ويمكن إجراء عمليات إسناد متعددة في عبارة واحدة. لا يمكن الوصول إلى المتغير المُعلن عنه داخل كتلة إلا داخل تلك الكتلة وأسفل تعريفه فقط.++=++&||

يُفرض تعريف أنواع البيانات بشكل ضعيف وثابت ، مع تحويل ضمني بين الأنواع الأولية. تسمح الأنواع المُعرَّفة من قِبل المستخدم بأسماء بديلة لمُحدِّدات الأنواع. تُعرَّف المصفوفات ويتم الوصول إليها باستخدام تدوين الأقواس المربعة، على سبيل المثال . تسمح أنواع البنيةmonth[11] المُعرَّفة من قِبل المستخدم بتمرير عناصر البيانات ذات الصلة ونسخها كوحدة واحدة، على الرغم من أنه لا يمكن مقارنة بنيتين بدون كتابة كود مخصص لمقارنة كل حقل. تدعم الاتحادات الأعضاء المتداخلة، مما يسمح لأنواع بيانات متعددة بمشاركة نفس موقع الذاكرة ، وتدعم أنواع التعداد أسماء بديلة للقيم الصحيحة. تفتقر لغة C إلى نوع سلسلة نصية مُخصَّص ، ولكنها توفر صيغة للسلاسل النصية المنتهية بـ null ، مع معالجة مُرتبطة بها في مكتبتها القياسية.

تدعم اللغة الوصول المباشر إلى ذاكرة الحاسوب عبر المؤشرات، وبنى شبيهة بالإجراءات على شكل دوال تُرجع قيمة void، وتخصيص الذاكرة الديناميكي من خلال دوال المكتبة القياسية. تتضمن معالج C المسبق لتعريف وحدات الماكرو ، وتضمين ملفات المصدر ، والترجمة المشروطة . وتُدعم البنية المعياريةstatic بمعالجة الملفات بشكل منفصل، مع التحكم في مستوى الوصول إليها عبر سمات `<input>` و`<input> extern`. تم تقليل الوظائف في اللغة الأساسية، حيث تُوفر المكتبات القياسية ميزات معقدة نسبيًا مثل الإدخال والإخراج ، ومعالجة السلاسل النصية، والدوال الرياضية. يتميز الكود المُترجم الناتج بمتطلبات بسيطة نسبيًا للمنصة الأساسية، مما يجعل لغة C مرغوبة لأنظمة التشغيل والأنظمة المدمجة .

مثال "مرحباً بالعالم"

برنامج "مرحباً بالعالم" من تأليف برايان كيرنيغان (1978)

أصبح مثال برنامج "Hello, World!" الذي ظهر في الطبعة الأولى من كتاب K&R نموذجًا لبرنامج تمهيدي في معظم كتب البرمجة. يطبع البرنامج عبارة "hello, world!" على المخرج القياسي .

النسخة الأصلية كانت: [ 17 ]

main () { printf ( "hello, world \n " ); }

أما النسخة الأكثر حداثة فهي: [ د ]

#include <stdio.h>int main ( void ) { printf ( "hello, world \n " ); }

السطر الأول هو توجيه للمعالج المسبق ، يُشار إليه بـ ، والذي يُجبر المعالج المسبق على استبدال هذا السطر من التعليمات البرمجية بنص ملف الرأس، الذي يحتوي على تعريفات لوظائف الإدخال والإخراج، بما في ذلك . تشير الأقواس الزاوية المحيطة بـ إلى إمكانية تحديد موقع ملف الرأس باستخدام استراتيجية بحث تُحدد ملفات الرأس المُرفقة مع المُصرّف بدلاً من الملفات التي تحمل نفس الاسم والتي قد توجد في أدلة خاصة بالمشروع.#includestdio.hprintfstdio.h

يُعلن سطر الكود التالي عن دالة نقطة الدخولmain . يستدعي بيئة التشغيل هذه الدالة لبدء تنفيذ البرنامج. intيُشير مُحدد النوع إلى أن الدالة تُرجع قيمة عددية صحيحة. voidتُشير قائمة المعاملات إلى أن الدالة لا تستهلك أي وسائط. في الواقع، تُمرر بيئة التشغيل وسيطين (من النوعين void intو void char *[])، لكن هذا التنفيذ يتجاهلهما. يتطلب معيار ISO C (القسم 5.1.2.2.1) صيغةً إما أن تكون void أو هذين الوسيطين - وهي معاملة خاصة لا تُمنح للدوال الأخرى. 

يشير القوس المعقوف المفتوح إلى بداية الكود الذي يحدد الدالة.

يستدعي سطر الكود التالي (يحوّل التنفيذ إلى) دالة من مكتبة C القياسية، printfمع تحديد عنوان الحرف الأول من سلسلة نصية منتهية بـ null كسلسلة نصية حرفية . النص \nهو تسلسل هروب يشير إلى حرف السطر الجديد ، والذي عند إخراجه في طرفية، يؤدي إلى نقل المؤشر إلى بداية السطر التالي. على الرغم من أن printfالدالة تُرجع intقيمة، إلا أنها تُتجاهل بصمت. ;تُنهي الفاصلة المنقوطة عبارة الاستدعاء.

يشير القوس المعقوف الأخير إلى نهاية الدالة main. قبل معيار C99، return 0;كان يلزم وجود عبارة صريحة في نهاية mainالدالة، ولكن منذ معيار C99، mainتُنهي الدالة (باعتبارها استدعاء الدالة الأولي) عملها ضمنيًا 0عند الوصول إلى قوسها المعقوف الأخير. [ هـ ]

تاريخ

التطورات المبكرة

الجدول الزمني للغة C
سنةاسم غير رسميالمعيار الرسمي
1972الإصدار الأولغير متوفر
1978كي آند آر سيغير متوفر
1989، 1990ANSI C ، C89، ISO C، C90أنسي X3.159-1989 آيزو/آي إي سي 9899:1990
1999C99 ، C9XISO/IEC 9899:1999
2011C11 ، C1XISO/IEC 9899:2011
2018C17 ، C18ISO/IEC 9899:2018
2024C23 ، C2XISO/IEC 9899:2024
سيتم الإعلان عنه لاحقاًC2Y

يرتبط أصل لغة C ارتباطًا وثيقًا بتطوير نظام التشغيل يونكس ، الذي طُبِّق في الأصل بلغة التجميع على جهاز PDP-7 بواسطة دينيس ريتشي وكين تومسون ، مع دمج العديد من الأفكار من زملائهم. وفي نهاية المطاف، قرروا نقل نظام التشغيل إلى جهاز PDP-11 . كما طُوِّر الإصدار الأصلي من يونكس لجهاز PDP-11 بلغة التجميع. [ 12 ]

ب

أراد تومسون لغة برمجة لتطوير أدوات مساعدة للمنصة الجديدة. حاول أولًا كتابة مُصرّف بلغة فورتران ، لكنه سرعان ما تخلى عن الفكرة، وابتكر بدلًا منها نسخة مُختصرة من لغة برمجة الأنظمة التي طُوّرت حديثًا آنذاك، والتي تُسمى BCPL . لم يكن الوصف الرسمي لـ BCPL مُتاحًا في ذلك الوقت، [ 19 ] فعدّل تومسون بناء الجملة لتكون أقل إسهابًا وأقرب إلى لغة ALGOL المُبسّطة المعروفة باسم SMALGOL. [ 20 ] أطلق على النتيجة اسم B ، [ 12 ] واصفًا إياها بأنها "دلالات BCPL مع الكثير من بناء جملة SMALGOL". [ 20 ] ومثل BCPL، احتوت B على مُصرّف تمهيدي لتسهيل نقلها إلى أجهزة جديدة. [ 20 ] في النهاية، لم تُكتب سوى أدوات مساعدة قليلة بلغة B لأنها كانت بطيئة جدًا، ولم تستطع الاستفادة من ميزات PDP-11 مثل إمكانية عنونة البايت .

على عكس لغة BCPL // commentالتي كانت تُعلّم التعليقات حتى نهاية السطر، اعتمدت لغة B /* comment */فاصلًا للتعليقات، وهو ما يُشبه لغة PL/1، مما يسمح بظهور التعليقات في منتصف الأسطر. (سيتم إعادة تقديم أسلوب التعليقات الخاص بلغة BCPL في لغة C++). [ 12 ]

إصدار جديد من الفئة ب وأول إصدار من الفئة ج

في عام 1971، بدأ ريتشي بتطوير لغة B للاستفادة من مزايا جهاز PDP-11 الأكثر قوة. وكان من الإضافات المهمة نوع بيانات الأحرف، والذي أطلق عليه اسم New B (NB). [ 20 ] بدأ تومسون باستخدام NB لكتابة نواة نظام يونكس ، وقد أثرت متطلباته على مسار تطوير اللغة. [ 20 ] [ 21 ]

حتى عام 1972، أُضيفت أنواع بيانات أكثر ثراءً إلى لغة NB. احتوت NB على مصفوفات من النوعين ` intx` و`y` char، وأُضيفت إلى هذه الأنواع المؤشرات، وإمكانية إنشاء مؤشرات إلى أنواع أخرى، ومصفوفات من جميع الأنواع، وأنواع تُعاد من الدوال. كانت المصفوفات داخل التعبيرات تُعامل فعليًا كمؤشرات. كُتب مُترجم جديد، وأُعيد تسمية اللغة إلى C. [ 12 ]

تم تضمين مترجم لغة C وبعض الأدوات المساعدة التي تم إنشاؤها باستخدامه في الإصدار الثاني من يونكس ، والذي يُعرف أيضًا باسم يونكس البحثي . [ 22 ]

الهياكل وإعادة كتابة نواة يونكس

في الإصدار الرابع من يونكس ، الذي صدر في نوفمبر 1973، تمت إعادة تنفيذ نواة يونكس على نطاق واسع بلغة C. [ 12 ] بحلول هذا الوقت، اكتسبت لغة C بعض الميزات القوية مثل الأنواع.struct

تم تقديم المعالج المسبق حوالي عام 1973 بناءً على اقتراح آلان سنايدر، وأيضًا إدراكًا لفائدة آليات تضمين الملفات المتوفرة في لغتي BCPL و PL/I . كانت نسخته الأصلية توفر فقط تضمين الملفات واستبدال السلاسل النصية البسيطة، #includeبالإضافة #defineإلى وحدات الماكرو بدون معلمات. بعد ذلك بوقت قصير، تم توسيعه، بشكل رئيسي بواسطة مايك ليسك ثم بواسطة جون رايزر، ليشمل وحدات الماكرو ذات الوسائط والترجمة الشرطية . [ 12 ]

كان يونكس من أوائل أنظمة التشغيل التي طُبِّقت بلغة برمجة غير لغة التجميع . ومن الأمثلة السابقة نظام Multics (المكتوب بلغة PL/I ) وبرنامج التحكم الرئيسي (MCP) لجهاز Burroughs B5000 (المكتوب بلغة ALGOL ) عام 1961. وفي عام 1977 تقريبًا، أدخل ريتشي وستيفن سي. جونسون تعديلات إضافية على اللغة لتسهيل نقل نظام التشغيل يونكس. وقد شكّل مُجمِّع جونسون المحمول للغة C أساسًا للعديد من تطبيقات لغة C على منصات جديدة. [ 21 ]

كي آند آر سي

غلاف كتاب "لغة البرمجة سي" ، الطبعة الأولى، من تأليف برايان كيرنيغان ودينيس ريتشي

في عام ١٩٧٨، نشر برايان كيرنيغان ودينيس ريتشي الطبعة الأولى من كتاب "لغة البرمجة سي" . [ ٢٣ ] عُرف الكتاب اختصارًا بـ K&R نسبةً إلى الأحرف الأولى من اسمي مؤلفيه، وظل لسنوات عديدة بمثابة مواصفات غير رسمية للغة. يُشار إلى نسخة لغة سي التي يصفها الكتاب عادةً باسم " K&R C ". ونظرًا لإصدارها عام ١٩٧٨، يُشار إليها الآن أيضًا باسم C78 . [ ٢٤ ] أما الطبعة الثانية من الكتاب [ ٢٥ ] فتغطي معيار ANSI C الأحدث ، والموصوف أدناه.

قدمت شركة K&R العديد من الميزات اللغوية:

  • مكتبة الإدخال/الإخراج القياسية
  • long intنوع البيانات
  • unsigned intنوع البيانات
  • تم تغيير عوامل التعيين المركبة من الشكل (مثل ) إلى الشكل (أي ) لإزالة الغموض الدلالي الناتج عن تركيبات مثل ، والتي تم تفسيرها على أنها (إنقاص بمقدار 10) بدلاً من المقصود المحتمل (ليكن −10).=op=-op=-=i=-10i =- 10ii = -10i

حتى بعد نشر معيار ANSI لعام 1989، ظل K&R C لسنوات عديدة يعتبر " القاسم المشترك الأدنى " الذي تقيد به مبرمجو لغة C أنفسهم عندما كانت هناك رغبة في أقصى قدر من قابلية النقل، نظرًا لأن العديد من المترجمات القديمة كانت لا تزال قيد الاستخدام، ولأن كود K&R C المكتوب بعناية يمكن أن يكون قانونيًا أيضًا كلغة C قياسية.

على الرغم من أن الإصدارات اللاحقة من لغة C تتطلب تعريفًا صريحًا لأنواع الدوال، فإن لغة K&R C لا تتطلب سوى تعريف أنواع الدوال التي تُرجع قيمةً غير النوع intالمحدد قبل استخدامها. أما الدوال المستخدمة دون تعريف مسبق، فيُفترض أنها تُرجع قيمةً من النوع المحدد int.

على سبيل المثال:

long long_function ();استدعاء_الدالة (){long longvar ;تسجيل متغير عددي ؛longvar = long_function ();إذا كان ( المتغير الطويل > 1 )intvar = 0 ;آخرintvar = int_function ();أعد متغيرًا صحيحًا ؛}

يُعدّ تعريف الدالة long_function()(في السطر 1) ضروريًا لأنها تُرجع قيمةً long، وليس قيمةً أخرى . يمكن استدعاء intالدالة (في السطر 11) حتى وإن لم يتم تعريفها، لأنها تُرجع قيمةً أخرى. كذلك، لا يلزم تعريف المتغير كنوع، لأن هذا هو النوع الافتراضي للكلمة المفتاحية.int_functionintintvarintregister

بما أن تعريفات الدوال لم تتضمن معلومات حول الوسائط، لم تُجرَ فحوصات الأنواع ، مع أن بعض المترجمات كانت تُصدر تحذيرًا إذا استخدمت استدعاءات مختلفة لدالة ما أعدادًا أو أنواعًا مختلفة من الوسائط. وقد طُوِّرت أدوات مثل أداة lint في نظام يونكس ، والتي كانت تتحقق (من بين أمور أخرى) من اتساق استخدام الدوال عبر ملفات المصدر المتعددة.

في السنوات التي تلت نشر كتاب K&R C، أُضيفت عدة ميزات إلى اللغة، بدعم من مُجمِّعات AT&T (وخاصةً PCC [ 26 ] ) وموردين آخرين. وشملت هذه الميزات ما يلي:

أدت شعبية اللغة، وعدم وجود اتفاق على واجهات المكتبة القياسية ، وعدم الامتثال لمواصفات K&R، إلى جهود التوحيد القياسي. [ 27 ]

ANSI C و ISO C

خلال أواخر السبعينيات والثمانينيات، تم تطبيق إصدارات من لغة C على مجموعة واسعة من أجهزة الكمبيوتر المركزية وأجهزة الكمبيوتر الصغيرة وأجهزة الكمبيوتر الدقيقة ، بما في ذلك جهاز IBM PC ، حيث زادت شعبيتها بشكل كبير.

في عام ١٩٨٣، شكّل المعهد الوطني الأمريكي للمعايير (ANSI) لجنةً، X3J11، لوضع مواصفات قياسية للغة C. استندت X3J11 في معيار C إلى تطبيق يونكس؛ إلا أن الجزء غير القابل للنقل من مكتبة يونكس C سُلّم إلى مجموعة العمل ١٠٠٣ التابعة لمعهد مهندسي الكهرباء والإلكترونيات (IEEE) ليصبح أساسًا لمعيار POSIX لعام ١٩٨٨. في عام ١٩٨٩، صُدّق على معيار C تحت مسمى ANSI X3.159-1989 "لغة البرمجة C". يُشار إلى هذه النسخة من اللغة غالبًا باسم ANSI C ، أو Standard C، أو أحيانًا C89 .

في عام 1990، اعتمدت المنظمة الدولية للتوحيد القياسي (ISO) معيار ANSI C (مع تغييرات في التنسيق) تحت مسمى ISO/IEC 9899:1990، والذي يُطلق عليه أحيانًا اسم C90 . لذا، يشير مصطلحا "C89" و"C90" إلى لغة البرمجة نفسها.

لم تعد الهيئة الوطنية الأمريكية للمعايير (ANSI)، مثلها مثل هيئات المعايير الوطنية الأخرى، تقوم بتطوير معيار C بشكل مستقل، بل تعتمد على معيار C الدولي، الذي تتولى صيانته مجموعة العمل ISO/IEC JTC1/SC22 /WG14. وعادةً ما يتم اعتماد تحديث المعيار الدولي على المستوى الوطني في غضون عام من نشره من قبل ISO.

كان أحد أهداف عملية توحيد لغة C هو إنتاج مجموعة شاملة من لغة K&R C، تتضمن العديد من الميزات غير الرسمية التي أُضيفت لاحقًا. كما أضافت لجنة المعايير عدة ميزات إضافية مثل نماذج الدوال (المستعارة من لغة C++)، voidوالمؤشرات، ودعم مجموعات الأحرف واللغات الدولية ، وتحسينات المعالج المسبق. وعلى الرغم من تعديل صيغة تعريفات المعاملات لتشمل النمط المستخدم في لغة C++، فقد استمر السماح باستخدام واجهة K&R، وذلك لضمان التوافق مع الشيفرة المصدرية الموجودة.

يدعم مُجمِّعات لغة C الحالية معيار C89، ويعتمد عليه معظم كود C الحديث. أي برنامج مكتوب بلغة C القياسية فقط، دون أي افتراضات تعتمد على العتاد، سيعمل بشكل صحيح على أي منصة مزودة بتنفيذ C متوافق، ضمن حدود مواردها. بدون هذه الاحتياطات، قد لا تُجمَّع البرامج إلا على منصة معينة أو باستخدام مُجمِّع محدد، وذلك بسبب استخدام مكتبات غير قياسية، مثل مكتبات واجهة المستخدم الرسومية ، أو بسبب الاعتماد على خصائص خاصة بالمُجمِّع أو المنصة، مثل الحجم الدقيق لأنواع البيانات وترتيب البايتات .

في الحالات التي يجب فيها أن يكون الكود قابلاً للترجمة بواسطة مترجمات متوافقة مع المعايير أو مترجمات K&R C، __STDC__يمكن استخدام الماكرو لتقسيم الكود إلى أقسام قياسية وأقسام K&R لمنع استخدام الميزات المتوفرة فقط في لغة C القياسية على مترجم K&R C.

بعد عملية توحيد المعايير التي قامت بها منظمة المعايير الوطنية الأمريكية (ANSI) والمنظمة الدولية للمعايير (ISO)، ظلّت مواصفات لغة C ثابتة نسبيًا لعدة سنوات. وفي عام 1995، نُشر التعديل المعياري الأول لمعيار C لعام 1990 (ISO/IEC 9899/AMD1:1995، والمعروف اختصارًا باسم C95)، لتصحيح بعض التفاصيل وإضافة دعم أوسع لمجموعات الأحرف الدولية. [ 28 ]

C99

تمت مراجعة معيار C بشكل إضافي في أواخر التسعينيات، مما أدى إلى نشر معيار ISO/IEC 9899:1999 في عام 1999، والذي يُشار إليه عادةً باسم " C99 ". وقد تم تعديله منذ ذلك الحين ثلاث مرات من خلال تصحيحات فنية. [ 29 ]

قدّمت لغة C99 العديد من الميزات الجديدة، بما في ذلك الدوال المضمنة ، وأنواع بيانات جديدة (بما في ذلك long long intنوع complexلتمثيل الأعداد المركبةوالمصفوفات ذات الطول المتغير وعناصر المصفوفة المرنة ، ودعمًا مُحسّنًا للفاصلة العائمة IEEE 754 ، ودعمًا لوحدات الماكرو المتغيرة الوسائط ، ودعمًا للتعليقات المكونة من سطر واحد والتي تبدأ بـ `<br>` //، كما هو الحال في لغتي BCPL وC++. وقد تم بالفعل تطبيق العديد من هذه الميزات كإضافات في العديد من مُجمّعات لغة C.

يُعدّ معيار C99 متوافقًا إلى حد كبير مع معيار C90، ولكنه أكثر صرامة في بعض الجوانب؛ فعلى وجه الخصوص، لم يعد intيُفترض ضمنيًا أي تعريف يفتقر إلى مُحدِّد نوع. ويتم تعريف ماكرو قياسي __STDC_VERSION__بقيمة 199901Lللإشارة إلى توافر دعم C99. يدعم كلٌّ من GCC و Solaris Studio ومترجمات لغة C الأخرى الآن العديد من ميزات C99 الجديدة أو جميعها. مع ذلك، يُطبِّق مُترجم لغة C في Microsoft Visual C++ معيار C89 وأجزاء C99 المطلوبة للتوافق مع C++11 . [ 30 ]

بالإضافة إلى ذلك، يتطلب معيار C99 دعم المعرفات باستخدام Unicode في شكل أحرف مهربة (مثل \u0040أو \U0001f431) ويقترح دعم أسماء Unicode الخام.

C11

بدأ العمل في عام 2007 على مراجعة أخرى لمعيار C، والذي أطلق عليه بشكل غير رسمي اسم "C1X" حتى نشره الرسمي ISO/IEC 9899:2011 في 8 ديسمبر 2011. وقد اعتمدت لجنة معايير C إرشادات للحد من اعتماد الميزات الجديدة التي لم يتم اختبارها من خلال التطبيقات الحالية.

يُضيف معيار C11 العديد من الميزات الجديدة إلى لغة C ومكتبتها، بما في ذلك وحدات الماكرو العامة للأنواع، والهياكل المجهولة، ودعم مُحسّن لليونيكود، والعمليات الذرية، والمعالجة المتعددة، والدوال التي يتم التحقق من حدودها. كما يجعل بعض أجزاء مكتبة C99 الحالية اختيارية، ويُحسّن التوافق مع لغة C++. __STDC_VERSION__يُعرّف الماكرو القياسي 201112Lللإشارة إلى توفّر دعم C11.

C17

C17 هو اسم غير رسمي لمعيار ISO/IEC 9899:2018، وهو معيار للغة البرمجة C نُشر في يونيو 2018. لا يُضيف هذا المعيار أي ميزات لغوية جديدة، بل يقتصر على تصحيحات تقنية وتوضيحات لعيوب في C11. __STDC_VERSION__يُعرّف الماكرو القياسي 201710Lللإشارة إلى توفر دعم C17.

C23

C23 هو اسم غير رسمي للمراجعة الرئيسية الحالية لمعيار لغة C. عُرفت باسم "C2X" خلال معظم مراحل تطويرها. وهي مبنية على الإصدارات السابقة، وتُقدم ميزات مثل كلمات مفتاحية جديدة، ومعنى إضافي لـ autoلتوفير استنتاج النوع عند تعريف المتغيرات، وأنواع جديدة بما في ذلك nullptr_tو _BitInt(N)، وتوسعات للمكتبة القياسية. [ 31 ]

تم نشر C23 في أكتوبر 2024 تحت اسم ISO/IEC 9899:2024. [ 32 ]__STDC_VERSION__ تم تعريف الماكرو القياسي 202311Lللإشارة إلى أن دعم C23 متاح.

C2Y

C2Y هو اسم غير رسمي للمراجعة الرئيسية التالية لمعيار لغة C، بعد C23 (C2X)، والتي من المأمول إصدارها في وقت لاحق من العقد الحالي، ومن هنا جاء الرقم "2" في "C2Y". وقد تم إصدار مسودة عمل مبكرة من C2Y في فبراير 2024 تحت اسم N3220 من قبل فريق العمل ISO/IEC JTC1/SC22 /WG14. [ 33 ]

لغة سي المضمنة

تاريخياً، تتطلب برمجة C المضمنة امتدادات غير قياسية للغة C لدعم ميزات غريبة مثل الحساب ذي النقطة الثابتة ، وبنوك الذاكرة المتعددة المتميزة ، وعمليات الإدخال/الإخراج الأساسية.

في عام 2008، نشرت لجنة معايير لغة C تقريرًا فنيًا يوسع نطاق لغة C [ 34 ] لمعالجة هذه المشكلات من خلال توفير معيار مشترك تلتزم به جميع التطبيقات. ويتضمن هذا التقرير عددًا من الميزات غير المتوفرة في لغة C العادية، مثل العمليات الحسابية ذات الفاصلة الثابتة، ومساحات العناوين المسماة، وعنونة أجهزة الإدخال/الإخراج الأساسية.

تعريف

تتمتع لغة C بقواعد نحوية رسمية محددة في معيار C. [ 35 ] لا تُعتبر نهايات الأسطر ذات أهمية في لغة C عمومًا؛ ومع ذلك، فإن حدود الأسطر لها أهمية خلال مرحلة المعالجة المسبقة. يمكن أن تظهر التعليقات إما بين المحددات /*و */، أو (منذ C99) بعد //حتى نهاية السطر. لا تتداخل التعليقات المحددة بـ /*و */، ولا تُفسر هذه التسلسلات من الأحرف على أنها محددات تعليقات إذا ظهرت داخل سلاسل نصية أو أحرف حرفية. [ 36 ]

تحتوي ملفات مصدر لغة C على التصريحات وتعريفات الدوال. بدورها، تحتوي تعريفات الدوال على التصريحات والعبارات . تُعرّف التصريحات أنواعًا جديدة باستخدام كلمات مفتاحية مثل struct`type` unionو`value` و` enumvar`، أو تُسند أنواعًا إلى متغيرات جديدة، وربما تحجز مساحة تخزين لها، وذلك عادةً بكتابة النوع متبوعًا باسم المتغير. تُحدد كلمات مفتاحية مثل `type` charو` intvalue` أنواعًا مضمنة. تُحاط أجزاء من التعليمات البرمجية بأقواس معقوفة (` {{ }...

تستخدم لغة C، كلغة إجرائية، عبارات لتحديد الإجراءات. العبارة الأكثر شيوعًا هي عبارة التعبير ، التي تتكون من تعبير يُراد تقييمه، متبوعًا بفاصلة منقوطة؛ وكنتيجة جانبية للتقييم، يمكن استدعاء الدوال وتعيين قيم جديدة للمتغيرات . لتعديل التنفيذ التسلسلي العادي للعبارات، توفر C عدة عبارات للتحكم في التدفق، يتم تحديدها بواسطة كلمات محجوزة. يدعم C البرمجة المهيكلة من خلال التنفيذ الشرطي ، والتنفيذ التكراري (الحلقات). تحتوي عبارة `break` على تعبيرات منفصلة للتهيئة والاختبار وإعادة التهيئة، ويمكن حذف أي منها أو جميعها. يمكن استخدام `break` و`continue` داخل الحلقة. تُستخدم `break` للخروج من عبارة الحلقة الداخلية، وتُستخدم `continue` للانتقال إلى إعادة تهيئتها. توجد أيضًا عبارة غير مهيكلة، تتفرع مباشرةً إلى التسمية المُحددة داخل الدالة. تحدد `continue` قيمة `a` المراد تنفيذها بناءً على قيمة تعبير عددي صحيح. على عكس العديد من اللغات الأخرى، ينتقل التحكم في التدفق إلى العبارة التالية ما لم يتم إنهاؤه بواسطة `continue` .ifelsedowhilewhileforforbreakcontinuegotoswitchcasecasebreak

يمكن للتعبيرات استخدام مجموعة متنوعة من المعاملات المدمجة، وقد تحتوي على استدعاءات دوال. ترتيب تقييم وسائط الدوال ومعاملات معظم المعاملات غير محدد، بل قد تتداخل عمليات التقييم. مع ذلك، ستحدث جميع التأثيرات الجانبية (بما في ذلك تخزين البيانات في المتغيرات) قبل " نقطة التسلسل " التالية؛ وتشمل نقاط التسلسل نهاية كل عبارة تعبيرية، ونقطة الدخول إلى كل استدعاء دالة ونقطة العودة منه. كما تحدث نقاط التسلسل أثناء تقييم التعبيرات التي تحتوي على معاملات معينة (مثل الفاصلة المنقوطة &&، والفاصلة ||، ومعامل الفاصلة ). يتيح هذا للمترجم تحسينًا كبيرًا لرمز الكائن، ولكنه يتطلب من مبرمجي لغة C توخي المزيد من الحذر للحصول على نتائج موثوقة مقارنةً بلغات البرمجة الأخرى.?:

يقول كيرنيغان وريتشي في مقدمة كتاب "لغة البرمجة سي" : "لغة سي، كأي لغة أخرى، بها عيوبها. فبعض المعاملات لها أسبقية خاطئة، وبعض أجزاء بناء الجملة يمكن تحسينها." [ 37 ] لم يحاول معيار لغة سي تصحيح العديد من هذه العيوب، نظرًا لتأثير هذه التغييرات على البرامج الموجودة بالفعل.

مجموعة الأحرف

تتضمن مجموعة الأحرف الأساسية لمصدر لغة C الأحرف التالية: [ 38 ]

يشير حرف السطر الجديد إلى نهاية سطر النص؛ ولا يشترط أن يتوافق مع حرف واحد فعلي، على الرغم من أن لغة C تتعامل معه على هذا النحو من أجل التسهيل.

يفرض معيار POSIX مجموعة أحرف قابلة للنقل ، تُضيف بعض الأحرف (وخاصةً "@") إلى مجموعة أحرف لغة C الأساسية. ولا يُحدد أيٌّ من المعيارين ترميزًا مُعينًا للقيم، إذ يتوافق كلٌّ من ASCII و EBCDIC مع هذه المعايير، لاحتوائهما على الأقل على تلك الأحرف الأساسية، على الرغم من استخدامهما قيمًا مُرمَّزة مختلفة لتلك الأحرف.

يمكن استخدام أحرف إضافية مُشفّرة متعددة البايتات في النصوص الحرفية ، لكنها ليست قابلة للنقل بشكل كامل . منذ معيار C99، يمكن تضمين أحرف Unicode متعددة الجنسيات بشكل قابل للنقل داخل نص مصدر C باستخدام \uXXXXالتشفير \UXXXXXXXX(حيث Xيشير إلى حرف سداسي عشري).

تحتوي مجموعة أحرف التنفيذ الأساسية للغة C على نفس الأحرف، بالإضافة إلى تمثيلات للحرف الفارغ ، والتنبيه ، ومسح للخلف ، وإرجاع السطر . [ 38 ]

ازداد دعم وقت التشغيل لمجموعات الأحرف الموسعة مع كل مراجعة لمعيار لغة C.

الكلمات المحجوزة

تحتوي جميع إصدارات لغة C على كلمات محجوزة حساسة لحالة الأحرف . وباعتبارها كلمات محجوزة، فلا يمكن استخدامها كأسماء للمتغيرات.

يحتوي C89 على 32 كلمة محجوزة:

أضافت C99 خمس كلمات محجوزة أخرى: (‡ يشير إلى اسم بديل لتهجئة كلمة مفتاحية في C23)

أضافت C11 سبع كلمات محجوزة أخرى: [ 39 ] (‡ يشير إلى اسم بديل لتهجئة كلمة رئيسية من C23)

  • _Alignas
  • _Alignof
  • _Atomic
  • _Generic
  • _Noreturn
  • _Static_assert
  • _Thread_local

C23 محجوزة خمس عشرة كلمة أخرى:

  • alignas
  • alignof
  • bool
  • constexpr
  • false
  • nullptr
  • static_assert
  • thread_local
  • true
  • typeof
  • typeof_unqual
  • _BitInt
  • _Decimal32
  • _Decimal64
  • _Decimal128

تبدأ معظم الكلمات المحجوزة حديثًا بشرطة سفلية متبوعة بحرف كبير، لأن المعرفات بهذا الشكل كانت محجوزة سابقًا في معيار لغة C لاستخدامها في التطبيقات فقط. وبما أن شفرة المصدر البرمجية الحالية لا ينبغي أن تستخدم هذه المعرفات، فلن تتأثر عندما بدأت تطبيقات لغة C بدعم هذه الإضافات للغة البرمجة. تُعرّف بعض رؤوس الملفات القياسية مرادفات أكثر ملاءمة للمعرفات التي تحتوي على شرطة سفلية. أُضيفت بعض هذه الكلمات ككلمات مفتاحية مع تهجئتها التقليدية في C23، وتم حذف وحدات الماكرو المقابلة لها.

قبل إصدار C89، entryكانت الكلمة المفتاحية محجوزة. في الطبعة الثانية من كتابهما "لغة البرمجة C" ، الذي يصف ما أصبح يُعرف باسم C89، كتب كيرنيغان وريتشي: "الكلمة المفتاحية ... entry، التي كانت محجوزة سابقًا ولكن لم تُستخدم قط، لم تعد محجوزة." و" entryتم سحب الكلمة المفتاحية التي لم تُستخدم." [ 40 ]

المشغلون

تدعم لغة C مجموعة غنية من المعاملات ، وهي رموز تُستخدم داخل التعبير لتحديد العمليات التي ستُجرى أثناء تقييم ذلك التعبير. تحتوي لغة C على معاملات لـ:

تستخدم لغة C عامل التعيين =(المستخدم في الرياضيات للتعبير عن المساواة) للإشارة إلى عملية الإسناد، على غرار لغتي Fortran و PL/I ، ولكن على عكس لغة ALGOL ومشتقاتها، تستخدم C عامل التعيين ==لاختبار المساواة. قد يؤدي التشابه بين عاملي التعيين والمساواة إلى استخدام أحدهما بدلًا من الآخر عن طريق الخطأ، وفي كثير من الحالات لا ينتج عن هذا الخطأ رسالة خطأ (مع أن بعض المترجمات تُصدر تحذيرات). على سبيل المثال، if (a == b + 1)قد يُكتب التعبير الشرطي خطأً على النحو التالي if (a = b + 1): ، والذي سيتم تقييمه على أنه إلا إذا كانت trueقيمة بعد عملية الإسناد. [ 41 ]a0

لا يكون ترتيب أسبقية المعاملات في لغة C بديهيًا دائمًا. على سبيل المثال، يرتبط المعامل ==بشكل أوثق (يُنفذ قبل) المعاملين &(AND و |OR) في تعابير مثل x & 1 == 0، والتي يجب كتابتها كما (x & 1) == 0لو كان هذا هو قصد المبرمج. [ 42 ]

أنواع البيانات

نظام الأنواع في لغة C ثابت وضعيف التحديد ، مما يجعله مشابهًا لنظام الأنواع في لغات مشتقة من ALGOL مثل باسكال . [ 43 ] تتضمن اللغة أنواعًا مدمجة للأعداد الصحيحة بمختلف أحجامها، سواءً كانت مُوقّعة أو غير مُوقّعة، بالإضافة إلى الأعداد العشرية ، وأنواع التعداد enum. يُستخدم نوع Integer charغالبًا للأحرف أحادية البايت. أضافت C99 نوع البيانات المنطقية (Boolean ) . كما توجد أنواع مشتقة تشمل المصفوفات ، والمؤشرات ، والسجلات ، structوالاتحادات .union

تُستخدم لغة C غالبًا في برمجة الأنظمة منخفضة المستوى حيث قد يكون من الضروري تجاوز نظام الأنواع. يحاول المترجم ضمان صحة أنواع معظم التعبيرات، ولكن يمكن للمبرمج تجاوز عمليات التحقق بطرق مختلفة، إما باستخدام تحويل النوع لتحويل قيمة من نوع إلى آخر بشكل صريح، أو باستخدام المؤشرات أو الاتحادات لإعادة تفسير البتات الأساسية لكائن البيانات بطريقة أخرى.

يجد البعض أن صيغة تعريف المتغيرات في لغة C غير بديهية، لا سيما بالنسبة لمؤشرات الدوال . (كانت فكرة ريتشي هي تعريف المعرفات في سياقات تشبه استخدامها: " التعريف يعكس الاستخدام "). [ 44 ]

تتيح عمليات التحويل الحسابي المعتادة في لغة C إنشاء شيفرة فعّالة، ولكنها قد تُنتج أحيانًا نتائج غير متوقعة. على سبيل المثال، تتطلب مقارنة عددين صحيحين، أحدهما مُوقّع والآخر غير مُوقّع، متساويين في العرض، تحويل القيمة المُوقّعة إلى قيمة غير مُوقّعة. وهذا قد يُنتج نتائج غير متوقعة إذا كانت القيمة المُوقّعة سالبة.

نصائح

تدعم لغة C استخدام المؤشرات ، وهي نوع من المراجع يُسجل عنوان أو موقع كائن أو دالة في الذاكرة. يمكن فك مرجعية المؤشرات للوصول إلى البيانات المخزنة في العنوان المُشار إليه، أو لاستدعاء دالة مُشار إليها. يمكن التعامل مع المؤشرات باستخدام عمليات الإسناد أو العمليات الحسابية الخاصة بالمؤشرات . عادةً ما يكون تمثيل قيمة المؤشر في وقت التشغيل عبارة عن عنوان ذاكرة خام (ربما مُضافًا إليه حقل إزاحة داخل الكلمة)، ولكن نظرًا لأن نوع المؤشر يتضمن نوع الكائن المُشار إليه، يمكن التحقق من نوع التعبيرات التي تتضمن مؤشرات في وقت الترجمة. يتم تعديل حجم العمليات الحسابية الخاصة بالمؤشرات تلقائيًا وفقًا لحجم نوع البيانات المُشار إليها.

تُستخدم المؤشرات في لغة C لأغراضٍ عديدة. فغالبًا ما تُعالج السلاسل النصية باستخدام المؤشرات في مصفوفات من الأحرف. كما يُستخدم تخصيص الذاكرة الديناميكيmalloc باستخدام المؤشرات؛ وعادةً ما تُحوّل نتيجة عملية ما إلى نوع البيانات المراد تخزينها. وتُنفّذ العديد من أنواع البيانات، مثل الأشجارstruct ، عادةً ككائنات مُخصصة ديناميكيًا مرتبطة ببعضها باستخدام المؤشرات. وكثيرًا ما تُستخدم المؤشرات إلى مؤشرات أخرى في المصفوفات متعددة الأبعاد ومصفوفات structالكائنات. وتُعدّ المؤشرات إلى الدوال ( مؤشرات الدوال ) مفيدةً لتمرير الدوال كوسائط إلى دوال من الرتبة العليا (مثل qsort أو bsearch )، أو في جداول التوزيع ، أو كدوال رد نداء لمعالجات الأحداث . [ 18 ]

يشير مؤشر فارغ صراحةً إلى موقع غير صالح. يُعدّ فكّ مرجعية مؤشر فارغ غير مُعرّف، وغالبًا ما يؤدي إلى خطأ تجزئة الذاكرة . تُفيد قيم المؤشر الفارغ في الإشارة إلى حالات خاصة، مثل عدم وجود مؤشر "التالي" في العقدة الأخيرة من قائمة مرتبطة ، أو كمؤشر خطأ من الدوال التي تُعيد مؤشرات. في سياقات مناسبة في شفرة المصدر، مثل إسناد قيمة إلى متغير مؤشر، يمكن كتابة ثابت المؤشر الفارغ0 على النحو التالي: `null` ، مع أو بدون تحويل صريح إلى نوع مؤشر، كما هو NULLمُعرّف في العديد من ملفات الرأس القياسية، أو منذ معيار C23 باستخدام الثابت `null` nullptr. في السياقات الشرطية، تُقيّم قيم المؤشر الفارغ إلى `null` false، بينما تُقيّم جميع قيم المؤشرات الأخرى إلى `null` true.

تشير المؤشرات الفارغة (void void *) إلى كائنات من نوع غير محدد، وبالتالي يمكن استخدامها كمؤشرات بيانات "عامة". ولأن حجم ونوع الكائن المشار إليه غير معروفين، فلا يمكن فك مرجعية المؤشرات الفارغة، كما لا يُسمح بإجراء عمليات حسابية عليها، على الرغم من أنه يمكن تحويلها بسهولة (وفي كثير من السياقات يتم ذلك ضمنيًا) من وإلى أي نوع آخر من مؤشرات الكائنات. [ 18 ]

يُعدّ الاستخدام غير الدقيق للمؤشرات أمرًا خطيرًا. نظرًا لأنها عادةً ما تكون غير مُدققة، يُمكن جعل متغير المؤشر يُشير إلى أي موقع عشوائي، مما قد يُسبب آثارًا غير مرغوب فيها. على الرغم من أن المؤشرات المُستخدمة بشكل صحيح تُشير إلى مواقع آمنة، إلا أنه يُمكن جعلها تُشير إلى مواقع غير آمنة باستخدام عمليات حسابية غير صالحة للمؤشرات ؛ فقد تستمر الكائنات التي تُشير إليها في الاستخدام بعد تحرير الذاكرة ( مؤشرات معلقة )؛ أو قد تُستخدم دون تهيئتها ( مؤشرات جامحة )؛ أو قد يتم إسناد قيمة غير آمنة إليها مباشرةً باستخدام التحويل أو الاتحاد أو من خلال مؤشر تالف آخر. بشكل عام، تسمح لغة C بالتلاعب بأنواع المؤشرات والتحويل بينها، على الرغم من أن المُترجمات تُوفر عادةً خيارات لمستويات مُختلفة من التدقيق. تُعالج بعض لغات البرمجة الأخرى هذه المشاكل باستخدام أنواع مرجعية أكثر تقييدًا .

المصفوفات

تتميز أنواع المصفوفات في لغة C تقليديًا بحجم ثابت ومحدد مسبقًا أثناء عملية الترجمة. كما يسمح معيار C99 الأحدث بنوع من المصفوفات ذات الطول المتغير. مع ذلك، من الممكن أيضًا تخصيص كتلة من الذاكرة (بأي حجم) أثناء التشغيل، باستخدام mallocدالة المكتبة القياسية، والتعامل معها كمصفوفة.

بما أن الوصول إلى المصفوفات يتم دائمًا (فعليًا) عبر المؤشرات، فإن عمليات الوصول إلى المصفوفات لا تخضع عادةً للتحقق من حجم المصفوفة الأساسية، على الرغم من أن بعض المترجمات قد توفر التحقق من الحدود كخيار. [ 45 ] [ 46 ] وبالتالي، فإن انتهاكات حدود المصفوفة واردة وقد تؤدي إلى عواقب وخيمة، بما في ذلك الوصول غير المصرح به إلى الذاكرة، وتلف البيانات، وتجاوز سعة المخزن المؤقت ، والاستثناءات أثناء التشغيل.

لا توفر لغة C آلية خاصة لتعريف المصفوفات متعددة الأبعاد ، بل تعتمد على الاستدعاء الذاتي داخل نظام الأنواع لتعريف مصفوفات المصفوفات، وهو ما يحقق نفس الغرض. يمكن اعتبار قيم فهرسة "المصفوفة متعددة الأبعاد" الناتجة متزايدة بترتيب الصفوف . تُستخدم المصفوفات متعددة الأبعاد بشكل شائع في الخوارزميات العددية (وخاصةً في الجبر الخطي التطبيقي ) لتخزين المصفوفات. بنية مصفوفة C مناسبة تمامًا لهذه المهمة. مع ذلك، في الإصدارات القديمة من C، كان يجب أن تكون حدود المصفوفة قيمًا ثابتة معروفة أو يتم تمريرها صراحةً إلى أي دالة فرعية تتطلبها، ولا يمكن الوصول إلى مصفوفات المصفوفات ذات الأحجام الديناميكية باستخدام الفهرسة المزدوجة. (كان الحل البديل لهذه المشكلة هو تخصيص المصفوفة بمتجه صف إضافي من المؤشرات إلى الأعمدة). قدمت C99 "المصفوفات ذات الطول المتغير" التي تعالج هذه المشكلة.

يوضح المثال التالي باستخدام لغة C الحديثة (C99 أو أحدث) تخصيص مصفوفة ثنائية الأبعاد على الكومة واستخدام فهرسة المصفوفات متعددة الأبعاد للوصول (والتي يمكنها استخدام فحص الحدود في العديد من مترجمات لغة C):

دالة عددية ( عدد صحيح n ، عدد صحيح m ) {float ( * p )[ n ][ m ] = malloc ( sizeof * p );إذا كان ( p == NULL ) {أعد -1 ؛}for ( int i = 0 ; i < n ; i ++ ) {for ( int j = 0 ; j < m ; j ++ ) {( * p )[ i ][ j ] = i + j ;}}print_array ( n , m , p );حر ( ص أعد 1 ؛}

وهنا تطبيق مشابه باستخدام ميزة Auto VLA في C99: [ f ]

دالة عددية ( عدد صحيح n ، عدد صحيح m ) {// تنبيه: يجب إجراء عمليات التحقق للتأكد من أن n * m * sizeof(float) لا يتجاوز حدود VLAs التلقائية ويقع ضمن الحجم المتاح للمكدس.float p [ n ][ m ]; // يتم تخزين المصفوفة ذات الطول الموجي الكبير التلقائي في المكدس، ويتم تحديد حجمها عند استدعاء الدالةfor ( int i = 0 ; i < n ; i ++ ) {for ( int j = 0 ; j < m ; j ++ ) {p [ i ][ j ] = i + j ;}}print_array ( n , m , p );// لا حاجة لتحرير الذاكرة (p) لأنها ستختفي عند انتهاء الدالة، مع بقية إطار المكدس.أعد 1 ؛}

قابلية التبادل بين المصفوفة والمؤشر

يُعدّ ترميز الفهرس السفلي x[i](حيث xيشير إلى مؤشر) اختصارًا برمجيًا لـ *(x+i). [ 47 ] بالاستفادة من معرفة المُصرّف بنوع المؤشر، فإنّ العنوان الذي x + iيشير إليه ليس هو العنوان الأساسي (الذي يشير إليه x) مُضافًا إليه iبايتات، بل هو العنوان الأساسي مُضافًا إليه بايتات iمضروبًا في حجم العنصر الذي xيشير إليه . وبالتالي، x[i]يُشير إلى i+1العنصر رقم في المصفوفة.

علاوة على ذلك، في معظم سياقات التعبير (باستثناء ملحوظ عند استخدامه كمعامل sizeof)، يُحوّل التعبير من نوع مصفوفة تلقائيًا إلى مؤشر إلى العنصر الأول في المصفوفة. هذا يعني أن المصفوفة لا تُنسخ بالكامل عند استدعائها كوسيط لدالة، بل يُمرر فقط عنوان العنصر الأول فيها. لذلك، على الرغم من أن استدعاءات الدوال في لغة C تستخدم دلالات التمرير بالقيمة ، فإن المصفوفات تُمرر فعليًا بالمرجع .

يمكن تحديد الحجم الإجمالي للمصفوفة xبتطبيق sizeofعامل التشغيل على تعبير من نوع مصفوفة. ويمكن تحديد حجم أي عنصر بتطبيق عامل التشغيل sizeofعلى أي عنصر مُشار إليه في المصفوفة A، كما في المثال . وبالتالي، يمكن تحديد n = sizeof A[0]عدد العناصر في مصفوفة مُعلنة على النحو التالي : . تجدر الإشارة إلى أنه في حال توفر مؤشر إلى العنصر الأول فقط، كما هو الحال غالبًا في لغة C بسبب التحويل التلقائي المذكور أعلاه، فإن معلومات النوع الكامل للمصفوفة وطولها تُفقد.Asizeof A / sizeof A[0]

إدارة الذاكرة

من أهم وظائف لغة البرمجة توفير أدوات لإدارة الذاكرة والكائنات المخزنة فيها. توفر لغة C ثلاث طرق رئيسية لتخصيص الذاكرة للكائنات: [ 18 ]

  • تخصيص الذاكرة الثابتة : يتم توفير مساحة للكائن في الملف الثنائي في وقت الترجمة؛ تتمتع هذه الكائنات بنطاق (أو عمر) طالما أن الملف الثنائي الذي يحتوي عليها محمل في الذاكرة.
  • تخصيص الذاكرة التلقائي : يمكن تخزين الكائنات المؤقتة على المكدس ، ويتم تحرير هذه المساحة تلقائيًا وإعادة استخدامها بعد الخروج من الكتلة التي تم الإعلان عنها فيها.
  • تخصيص الذاكرة الديناميكي : يمكن طلب كتل من الذاكرة ذات حجم عشوائي في وقت التشغيل باستخدام وظائف المكتبة مثل mallocمن منطقة في الذاكرة تسمى الكومة ؛ وتستمر هذه الكتل حتى يتم تحريرها لاحقًا لإعادة استخدامها عن طريق استدعاء وظيفة المكتبة reallocأو free.

تُناسب هذه الأساليب الثلاثة حالاتٍ مختلفة، ولكلٍّ منها مزايا وعيوب. فعلى سبيل المثال، يتميز تخصيص الذاكرة الثابت بانخفاض تكلفة التخصيص، بينما قد ينطوي التخصيص التلقائي على تكلفة إضافية طفيفة، أما تخصيص الذاكرة الديناميكي فقد ينطوي على تكلفة إضافية كبيرة في كلٍّ من التخصيص وإلغاء التخصيص. وتُعدّ الطبيعة الدائمة للكائنات الثابتة مفيدةً للحفاظ على معلومات الحالة بين استدعاءات الدوال، بينما يتميز التخصيص التلقائي بسهولة الاستخدام، إلا أن مساحة المكدس عادةً ما تكون محدودةً وعابرةً أكثر من مساحة الذاكرة الثابتة أو مساحة الكومة، أما تخصيص الذاكرة الديناميكي فيتيح تخصيصًا ملائمًا للكائنات التي لا يُعرف حجمها إلا في وقت التشغيل. وتستفيد معظم برامج لغة C بشكلٍ كبير من هذه الأساليب الثلاثة.

حيثما أمكن، يُعدّ التخصيص التلقائي أو الثابت أبسط الطرق عادةً، لأنّ المُصرّف يُدير مساحة التخزين، مُعفياً المُبرمج من مهمة التخصيص والتحرير اليدويّين، والتي قد تكون عُرضةً للأخطاء. مع ذلك، يُمكن أن يتغيّر حجم العديد من هياكل البيانات أثناء التشغيل، وبما أنّ التخصيصات الثابتة (والتخصيصات التلقائية قبل معيار C99) يجب أن يكون لها حجم ثابت أثناء الترجمة، فهناك العديد من الحالات التي يكون فيها التخصيص الديناميكي ضرورياً. [ 18 ] قبل معيار C99، كانت المصفوفات ذات الأحجام المتغيّرة مثالاً شائعاً على ذلك. (انظر مقالة تخصيص الذاكرة الديناميكي في لغة C للاطلاع على مثال للمصفوفات المُخصصة ديناميكياً). على عكس التخصيص التلقائي، الذي قد يفشل أثناء التشغيل مع عواقب غير مُتحكّم بها، تُعيد دوال التخصيص الديناميكي إشارة (على شكل قيمة مؤشر فارغ) عندما لا يُمكن تخصيص مساحة التخزين المطلوبة. (عادةً ما يكتشف الرابط أو المُحمّل التخصيص الثابت الكبير جدًا ، قبل أن يبدأ البرنامج بالتنفيذ).

ما لم يُنص على خلاف ذلك، تحتوي الكائنات الثابتة على قيم مؤشر صفرية أو فارغة عند بدء تشغيل البرنامج. أما الكائنات المُخصصة تلقائيًا وديناميكيًا، فلا تُهيأ إلا إذا حُددت قيمة ابتدائية لها صراحةً؛ وإلا فإنها تحتوي في البداية على قيم غير محددة (عادةً، أي نمط بت موجود في الذاكرة ، والذي قد لا يُمثل قيمة صالحة لهذا النوع). إذا حاول البرنامج الوصول إلى قيمة غير مُهيأة، فستكون النتائج غير مُحددة. تحاول العديد من المُترجمات الحديثة اكتشاف هذه المشكلة والتحذير منها، ولكن قد تحدث نتائج إيجابية خاطئة وسلبية خاطئة .

يجب مزامنة تخصيص ذاكرة الكومة مع استخدامها الفعلي في أي برنامج لضمان إعادة استخدامها قدر الإمكان. على سبيل المثال، إذا خرج المؤشر الوحيد لتخصيص ذاكرة الكومة عن نطاق التعريف أو تم استبدال قيمته قبل تحريرها صراحةً، فلن يكون بالإمكان استعادة تلك الذاكرة لإعادة استخدامها لاحقًا، وبالتالي تُفقد فعليًا من البرنامج، وهي ظاهرة تُعرف بتسرب الذاكرة . في المقابل، من الممكن تحرير الذاكرة ثم الرجوع إليها لاحقًا، مما يؤدي إلى نتائج غير متوقعة. عادةً ما تظهر أعراض الفشل في جزء من البرنامج لا علاقة له بالكود الذي تسبب في الخطأ، مما يصعب تشخيصه. يتم التخفيف من هذه المشكلات في اللغات التي تدعم جمع البيانات المهملة تلقائيًا .

المكتبات

تستخدم لغة البرمجة C المكتبات كطريقة أساسية للتوسيع. في لغة C، المكتبة عبارة عن مجموعة من الدوال الموجودة في ملف "أرشيف" واحد. تحتوي كل مكتبة عادةً على ملف رأس ، يتضمن نماذج الدوال التي يمكن للبرنامج استخدامها، بالإضافة إلى تعريفات لأنواع البيانات الخاصة ورموز الماكرو المستخدمة مع هذه الدوال. لكي يستخدم البرنامج مكتبةً ما، يجب عليه تضمين ملف رأس المكتبة، ويجب ربط المكتبة بالبرنامج، وهو ما يتطلب في كثير من الحالات استخدام علامات المُصرّف (مثلًا -lm، اختصارًا لـ "ربط مكتبة الرياضيات"). [ 18 ]

المكتبة الأكثر شيوعًا في لغة C هي مكتبة C القياسية ، المحددة في معايير ISO و ANSI للغة C ، وتأتي مع كل تطبيق للغة C (قد توفر التطبيقات التي تستهدف بيئات محدودة، مثل الأنظمة المدمجة، مجموعة فرعية فقط من المكتبة القياسية). تدعم هذه المكتبة إدخال وإخراج البيانات المتدفقة، وتخصيص الذاكرة، والعمليات الحسابية، والسلاسل النصية، وقيم الوقت. stdio.hتحدد عدة ملفات رأس قياسية منفصلة (على سبيل المثال، ) واجهات هذه الميزات وغيرها من ميزات المكتبة القياسية.

هناك مجموعة أخرى شائعة من وظائف مكتبة لغة C، وهي تلك التي تستخدمها التطبيقات المصممة خصيصًا لأنظمة يونكس والأنظمة الشبيهة بيونكس ، وخاصة الوظائف التي توفر واجهة لنواة النظام . وتُفصّل هذه الوظائف في معايير مختلفة مثل POSIX ومواصفات يونكس الموحدة .

نظراً لأن العديد من البرامج كُتبت بلغة C، فهناك مجموعة واسعة من المكتبات الأخرى المتاحة. غالباً ما تُكتب المكتبات بلغة C لأن مُترجمات C تُنتج شيفرة كائنية فعّالة ؛ ثم يقوم المبرمجون بإنشاء واجهات للمكتبة بحيث يمكن استخدام الإجراءات من لغات برمجة عالية المستوى مثل Java و Perl و Python . [ 18 ]

معالجة الملفات والتدفقات

لا تُعدّ عمليات إدخال وإخراج الملفات جزءًا من لغة C نفسها، بل تتم معالجتها بواسطة مكتبات (مثل مكتبة C القياسية) وملفات الرأس المرتبطة بها stdio.h. تُنفَّذ معالجة الملفات عمومًا من خلال عمليات إدخال وإخراج عالية المستوى تعمل عبر التدفقات . يُعرَّف التدفق، من هذا المنظور، بأنه تدفق بيانات مستقل عن الأجهزة، بينما يُعدّ الملف جهازًا ملموسًا. تتم عمليات الإدخال والإخراج عالية المستوى من خلال ربط تدفق بملف. في مكتبة C القياسية، يُستخدم مخزن مؤقت (مساحة ذاكرة أو قائمة انتظار) لتخزين البيانات مؤقتًا قبل إرسالها إلى الوجهة النهائية. يُقلل هذا من وقت الانتظار للأجهزة الأبطأ، مثل القرص الصلب أو محرك الأقراص ذي الحالة الصلبة . لا تُعدّ وظائف الإدخال والإخراج منخفضة المستوى جزءًا من مكتبة C القياسية ، ولكنها تُعدّ عمومًا جزءًا من برمجة "الأجهزة الأساسية" (البرمجة المستقلة عن أي نظام تشغيل، مثل معظم برامج الأنظمة المدمجة ). باستثناءات قليلة، تتضمن التطبيقات عمليات إدخال وإخراج منخفضة المستوى.

أدوات اللغة

تم تطوير عدد من الأدوات لمساعدة مبرمجي لغة C في العثور على العبارات ذات السلوك غير المحدد أو التعبيرات الخاطئة المحتملة وإصلاحها، بدقة أكبر من تلك التي يوفرها المترجم.

تتوفر أدوات آلية لفحص وتدقيق شفرة المصدر، مثل Lint . ومن الممارسات الشائعة استخدام Lint للكشف عن الشفرة المشكوك فيها عند كتابة البرنامج لأول مرة. بعد اجتياز البرنامج فحص Lint، يتم تجميعه باستخدام مُجمِّع لغة C. كما يمكن للعديد من المُجمِّعات أن تُصدر تحذيرات اختيارية بشأن البنى الصحيحة نحويًا والتي يُحتمل أن تكون أخطاءً. MISRA C هي مجموعة إرشادات خاصة لتجنب هذه الشفرة المشكوك فيها، وقد طُوِّرت للأنظمة المُدمجة. [ 48 ]

توجد أيضًا مترجمات ومكتبات وآليات على مستوى نظام التشغيل لتنفيذ إجراءات ليست جزءًا قياسيًا من لغة C، مثل فحص حدود المصفوفات، واكتشاف تجاوز سعة المخزن المؤقت ، والتسلسل ، وتتبع الذاكرة الديناميكية ، وجمع البيانات المهملة التلقائي .

يمكن لأدوات فحص إدارة الذاكرة مثل Purify أو Valgrind، والربط مع المكتبات التي تحتوي على إصدارات خاصة من وظائف تخصيص الذاكرة، أن تساعد في الكشف عن أخطاء وقت التشغيل في استخدام الذاكرة. [ 49 ] [ 50 ]

الاستخدامات

تُستخدم لغة C على نطاق واسع لتنفيذ تطبيقات المستخدم النهائي وتطبيقات مستوى النظام. [ 51 ]

مبررات الاستخدام في برمجة الأنظمة

بعض البرامج المكتوبة بلغة C

تُستخدم لغة C على نطاق واسع في برمجة الأنظمة لتنفيذ أنظمة التشغيل وتطبيقات الأنظمة المدمجة . [ 52 ] وذلك لعدة أسباب:

  • تسمح لغة C بالوصول إلى أجهزة النظام الأساسي والذاكرة باستخدام المؤشرات وتغيير النوع ، لذلك يمكن تكوين واستخدام الميزات الخاصة بالنظام (مثل سجلات التحكم/الحالة ، وسجلات الإدخال/الإخراج ) مع التعليمات البرمجية المكتوبة بلغة C - فهي تتيح التحكم الكامل في النظام الأساسي الذي تعمل عليه.
  • لا يتطلب الكود الناتج عن عملية التجميع العديد من ميزات النظام ، ويمكن استدعاؤه من بعض أكواد التمهيد بطريقة مباشرة - إنه سهل التنفيذ.
  • عادةً ما تتوافق عبارات وتعبيرات لغة C بشكل جيد مع تسلسلات التعليمات الخاصة بالمعالج المستهدف، وبالتالي يكون هناك طلب منخفض على موارد النظام أثناء وقت التشغيل - فهي سريعة التنفيذ.
  • بفضل مجموعة عوامل التشغيل الغنية التي تتمتع بها لغة C، يمكنها الاستفادة من العديد من ميزات وحدات المعالجة المركزية المستهدفة. وعندما تحتوي وحدة معالجة مركزية معينة على تعليمات أكثر تخصصًا، يمكن إنشاء نسخة معدلة من اللغة، ربما باستخدام وظائف مضمنة، لاستغلال تلك التعليمات - مما يتيح لها استخدام جميع ميزات وحدة المعالجة المركزية المستهدفة تقريبًا.
  • تسهل هذه اللغة وضع الهياكل فوق كتل البيانات الثنائية، مما يسمح بفهم البيانات والتنقل بينها وتعديلها - ويمكنها كتابة هياكل البيانات، وحتى أنظمة الملفات.
  • تدعم اللغة مجموعة غنية من العوامل، بما في ذلك معالجة البتات، للحسابات المنطقية الصحيحة، وربما أحجام مختلفة من الأرقام العشرية - يمكنها معالجة البيانات المنظمة بشكل مناسب بفعالية.
  • لغة C هي لغة صغيرة نسبياً، تحتوي على عدد قليل من العبارات فقط، وبدون الكثير من الميزات التي تولد رمزًا مستهدفًا واسع النطاق - إنها مفهومة.
  • تتمتع لغة C بالتحكم المباشر في تخصيص الذاكرة وإلغاء تخصيصها، مما يوفر كفاءة معقولة وتوقيتًا يمكن التنبؤ به لعمليات معالجة الذاكرة، دون أي مخاوف بشأن أحداث جمع البيانات المهملة المتقطعة التي توقف العالم - فهي تتمتع بأداء يمكن التنبؤ به.
  • تسمح لغة C باستخدام وتنفيذ مخططات تخصيص الذاكرة المختلفة ، بما في ذلك المخططات النموذجية mallocو free؛ آلية أكثر تطوراً مع ساحات ؛ أو إصدار لنواة نظام التشغيل قد يناسب DMA ، أو الاستخدام داخل معالجات المقاطعة ، أو التكامل مع نظام الذاكرة الظاهرية .
  • اعتمادًا على الرابط والبيئة، يمكن لرمز C أيضًا استدعاء المكتبات المكتوبة بلغة التجميع ، ويمكن استدعاؤه من لغة التجميع - فهو يتفاعل بشكل جيد مع التعليمات البرمجية الأخرى منخفضة المستوى.
  • تُستخدم لغة C واتفاقيات الاستدعاء الخاصة بها وهياكل الربط الخاصة بها بشكل شائع بالتزامن مع لغات عالية المستوى أخرى، مع دعم الاستدعاءات من وإلى لغة C - فهي تعمل بشكل جيد مع التعليمات البرمجية عالية المستوى الأخرى.
  • تتمتع لغة C بنظام بيئي متكامل وواسع، يشمل المكتبات، والأطر البرمجية، والمترجمات مفتوحة المصدر، وأدوات تصحيح الأخطاء، والأدوات المساعدة، وهي تُعتبر المعيار الفعلي. من المرجح أن تكون برامج التشغيل موجودة بالفعل بلغة C، أو أن هناك بنية معالج مركزي مماثلة تُستخدم كخلفية لمترجم C، مما يقلل من الحافز لاختيار لغة أخرى.

ألعاب

غالبًا ما تُبنى ألعاب الكمبيوتر باستخدام مزيج من لغات البرمجة. وقد برزت لغة C بشكل ملحوظ، خاصةً في الألعاب التي تسعى إلى تحقيق أفضل أداء ممكن على منصات الكمبيوتر. ومن الأمثلة على ذلك لعبة Doom الصادرة عام 1993. [ 53 ]

شبكة الانترنت

تاريخيًا، استُخدمت لغة C أحيانًا في تطوير مواقع الويب باستخدام واجهة البوابة العامة (CGI) كبوابة لنقل المعلومات بين تطبيق الويب والخادم والمتصفح. [ 54 ] ربما تم اختيار C على اللغات المفسرة نظرًا لسرعتها واستقرارها وتوفرها شبه العالمي. [ 55 ] لم يعد تطوير مواقع الويب باستخدام C ممارسة شائعة، [ 56 ] وتنتشر العديد من لغات تطوير الويب الأخرى . تشمل التطبيقات التي لا يزال تطوير مواقع الويب فيها قائمًا على لغة C صفحات تكوين HTTP على أجهزة التوجيه وأجهزة إنترنت الأشياء وما شابه، على الرغم من أن بعض المشاريع هنا تتضمن أجزاءً مكتوبة بلغات برمجة عالية المستوى، مثل استخدام لغة Lua ضمن نظام OpenWRT .

يُكتب خادما الويب الشهيران ، Apache HTTP Server و Nginx ، بلغة C. [ 57 ] [ 58 ] يسمح نهج C القريب من مستوى النظام ببناء أنظمة برمجية عالية الأداء كهذه. [ 59 ]

لغة C كلغة وسيطة

تُستخدم لغة C أحيانًا كلغة وسيطة في تطبيقات لغات أخرى. يُلجأ إلى هذا الأسلوب لتحسين قابلية النقل أو تسهيل الاستخدام؛ فباستخدام C كلغة وسيطة، لا حاجة إلى مولدات أكواد خاصة بكل جهاز. تتميز C ببعض الخصائص، مثل توجيهات المعالج المسبق لأرقام الأسطر والفواصل الزائدة الاختيارية في نهاية قوائم التهيئة، التي تدعم ترجمة الكود المُولّد. مع ذلك، دفعت بعض أوجه قصور C إلى تطوير لغات أخرى مبنية على C مصممة خصيصًا للاستخدام كلغات وسيطة، مثل C-- . كما أن مُجمّعي الأكواد الرئيسيين المعاصرين ، GCC و LLVM ، يُوفران تمثيلًا وسيطًا ليس بلغة C، ويدعمان واجهات أمامية للعديد من اللغات، بما فيها C.

مكتبات تتطلب حسابات مكثفة

تُمكّن لغة C المبرمجين من إنشاء تطبيقات فعّالة للخوارزميات وهياكل البيانات، نظرًا لانخفاض مستوى التجريد من المكونات المادية وانخفاض تكلفتها، وهو معيار مهم للبرامج كثيفة الحساب. على سبيل المثال، مكتبة GNU للحسابات متعددة الدقة ، ومكتبة GNU العلمية ، وبرنامج Mathematica ، وبرنامج MATLAB مكتوبة كليًا أو جزئيًا بلغة C. تدعم العديد من اللغات استدعاء وظائف المكتبات بلغة C؛ فعلى سبيل المثال، يستخدم إطار عمل NumPy المبني على لغة Python لغة C لجوانب الأداء العالي والتفاعل مع المكونات المادية.

تُكتب لغات أخرى بلغة C

نتيجة لتوافر لغة C على نطاق واسع وكفاءتها، فإن المترجمات والمكتبات والمفسرات للغات البرمجة الأخرى غالبًا ما يتم تنفيذها بلغة C. [ 60 ] على سبيل المثال، فإن التطبيقات المرجعية للغات Python ، [ 61 ] وPerl ، [ 62 ] وRuby ، [ 63 ] و PHP [ 64 ] مكتوبة بلغة C.

القيود

وقد مازح ريتشي نفسه بشأن قيود اللغة التي ابتكرها: [ 65 ]

قوة لغة التجميع وسهولة استخدامها... لغة التجميع

دينيس ريتشي

على الرغم من أن الخيار C يحظى بشعبية وتأثير ونجاح هائل، إلا أنه ينطوي على عيوب، منها:

  • إن التعامل القياسي مع الذاكرة الديناميكية باستخدام malloc`and` freeعرضة للأخطاء. وقد يؤدي الاستخدام غير السليم إلى تسرب الذاكرة وظهور مؤشرات معلقة . [ 66 ]
  • إن استخدام المؤشرات والتلاعب المباشر بالذاكرة يعني أن تلف الذاكرة أمر ممكن.
  • يوجد فحص للأنواع ، لكنه لا ينطبق على بعض المجالات مثل الدوال ذات عدد متغير من الوسائط ، ويمكن تجاوز فحص الأنواع بسهولة أو عن غير قصد. إنه ضعيف النوع ، على الرغم من كونه ثابت النوع.
  • بما أن الكود الذي يولده المترجم يحتوي على عدد قليل من عمليات التحقق في وقت التشغيل، فإن هناك عبئًا على المبرمج للنظر في جميع النتائج المحتملة، للحماية من تجاوزات المخزن المؤقت، والتحقق من حدود المصفوفة، وتجاوزات المكدس ، واستنفاد الذاكرة، والنظر في حالات التزامن ، وعزل الخيوط، وما إلى ذلك.
  • يُتيح استخدام المؤشرات ومعالجتها أثناء التشغيل طريقتين للوصول إلى البيانات نفسها (التداخل)، وهو أمر لا يمكن تحديده دائمًا أثناء الترجمة. هذا يعني أن بعض التحسينات المتاحة في لغات أخرى، مثل فورتران، غير ممكنة في لغة سي. ولهذا السبب، تُعتبر فورتران أحيانًا أسرع. [ 67 ]
  • بعض وظائف المكتبة القياسية، على سبيل المثال scanfأو strncat، يمكن أن تؤدي إلى تجاوزات المخزن المؤقت .
  • يوجد توحيد محدود لدعم المتغيرات منخفضة المستوى في الكود المُولّد، مثل اختلاف اصطلاحات استدعاء الدوال وواجهات التطبيقات الثنائية (ABIs) ؛ واختلاف اصطلاحات تعبئة البنية ؛ واختلاف ترتيب البايتات ضمن الأعداد الصحيحة الكبيرة (بما في ذلك ترتيب البايتات). في العديد من تطبيقات اللغات، يمكن التعامل مع بعض هذه الخيارات باستخدام توجيه المعالج المسبق #pragma، [ 68 ] [ 69 ] وبعضها الآخر باستخدام كلمات مفتاحية إضافية، مثل استخدام __cdeclاصطلاح الاستدعاء. لا يتم دعم التوجيه والخيارات بشكل متسق. [ 70 ]
  • تتطلب معالجة السلاسل النصية باستخدام المكتبة القياسية كتابة الكثير من التعليمات البرمجية، مع ضرورة إدارة الذاكرة بشكل صريح.
  • لا تدعم اللغة بشكل مباشر التوجه الكائني، والاستكشاف الذاتي ، وتقييم التعبيرات في وقت التشغيل (كما هو الحال evalفي جافا سكريبت)، وجمع البيانات المهملة، وما إلى ذلك.
  • توجد وسائل حماية قليلة ضد إساءة استخدام خصائص اللغة، مما قد يؤدي إلى كتابة شفرة برمجية يصعب صيانتها . على وجه الخصوص، يمكن لمعالج C المسبق إخفاء آثار ضارة مثل التقييم المزدوج وما هو أسوأ. [ 71 ] وقد تم الاحتفاء بهذه القدرة على تشفير الشفرة من خلال مسابقات مثل المسابقة الدولية لشفرة C المشفرة ومسابقة C الخفية .
  • تفتقر لغة C إلى دعم قياسي لمعالجة الاستثناءات ، ولا توفر سوى رموز إرجاع للتحقق من الأخطاء. وقد استُخدمت دوال المكتبة القياسية setjmp[ longjmp72 ] لتنفيذ آلية try-catch عبر وحدات الماكرو. كما gotoتُستخدم عبارات try-catch بشكل شائع لمعالجة الأخطاء.

حلول لمشاكل C

في بعض الأغراض، تم اعتماد أنماط محدودة من لغة C، مثل MISRA C أو CERT C ، في محاولة للحد من فرص السلوك غير المرغوب فيه. [ 73 ] وتسعى قواعد البيانات مثل CWE إلى حصر الثغرات الأمنية المحتملة في الأنظمة بشكل عام، وخاصة تلك المبرمجة بلغة C، إلى جانب تقديم توصيات للتخفيف من هذه الثغرات.

توجد أدوات يمكنها التخفيف من بعض العيوب. تتضمن مُجمِّعات لغة C الحديثة عمليات فحص قد تُصدر تحذيرات للمساعدة في تحديد العديد من الأخطاء المحتملة.

يمكن تقليل مخاطر استخدام المؤشرات في لغة C باستخدام امتدادات بنية مجموعة التعليمات مثل CHERI أو امتدادات تراكب الأذونات . تُغير هذه التقنيات الطبيعة الأساسية للمؤشرات على مستوى العتاد لتشمل عمليات فحص الحدود والأغراض، مما يساعد على منع تجاوزات المخزن المؤقت والوصول غير المناسب إلى الذاكرة الديناميكية.

منذ أوائل العقد الثاني من القرن الحادي والعشرين، أصبحت نواة لينكس تحتوي على أقسام مكتوبة بلغة رست ، وهي لغة تتضمن تدابير محددة لتحسين السلامة. [ 74 ]

مؤشر TIOBE

تأثرت العديد من اللغات التي طُورت بعد لغة C بجوانب منها، واستعارت منها، بما في ذلك C++ و C# و C shell و D و Go و Java و JavaScript و Julia و Limbo و LPC و Objective-C و Perl و PHP و Python و Ruby و Rust و Swift و Verilog و SystemVerilog . [ 8 ] [ 75 ] ويزعم البعض أن التأثير الأبرز كان نحويًا ، حيث تجمع هذه اللغات بين بنية العبارات والتعبيرات في لغة C وأنظمة الأنواع ونماذج البيانات وهياكل البرامج واسعة النطاق التي تختلف عن تلك الموجودة في لغة C، وأحيانًا بشكل جذري.

توجد العديد من مترجمات لغة C أو ما يقاربها، بما في ذلك Ch و CINT ، والتي يمكن استخدامها أيضًا لكتابة البرامج النصية.

عندما شاعت لغات البرمجة كائنية التوجه ، كانت لغتا C++ و Objective-C امتدادين مختلفين للغة C، وقد وفرتا إمكانيات البرمجة كائنية التوجه. تم تنفيذ كلتا اللغتين في الأصل كمترجمات من المصدر إلى المصدر ؛ حيث تُترجم الشفرة المصدرية إلى لغة C، ثم تُجمّع باستخدام مترجم لغة C. [ 76 ]

ابتكر بيارن ستروستروب لغة البرمجة C++ (التي كانت تُسمى في الأصل "C مع الفئات ") كمنهج لتوفير وظائف البرمجة الكائنية باستخدام بنية مشابهة للغة C. [ 77 ] تُضيف C++ قوة أكبر في تحديد أنواع البيانات، ونطاق المتغيرات، وأدوات أخرى مفيدة في البرمجة الكائنية، كما تسمح بالبرمجة العامة عبر القوالب. تُعد C++ تقريبًا مجموعة شاملة للغة C، وهي تدعم الآن معظم وظائف C، مع بعض الاستثناءات .

كانت لغة Objective-C في الأصل طبقةً رقيقةً فوق لغة C، ولا تزال مجموعةً شاملةً لها تسمح بالبرمجة كائنية التوجه باستخدام نموذج كتابة هجين يجمع بين الديناميكية والثابتة. تستمد Objective-C بنيتها من كلٍّ من لغتي C و Smalltalk : فالبنية التي تتضمن المعالجة المسبقة، والتعبيرات، وتصريحات الدوال، واستدعاءاتها موروثة من لغة C، بينما استُمدت بنية ميزات البرمجة كائنية التوجه في الأصل من لغة Smalltalk.

بالإضافة إلى لغتي C++ و Objective-C ، فإن لغات Ch و Cilk و Unified Parallel C هي مجموعات شاملة تقريبًا للغة C.

انظر أيضاً

ملحوظات

  1. «قام تومسون بمحاولة وجيزة لإنتاج نظام مشفر بنسخة مبكرة من لغة سي - قبل ظهور الهياكل - في عام 1972، لكنه تخلى عن هذا الجهد.» [ 2 ] [ 3 ] [ 4 ]
  2. "إن مخطط تكوين الأحرف الذي اعتمدته لغة C مدين بشكل كبير لخط Algol 68، على الرغم من أنه ربما لم يظهر بالشكل الذي يوافق عليه أنصار Algol." [ 6 ] [ 7 ] [ 4 ]
  3. يُنطق / ˈ siː / ، مثل حرف ' c ' . [ 9 ]
  4. سيتم تجميع نموذج الكود الأصلي على معظم المترجمات الحديثة التي لا تعمل في وضع الامتثال الصارم للمعايير، ولكنه لا يتوافق تمامًا مع متطلبات كل من C89 و C99. في الواقع، يتطلب C99 إنتاج رسالة تشخيصية.
  5. تُستخدمقيمة الإرجاع عادةً في هذا السياق للإشارة إلى النجاح. [ 18 ]0
  6. يختلف الكودprint_array(غير الموضح) قليلاً أيضًا، بسبب نوع p ، حيث يكون مؤشرًا إلى مصفوفة ثنائية الأبعاد في الإصدار الذي تم تخصيصه بواسطة malloc، ومجرد مصفوفة ثنائية الأبعاد في إصدار auto VNA.

مراجع

  1. 1 2 برينز، بيتر؛ كروفورد، توني (16 ديسمبر 2005). C باختصار . أورايلي ميديا، إنك. ص 3. ISBN  978-0-596-55071-4.
  2. ريتشي (1993أ) ، ص 9.
  3. ريتشي (1993ب) ، ص 9.
  4. 1 2 ريتشي (2003) .
  5. "N3221 – تقرير المحرر، بعد اجتماع ستراسبورغ، فرنسا، يناير 2024" . ISO/IEC JTC1/SC22/WG14 . المعايير المفتوحة. 21 فبراير 2024. تم الاطلاع عليه في 24 مايو 2024 .
  6. ريتشي (1993أ) ، ص 8.
  7. ريتشي (1993ب) ، ص 8.
  8. ١ ٢ "Verilog HDL (وC)" (ملف PDF) . كلية أبحاث علوم الحاسوب في الجامعة الوطنية الأسترالية. ٣ يونيو ٢٠١٠. مؤرشف من الأصل (ملف PDF) في ٦ نوفمبر ٢٠١٣. تم الاطلاع عليه في ١٩ أغسطس ٢٠١٣. ثمانينيات القرن العشرين : تم تقديم Verilog لأول مرة؛ Verilog مستوحاة من لغة البرمجة C
  9. «الاسم مشتق من حرف C في الأبجدية الإنجليزية، ويُنطق مثله» . صوت لغة البرمجة C. قاموس إنجليزي صيني. مؤرشف من الأصل في 17 نوفمبر 2022. تم الاطلاع عليه في 17 نوفمبر 2022 .
  10. مونوز، دانيال. "بعد كل هذه السنوات، لا يزال العالم يعتمد على برمجة C | توبتال" . مدونة توبتال الهندسية . تم الاطلاع عليه في 15 يونيو 2024 .
  11. "تراجع شعبية لغة C إلى أدنى مستوى" . Developer.com . 9 أغسطس 2016. مؤرشف من الأصل في 22 أغسطس 2022. تم الاطلاع عليه في 1 أغسطس 2022 .
  12. 1 2 3 4 5 6 7 ريتشي (1993أ) .
  13. "شعبية لغات البرمجة" . 2009. مؤرشف من الأصل في 16 يناير 2009. تم الاطلاع عليه في 16 يناير 2009 .
  14. "فهرس مجتمع برمجة TIOBE" . 2009. مؤرشف من الأصل في 4 مايو 2009. تم الاسترجاع في 6 مايو 2009 .
  15. وارد، تيري أ. (أغسطس 1983). "شروح لغة سي / ببليوغرافيا لغة سي" . بايت . ص 268. تم الاطلاع عليه في 31 يناير 2015 . 
  16. "مؤشر TIOBE لشهر سبتمبر 2024" . مؤرشف من الأصل في 18 سبتمبر 2024. تم الاطلاع عليه في 16 ديسمبر 2025 .
  17. كيرنيغان وريتشي (1978) ، ص 6.
  18. 1 2 3 4 5 6 7 كليمنس، بن (2013). القرن الحادي والعشرون ج . أورايلي وسائل الإعلام . رقم ISBN 978-1-4493-2714-9.
  19. ريتشي، دينيس. "BCPL إلى B إلى C" . lysator.liu.se . مؤرشف من الأصل في 12 ديسمبر 2019. تم الاطلاع عليه في 10 سبتمبر 2019 .
  20. 1 2 3 4 5 جنسن، ريتشارد (9 ديسمبر 2020). ""تصرف غبي للغاية" - أصول حرف C. آرس تكنيكا . مؤرشف من الأصل في 28 مارس 2022. تم الاطلاع عليه في 28 مارس 2022 .
  21. 1 2 جونسون، إس سي ؛ ريتشي، دي إم (1978). "قابلية نقل برامج لغة سي ونظام يونكس". مجلة بيل سيستم التقنية. 57 ( 6): 2021-2048 . CiteSeerX 10.1.1.138.35 . doi : 10.1002/j.1538-7305.1978.tb02141.x . ISSN 0005-8580 . S2CID 17510065 .   (ملاحظة: ملف PDF هو نسخة ممسوحة ضوئياً بتقنية التعرف الضوئي على الحروف (OCR) من الملف الأصلي، ويحتوي على عرض لـ "IBM 370" على أنه "IBM 310".)
  22. ماكيلروي، دكتور في الطب (1987). قارئ أبحاث يونكس: مقتطفات مشروحة من دليل المبرمج، 1971-1986 (ملف PDF) (تقرير فني). مختبرات بيل، قسم أبحاث الحوسبة والتقنية. ص 10. 139. مؤرشف من الأصل (ملف PDF) في 11 نوفمبر 2017. تم الاطلاع عليه في 1 فبراير 2015 . 
  23. ^ كيرنيغان وريتشي (1978) .
  24. "صفحات دليل لغة C". دليل معلومات متنوعة لنظام FreeBSD (إصدار FreeBSD 13.0 ). 30 مايو 2011. مؤرشف من الأصل في 21 يناير 2021. تم الاطلاع عليه في 15 يناير 2021 . أُرشف بتاريخ 21 يناير 2021 في أرشيف الإنترنت (Wayback Machine) .
  25. ^ كيرنيغان وريتشي (1988) .
  26. ستروستروب، بيارن (2002). التنافس بين الأشقاء: لغتا C و C++ (ملف PDF) (تقرير). مختبرات AT&T. مؤرشف من الأصل (ملف PDF) بتاريخ 24 أغسطس 2014. تم الاطلاع عليه بتاريخ 14 أبريل 2014 .
  27. "الأساس المنطقي للمعيار الوطني الأمريكي لنظم المعلومات - لغة البرمجة - سي" . مؤرشف من الأصل في 17 يوليو 2024. تم الاطلاع عليه في 17 يوليو 2024 .
  28. ج. النزاهة . المنظمة الدولية للتوحيد القياسي. 30 مارس 1995. مؤرشف من الأصل في 25 يوليو 2018. تم الاسترجاع في 24 يوليو 2018 .
  29. "JTC1/SC22/WG14 – C" . الصفحة الرئيسية . ISO/IEC. مؤرشف من الأصل في 12 فبراير 2018. تم الاطلاع عليه في 2 يونيو 2011 . 
  30. أندرو بينستوك (12 أكتوبر 2011). "مقابلة مع هيرب ساتر" . دكتور دوبس . مؤرشف من الأصل في 2 أغسطس 2013. تم الاطلاع عليه في 7 سبتمبر 2013 .
  31. "ISO/IEC 9899:2024 (en) — N3220 مسودة عمل" (PDF) . تم الاطلاع عليه بتاريخ 11 يوليو 2025 .
  32. "WG14-N3132 : الجدول الزمني C23 المنقح" (ملف PDF) . open-std.org . 4 يونيو 2023. مؤرشف من النسخة الأصلية (ملف PDF) في 9 يونيو 2023. 
  33. "WG14-N3220 : مسودة عمل، C2y" (ملف PDF) . open-std.org . 21 فبراير 2024. مؤرشف من النسخة الأصلية (ملف PDF) في 26 فبراير 2024. 
  34. "TR 18037: Embedded C" (ملف PDF) . open-std.org . 4 أبريل 2006. ISO/IEC JTC1 SC22 WG14 N1169. مؤرشف من الأصل (ملف PDF) في 25 فبراير 2021. تم الاطلاع عليه في 26 يوليو 2011 .
  35. هاربيسون، صموئيل ب.؛ ستيل، جاي ل. (2002). ج: دليل مرجعي ( الطبعة الخامسة). إنجلوود كليفس، نيوجيرسي : برنتيس هول . ISBN  978-0-13-089592-9.يحتوي على قواعد BNF للغة C.
  36. كيرنيغان وريتشي (1988) ، ص 192.
  37. كيرنيغان وريتشي (1978) ، ص 3.
  38. 1 2 "مسودة اللجنة ISO/IEC 9899:TC3: 5.2.1 مجموعات الأحرف" . 2007.
  39. "مسودة لجنة ISO/IEC 9899:201x (ISO C11)" (ملف PDF) . open-std.org . 2 ديسمبر 2010. مؤرشفة من الأصل (ملف PDF) في 22 ديسمبر 2017. تم الاطلاع عليها في 16 سبتمبر 2011 .
  40. ^ كيرنيغان وريتشي (1988) ، ص 192، 259.
  41. "10 أخطاء شائعة في برمجة لغة C++" . Cs.ucr.edu . مؤرشف من الأصل بتاريخ 21 أكتوبر 2008. تم الاطلاع عليه بتاريخ 26 يونيو 2009 .
  42. شولتز، توماس (2004). لغة C و8051 ( الطبعة الثالثة). أوتسيغو، ميشيغان: دار نشر بيج فري. ص 20. ISBN   978-1-58961-237-2تم الاطلاع عليه بتاريخ 10 فبراير 2012 .
  43. فوير، آلان ر.؛ جيهاني، نارين ح. (مارس 1982). "مقارنة بين لغتي البرمجة سي وباسكال". مجلة ACM Computing Surveys . 14 (1): 73-92 . doi : 10.1145/356869.356872 . S2CID 3136859 . 
  44. كيرنيغان وريتشي (1988) ، ص 122.
  45. على سبيل المثال، يوفر gcc ميزة _FORTIFY_SOURCE. "ميزات الأمان: فحوصات المخزن المؤقت أثناء الترجمة (FORTIFY_SOURCE)" . fedoraproject.org. مؤرشف من الأصل في 7 يناير 2007. تم الاطلاع عليه في 5 أغسطس 2012 .
  46. نيويورك، لندن (2016). البرمجة باستخدام C . بانكوك، تايلاند: SE-EDUCATION PUBLIC COMPANY LIMITED. ص 225 – 230. ISBN  978-616-08-2740-4.
  47. ريموند، إريك س. (11 أكتوبر 1996). قاموس المخترق الجديد ( الطبعة الثالثة). مطبعة معهد ماساتشوستس للتكنولوجيا. ص 432. ISBN   978-0-262-68092-9تم الاطلاع عليه بتاريخ 5 أغسطس 2012 .
  48. "صفحة دليل lint (القسم 1 من نظام freebsd)" . unix.com . 24 مايو 2001. تم الاطلاع عليه في 15 يوليو 2014 .
  49. هارديسون، نيت. "CS107 Valgrind Memcheck" . web.stanford.edu . تم الاطلاع عليه في 23 يونيو 2023 .
  50. هاستينغز، ريد؛ جويس، بوب. "Purify: الكشف السريع عن تسربات الذاكرة وأخطاء الوصول" (ملف PDF) . شركة Pure Software Inc .: 9.
  51. مونوز، دانيال. "بعد كل هذه السنوات، لا يزال العالم يعتمد على برمجة لغة سي" . مدونة توبتال الهندسية . تم الاطلاع عليه بتاريخ 17 نوفمبر 2023 .
  52. ديل، نيل ب.؛ ويمز، تشيب (2014). البرمجة وحل المشكلات باستخدام لغة C++ (الطبعة السادسة ). بيرلينجتون، ماساتشوستس: جونز وبارتليت ليرنينج. ISBN  978-1-4496-9428-9. OCLC 894992484 . 
  53. "تطوير لعبة Doom" . DoomWiki.org . 2 مارس 2025. تم الاطلاع عليه في 2 مارس 2025 .
  54. ^ الكتاب المرجعي للدكتور دوب . الولايات المتحدة: شركة ميلر فريمان، نوفمبر-ديسمبر 1995.
  55. "استخدام لغة C لبرمجة CGI" . linuxjournal.com. 1 مارس 2005. مؤرشف من الأصل في 13 فبراير 2010. تم الاطلاع عليه في 4 يناير 2010 .
  56. بيركنز، لوك (17 سبتمبر 2013). "تطوير مواقع الويب بلغة C: جنون؟ أم جنون كالثعلب؟" . ميديوم . مؤرشف من الأصل في 4 أكتوبر 2014. تم الاطلاع عليه في 8 أبريل 2022 .
  57. "ما لغة البرمجة التي يستخدمها NGINX؟ "
  58. "ما هو أباتشي وماذا يفعل لتطوير مواقع الويب؟" . 15 فبراير 2022.
  59. "نظام المشاركة الزمنية في يونكس: لغة البرمجة سي" . مختبرات نوكيا بيل . تم الاطلاع عليه في 15 يونيو 2026 .
  60. "لغة C - أم اللغات" . أكاديمية تكنولوجيا المعلومات والاتصالات في معهد IITK . ١٣ نوفمبر ٢٠١٨. مؤرشف من الأصل في ٣١ مايو ٢٠٢١. تم الاطلاع عليه في ١١ أكتوبر ٢٠٢٢ .
  61. "1. توسيع بايثون باستخدام لغة C أو C++" . وثائق بايثون 3.10.7 . مؤرشف من الأصل في 5 نوفمبر 2012. تم الاطلاع عليه في 11 أكتوبر 2022 .
  62. كونراد، مايكل (22 يناير 2018). "نظرة عامة على محرك بيرل 5" . Opensource.com . مؤرشف من الأصل في 26 مايو 2022. تم الاطلاع عليه في 11 أكتوبر 2022 .
  63. "التحويل من لغة C و C++ إلى لغة روبي" . لغة برمجة روبي . مؤرشف من الأصل في 12 أغسطس 2013. تم الاطلاع عليه في 11 أكتوبر 2022 .
  64. بارا، مايكل (3 أغسطس 2022). "ما هي لغة PHP؟ كيف تكتب برنامجك الأول بلغة PHP؟" . freeCodeCamp . مؤرشف من الأصل في 4 أغسطس 2022. تم الاطلاع عليه في 11 أكتوبر 2022 .
  65. ميتز، كيد (13 أكتوبر 2011). "دينيس ريتشي: الأكتاف التي وقف عليها ستيف جوبز" . وايرد . مؤرشف من الأصل في 12 أبريل 2022. تم الاطلاع عليه في 19 أبريل 2022 .
  66. مجموعة أبحاث أمن الإنترنت. "ما هو أمان الذاكرة ولماذا هو مهم؟" . بروسيمو . تم الاطلاع عليه في 3 مارس 2025 .
  67. هاول، إيغور (16 مايو 2023). "لماذا يجب عليك التفكير في استخدام لغة فورتران كعالم بيانات" . نحو علم البيانات . تم الاسترجاع في 9 يوليو 2026 .
  68. corob-msft (31 مارس 2022). "توجيهات Pragma والكلمات المفتاحية __pragma و_Pragma" . Microsoft Learn . مؤرشف من الأصل في 24 سبتمبر 2022. تم الاطلاع عليه في 24 سبتمبر 2022 .
  69. "Pragmas (The C Preprocessor)" . GCC، مجموعة مُجمِّعات GNU . مؤرشف من الأصل في 17 يونيو 2002. تم الاطلاع عليه في 24 سبتمبر 2022 .
  70. "Pragmas" . دليل ومرجع مطوري مُصرّف Intel C++ الكلاسيكي . Intel. مؤرشف من الأصل في 10 أبريل 2022. تم الاسترجاع في 10 أبريل 2022 .
  71. "في مدح معالج C المسبق" . apenwarr . 13 أغسطس 2007. تم الاطلاع عليه في 9 يوليو 2023 .
  72. روبرتس، إريك س. (21 مارس 1989). "تطبيق الاستثناءات في لغة C" (ملف PDF) . مركز أبحاث أنظمة DEC . SRC-RR-40. مؤرشف من الأصل (ملف PDF) في 15 يناير 2017. تم الاطلاع عليه في 4 يناير 2022 .
  73. "نظرة عامة على البرمجة الآمنة" (ملف PDF) . معهد هندسة البرمجيات، جامعة كارنيجي ميلون . تم الاطلاع عليه بتاريخ 15 ديسمبر 2025 .
  74. "تحديث جديد لنظام لينكس يؤكد: انتهاء تجربة لغة رست، وبقاءها" . www.phoronix.com . تاريخ الاطلاع: 15 ديسمبر 2025 .
  75. أوريغان، جيرارد (24 سبتمبر 2015). ركائز الحوسبة : مجموعة مختارة من شركات التكنولوجيا المحورية . سبرينغر. ISBN  978-3-319-21464-1. OCLC 922324121 . 
  76. راوخويرجر، لورانس (2004). اللغات والمترجمات للحوسبة المتوازية : ورشة العمل الدولية السادسة عشرة، LCPC 2003، كوليدج ستيشن، تكساس، الولايات المتحدة الأمريكية، 2-4 أكتوبر 2003 : أوراق منقحة . سبرينغر. ISBN   978-3-540-24644-2. OCLC 57965544 . 
  77. ستروستروب، بيارن (1993). "تاريخ لغة C++: 1979-1991" (ملف PDF) . مؤرشف من الأصل (ملف PDF) في 2 فبراير 2019. تم الاطلاع عليه في 9 يونيو 2011 .

مصادر

للمزيد من القراءة

  • بلاوجر، بي جيه (1992). مكتبة لغة سي القياسية (  الطبعة الأولى). برنتيس هول. رقم ISBN 978-0-13-131509-9.(مصدر)
  • باناهان، م.؛ برادي، د.؛ دوران، م. (1991). كتاب لغة C: عرض معيار ANSI C (  الطبعة الثانية). أديسون-ويسلي. ISBN 978-0-201-54433-6.(حر)
  • فوير، آلان ر. (1985). كتاب ألغاز حرف C (  الطبعة الأولى). برنتيس هول. ISBN 0-13-109934-5.
  • هاربيسون، صموئيل؛ ستيل، جاي الابن (2002). ج: دليل مرجعي (  الطبعة الخامسة). بيرسون. ISBN 978-0-13-089592-9.(أرشيف)
  • كينغ، ك. ن. (2008). برمجة لغة سي: منهج حديث (  الطبعة الثانية). دبليو دبليو نورتون. رقم ISBN 978-0-393-97950-3.(أرشيف)
  • غريفيث، ديفيد؛ غريفيث، داون (2012). هيد فيرست سي (  الطبعة الأولى). أورايلي. رقم ISBN 978-1-4493-9991-7.
  • بيري، جريج؛ ميلر، دين (2013). برمجة لغة سي: دليل المبتدئين المطلق (  الطبعة الثالثة). كيو. رقم ISBN 978-0-7897-5198-0.
  • ديتيل، بول؛ ديتيل، هارفي (2015). ج: كيفية البرمجة (8  ed.). بيرسون. رقم ISBN 978-0-13-397689-2.
  • جوستيدت، ينس (2025). لغة سي الحديثة (  الطبعة الثالثة). مانينغ. ISBN 9781633437777.(حر)