C (لغة برمجة)
![]() لغة البرمجة C [1] (يشار إليها غالبًا باسم K&R ) ، الكتاب الأساسي عن C | |
نموذج | متعدد النماذج : أمر حتمي ( إجرائي ) ، منظم |
---|---|
صمم بواسطة | دينيس ريتشي |
مطور | دينيس ريتشي و مختبرات بيل (المبدعين)؛ ANSI X3J11 ( ANSI C ) ؛ ISO / IEC JTC1 / SC22 / WG14 (ISO C) |
اول ظهور | 1972 [2] |
إصدارة مستقرة | C17
/ يونيو 2018 |
معاينة الإصدار | |
تأديب الكتابة | ثابت ، ضعيف ، واضح ، اسمي |
نظام التشغيل | عبر منصة |
ملحقات اسم الملف | .c ، .h |
موقع الكتروني | www www |
التطبيقات الرئيسية | |
K&R C ، GCC ، Clang ، Intel C ، C ++ Builder ، Microsoft Visual C ++ ، Watcom C | |
اللهجات | |
Cyclone ، Unified Parallel C ، Split-C ، Cilk ، C * | |
تأثر ب | |
B ( BCPL ، CPL ) ، ALGOL 68 ، [4] التجميع ، PL / I ، FORTRAN | |
تأثر | |
عديدة : AMPL و AWK و csh و C ++ و C-- و C # و Objective-C و D و Go و Java و JavaScript و Julia و Limbo و LPC و Perl و PHP و Pike و Processing و Python و Rust و Seed7 و Vala و فيريلوج (HDL) ، [5] نيم ، زيغ | |
|
C ( / ق Î / ، كما في الرسالة ج ) هي للأغراض العامة ، الإجرائية الكمبيوتر لغة البرمجة دعم البرمجة المهيكلة ، نطاق متغير المفردات ، و الإعادة ، مع نوع نظام ثابت . حسب التصميم ، يوفر C التركيبات التي ترسم بكفاءة لتعليمات الماكينة النموذجية . لقد وجد استخدامًا دائمًا في التطبيقات التي تم ترميزها مسبقًا في لغة التجميع . تتضمن هذه التطبيقات أنظمة تشغيل وبرامج تطبيقية متنوعةللأبنية الكمبيوتر التي تتراوح من أجهزة الكمبيوتر العملاقة إلى الشركات المحدودة العامة و الأنظمة المدمجة .
تم تطوير خليفة للغة البرمجة B ، C في الأصل في Bell Labs بواسطة Dennis Ritchie بين عامي 1972 و 1973 لإنشاء أدوات مساعدة تعمل على Unix . تم تطبيقه لإعادة تنفيذ نواة نظام التشغيل Unix. [6] خلال الثمانينيات ، اكتسبت لغة C شعبية تدريجيًا. لقد أصبحت واحدة من أكثر لغات البرمجة استخدامًا ، [7] [8] مع مترجمي لغة سي من بائعين مختلفين متاحين لغالبية معماريات وأنظمة تشغيل الكمبيوتر الحالية . تم توحيد C من قبل ANSI منذ عام 1989 ( ANSI C ) ومن قبلالمنظمة الدولية للتوحيد القياسي (ISO).
لغة C هي لغة إجرائية حتمية . لقد تم تصميمه ليتم تجميعه لتوفير وصول منخفض المستوى إلى الذاكرة وبنى اللغة التي تعين بشكل فعال تعليمات الجهاز ، وكل ذلك مع الحد الأدنى من دعم وقت التشغيل . على الرغم من قدراتها منخفضة المستوى ، فقد تم تصميم اللغة لتشجيع البرمجة عبر الأنظمة الأساسية. و للمعايير برنامج C المتوافق مع مكتوبة مع قابلية في الاعتبار يمكن جمعها لمجموعة واسعة من منصات الكمبيوتر وأنظمة التشغيل مع تغييرات قليلة إلى رمز مصدره. [9]
اعتبارًا من يناير 2021 [update]، تم تصنيف C في المرتبة الأولى في مؤشر TIOBE ، وهو مقياس لشعبية لغات البرمجة ، حيث ارتفع من no. 2 بقعة في العام السابق. [10]
نظرة عامة
مثل معظم اللغات الإجرائية في تقليد ALGOL ، فإن لغة C لديها تسهيلات للبرمجة المهيكلة وتسمح بنطاق متغير معجمي وتكرار. يمنع نظام النوع الثابت الخاص به العمليات غير المقصودة. في لغة سي ، يتم تضمين كافة التعليمات البرمجية القابلة للتنفيذ في الإجراءات الفرعية (تسمى أيضًا "وظائف" ، وإن لم تكن بشكل صارم بمعنى البرمجة الوظيفية ). يتم تمرير معلمات الوظيفة دائمًا بالقيمة (باستثناء المصفوفات ). تتم محاكاة التمرير بالمرجع في لغة C بتمرير قيم المؤشر بشكل صريح . نص مصدر برنامج C هو تنسيق حر ، باستخدام الفاصلة المنقوطةكما بيان فاصل و الأقواس المجعدة لتجميع كتل البيانات .
تعرض لغة C أيضًا الخصائص التالية:
- اللغة لديه، عدد قليل الثابتة من الكلمات الرئيسية، بما في ذلك مجموعة كاملة من التحكم في التدفق البدائيون:
if/else
،for
،do/while
،while
، وswitch
. لا يتم تمييز الأسماء المعرفة من قبل المستخدم عن الكلمات الرئيسية بأي نوع من sigil . - لديها عدد كبير من العمليات الحسابية والبتية والمنطقية:
+
،+=
،++
،&
،||
، إلخ. - يمكن تنفيذ أكثر من مهمة واحدة في بيان واحد.
- المهام:
- يمكن تجاهل قيم إرجاع الدالة ، عند عدم الحاجة إليها.
- تسمح مؤشرات الوظائف والبيانات بتعدد أشكال وقت التشغيل المخصص .
- قد لا يتم تعريف الوظائف ضمن النطاق المعجمي للوظائف الأخرى.
- كتابة البيانات ثابتة ولكنها ضعيفة التنفيذ ؛ كل البيانات لها نوع ، لكن التحويلات الضمنية ممكنة.
- يحاكي بناء جملة الإعلان سياق الاستخدام. C لا يوجد لديه كلمة "تعريف" ؛ بدلاً من ذلك ، يتم أخذ العبارة التي تبدأ باسم نوع كإعلان. لا توجد كلمة رئيسية "وظيفة" ؛ بدلاً من ذلك ، تتم الإشارة إلى الوظيفة من خلال وجود قائمة وسيطة بين قوسين.
- المعرفة من قبل المستخدم ( typedef ) والأنواع المركبة ممكنة.
struct
تسمح أنواع البيانات المجمعة غير المتجانسة ( ) بالوصول إلى عناصر البيانات ذات الصلة وتعيينها كوحدة.- الاتحاد هيكل به أعضاء متداخلين ؛ فقط العضو الأخير المخزن صالح.
- فهرسة المصفوفة هي تدوين ثانوي ، يتم تعريفه من حيث حساب المؤشر. على عكس البنيات ، المصفوفات ليست كائنات من الدرجة الأولى: لا يمكن تخصيصها أو مقارنتها باستخدام عوامل مدمجة واحدة. لا توجد كلمة رئيسية "مصفوفة" قيد الاستخدام أو التعريف ؛ بدلاً من ذلك ، تشير الأقواس المربعة إلى المصفوفات نحويًا ، على سبيل المثال
month[11]
. - الأنواع التي تم تعدادها ممكنة مع
enum
الكلمة الأساسية. فهي قابلة للتحويل مع الأعداد الصحيحة بحرية. - سلاسل ليست نوع بيانات واضح، ولكن تقليديا تنفيذها كما منتهية خالية صفائف الحرف.
- يمكن الوصول بمستوى منخفض إلى ذاكرة الكمبيوتر عن طريق تحويل عناوين الجهاز إلى مؤشرات مكتوبة .
- الإجراءات ( الإجراءات الفرعية التي لا تُرجع القيم) هي حالة خاصة للدالة ، مع نوع إرجاع غير مطبوع
void
. - A المعالج بأداء الاقتصاد الكلي التعريف، الشفرة المصدرية إدراج الملف، و الترجمة الشرطية .
- هناك الشكل الأساسي لل نمطية : يمكن تجميع الملفات على حدة و ترتبط معا، مع السيطرة على أي وظائف والبيانات الأشياء واضحة إلى ملفات أخرى عبر
static
وextern
الصفات. - وظائف معقدة مثل I / O ، سلسلة تفوض التلاعب، والدوال الرياضية باستمرار ل إجراءات مكتبة .
بينما C لا تشمل بعض الميزات الموجودة في لغات أخرى (مثل توجيه كائن و جمع القمامة )، وهذه يمكن تنفيذها أو محاكاتها، في كثير من الأحيان من خلال استخدام مكتبات خارجية (على سبيل المثال، كائن نظام الخصلة أو جامع القمامة بوهم ).
العلاقات باللغات الأخرى
اقترضت العديد من اللغات اللاحقة بشكل مباشر أو غير مباشر من C ، بما في ذلك C ++ و C # و Unix's C shell و D و Go و Java و JavaScript (بما في ذلك transpilers ) و Julia و Limbo و LPC و Objective-C و Perl و PHP و Python و Ruby و الصدأ ، سويفت ، فيريلوج و SystemVerilog (وصف الأجهزة لغات). [5] لقد استمدت هذه اللغات العديد من هياكل التحكم والميزات الأساسية الأخرى من C. معظمها (Python استثناء دراماتيكي) تعبر أيضًا عن بناء جملة مشابه جدًا لـ C ، وتميل إلى الجمع بين التعبير المميز وبناء جملة الجمل C مع النوع الأساسي الأنظمة ونماذج البيانات والدلالات التي يمكن أن تكون مختلفة جذريًا.
التاريخ
التطورات المبكرة
عام | معيار C [9] |
---|---|
1972 | ولادة |
1978 | K & R ج |
1989/1990 | ANSI C و ISO C |
1999 | ج 99 |
2011 | ج 11 |
2017 | ج 17 |
يحدد لاحقًا | C2x |
يرتبط أصل C ارتباطًا وثيقًا بتطوير نظام التشغيل Unix ، الذي تم تنفيذه في الأصل بلغة التجميع على PDP-7 بواسطة Dennis Ritchie و Ken Thompson ، مع دمج العديد من الأفكار من الزملاء. في النهاية ، قرروا نقل نظام التشغيل إلى PDP-11 . تم تطوير نسخة PDP-11 الأصلية من Unix أيضًا بلغة التجميع. [6]
أراد Thompson لغة برمجة لإنشاء أدوات مساعدة للنظام الأساسي الجديد. في البداية ، حاول إنشاء مترجم فورتران ، لكنه سرعان ما تخلى عن الفكرة. بدلاً من ذلك ، أنشأ نسخة مختصرة من لغة برمجة أنظمة BCPL المطورة حديثًا . ووصف مسؤول من BCPL غير متوفرة في ذلك الوقت، [11] وتومسون تعديل بناء الجملة لتكون أقل الالفاظ، وإنتاج مماثل ولكن أبسط بعض الشيء B . [6] ومع ذلك ، تمت كتابة عدد قليل من الأدوات المساعدة في النهاية في B لأنها كانت بطيئة للغاية ، ولم يتمكن B من الاستفادة من ميزات PDP-11 مثل قابلية معالجة البايت .
في عام 1972 ، بدأ ريتشي في تحسين B ، وأبرزها إضافة بيانات كتابة للمتغيرات ، مما أدى إلى إنشاء لغة جديدة C. [12] تم تضمين مترجم C وبعض الأدوات المساعدة في الإصدار 2 Unix . [13]
في الإصدار 4 من Unix ، الذي تم إصداره في نوفمبر 1973 ، تمت إعادة تطبيق نواة Unix على نطاق واسع في C. [6] بحلول هذا الوقت ، اكتسبت لغة C بعض الميزات القوية مثل الأنواع.
struct
تم تقديم المعالج الأولي في حوالي عام 1973 بناءً على طلب آلان سنايدر وأيضًا تقديراً لفائدة آليات تضمين الملفات المتوفرة في BCPL و PL / I. في النسخة الأصلية المقدمة شملت فقط الملفات واستبدال سلسلة بسيطة: #include
و #define
وحدات الماكرو parameterless. بعد ذلك بوقت قصير ، تم تمديده ، في الغالب بواسطة مايك ليسك ثم جون ريزر ، لدمج وحدات الماكرو مع الحجج والتجميع الشرطي. [6]
كان يونكس من أوائل نوى أنظمة التشغيل التي تم تطبيقها بلغة أخرى غير التجميع . تتضمن الأمثلة السابقة نظام Multics (الذي تمت كتابته في PL / I ) وبرنامج التحكم الرئيسي (MCP) للطراز Burroughs B5000 (الذي تمت كتابته في ALGOL ) في عام 1961. وفي حوالي عام 1977 ، أجرى ريتشي وستيفن سي. اللغة لتسهيل قابلية نظام التشغيل Unix. عمل مترجم جونسون المحمول C كأساس للعديد من تطبيقات C على منصات جديدة. [12]
K&R C
في عام 1978، براين كيرنيغان و دينيس ريتشي نشر الطبعة الأولى من وC برمجة اللغة . [1] هذا الكتاب، والمعروف أن المبرمجين C كما K & R ، عمل لسنوات عديدة باعتباره غير رسمية مواصفات اللغة. يُشار عادةً إلى إصدار C الذي يصفه باسم " K&R C ". نظرًا لأنه تم إصداره في عام 1978 ، يشار إليه أيضًا باسم C78 . [14] يغطي الإصدار الثاني من الكتاب [15] معيار ANSI C الأحدث ، الموصوف أدناه.
قدمت K&R العديد من ميزات اللغة:
- مكتبة I / O القياسية
long int
نوع البياناتunsigned int
نوع البيانات- تم تغيير مشغلي التخصيص المركب للنموذج (مثل ) إلى النموذج (أي ) لإزالة الغموض الدلالي الناتج عن بنيات مثل ، والتي تم تفسيرها على أنها (إنقاص بمقدار 10) بدلاً من المقصود المحتمل (لنكن - 10).
=op
=-
op=
-=
i=-10
i =- 10
i
i = -10
i
حتى بعد نشر معيار ANSI لعام 1989 ، ظل K&R C لسنوات عديدة يعتبر " القاسم المشترك الأدنى " الذي يقيد مبرمجو C أنفسهم به عندما كان مطلوبًا أقصى قابلية للنقل ، نظرًا لأن العديد من المجمعين الأقدم كانوا لا يزالون قيد الاستخدام ، ولأن K&R مكتوب بعناية يمكن أن يكون كود C هو المعيار C القانوني أيضًا.
في الإصدارات القديمة من لغة C ، int
يجب التصريح عن الوظائف التي ترجع أنواعًا أخرى فقط إذا تم استخدامها قبل تعريف الوظيفة ؛ تم افتراض أن الوظائف المستخدمة بدون إعلان مسبق من نوع الإرجاع int
.
على سبيل المثال:
بعض الوظائف الطويلة () ؛
/ * int * / other_function () ؛
/ * int * / calling_function ()
{
اختبار طويل 1 ؛
تسجيل / * int * / test2 ؛
test1 = some_function () ؛
إذا ( test1 > 0 )
test2 = 0 ؛
آخر
test2 = other_function () ،
اختبار العودة 2 ؛
}
على int
محددات النوع التي علق بها يمكن حذف في K & R C، ولكن مطلوبة في مستويات لاحقة.
نظرًا لأن إعلانات وظائف K&R لم تتضمن أي معلومات حول وسيطات الدالة ، لم يتم إجراء عمليات التحقق من نوع معلمة الوظيفة ، على الرغم من أن بعض المجمعين قد يصدرون رسالة تحذير إذا تم استدعاء دالة محلية مع عدد غير صحيح من الوسائط ، أو في حالة استدعاءات متعددة لوظيفة خارجية تستخدم أعدادًا أو أنواعًا مختلفة من الوسيطات. تم تطوير أدوات منفصلة مثل أداة لينت الخاصة بـ Unix والتي (من بين أشياء أخرى) يمكنها التحقق من تناسق استخدام الوظيفة عبر ملفات مصدر متعددة.
في السنوات التي أعقبت نشر K&R C ، تمت إضافة العديد من الميزات إلى اللغة ، مدعومة من قبل المترجمين من AT&T (على وجه الخصوص PCC [16] ) وبعض البائعين الآخرين. وشملت هذه:
void
الدوال (أي الدوال التي ليس لها قيمة عائدة)- إرجاع الدالات
struct
أوunion
أنواعها (بدلاً من المؤشرات) - التنازل عن
struct
أنواع البيانات - الأنواع المعدودة
أدى العدد الكبير من الامتدادات وعدم الاتفاق على مكتبة قياسية ، جنبًا إلى جنب مع شعبية اللغة وحقيقة أنه حتى مترجمي Unix لم ينفذوا بدقة مواصفات K&R ، أدى إلى ضرورة التوحيد القياسي.
ANSI C و ISO C
خلال أواخر 1970s و 1980s، تم تنفيذ إصدارات C لمجموعة واسعة من أجهزة الكمبيوتر المركزية ، متوسطة ، و الحواسيب الصغيرة ، بما في ذلك أجهزة الكمبيوتر IBM ، في الوقت الذي بدأت شعبيته إلى زيادة كبيرة.
في عام 1983 ، شكل المعهد الوطني الأمريكي للمعايير (ANSI) لجنة ، X3J11 ، لوضع مواصفات قياسية لـ C. X3J11 استنادًا إلى معيار C على تطبيق Unix ؛ ومع ذلك ، تم تسليم الجزء غير المحمول من مكتبة Unix C إلى مجموعة عمل IEEE 1003 لتصبح الأساس لمعيار POSIX لعام 1988 . في عام 1989 ، تم التصديق على معيار C كـ ANSI X3.159-1989 "لغة البرمجة C". غالبًا ما يشار إلى هذا الإصدار من اللغة باسم ANSI C أو Standard C أو أحيانًا C89.
في عام 1990 ، تم اعتماد معيار ANSI C (مع تغييرات التنسيق) من قبل المنظمة الدولية للتوحيد القياسي (ISO) باعتباره 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 للتوافق مع شفرة المصدر الحالية.
C89 مدعوم من قبل مترجمي C الحاليين ، ويعتمد عليه معظم كود C الحديث. أي برنامج مكتوب فقط في المعيار C وبدون أي افتراضات تعتمد على الأجهزة سيعمل بشكل صحيح على أي منصة مع تطبيق C متوافق ، ضمن حدود موارده. بدون هذه الاحتياطات ، قد يتم تجميع البرامج فقط على نظام أساسي معين أو مع مترجم معين ، على سبيل المثال ، بسبب استخدام المكتبات غير القياسية ، مثل مكتبات واجهة المستخدم الرسومية ، أو الاعتماد على سمات خاصة بالمترجم أو النظام الأساسي مثل كحجم دقيق لأنواع البيانات و endianness البايت .
في الحالات التي يجب أن يكون فيها الكود قابلاً للترجمة عن طريق المترجمين المطابقين للمعيار أو المترجمين المعتمدين على K&R C ، __STDC__
يمكن استخدام الماكرو لتقسيم الكود إلى أقسام قياسية و K&R لمنع الاستخدام في مترجم K&R C من الميزات المتوفرة فقط في Standard ج.
بعد عملية توحيد ANSI / ISO ، ظلت مواصفات لغة C ثابتة نسبيًا لعدة سنوات. في عام 1995 ، تم نشر التعديل المعياري 1 لمعيار 1990 C (ISO / IEC 9899 / AMD1: 1995 ، المعروف بشكل غير رسمي باسم C95) ، لتصحيح بعض التفاصيل وإضافة المزيد من الدعم المكثف لمجموعات الأحرف الدولية. [17]
C99
تمت مراجعة معيار C مرة أخرى في أواخر التسعينيات ، مما أدى إلى نشر ISO / IEC 9899: 1999 في عام 1999 ، والذي يشار إليه عادة باسم " C99 ". ومنذ ذلك الحين تم تعديله ثلاث مرات بواسطة تصويبات فنية. [18]
قدم C99 العديد من الميزات الجديدة، بما في ذلك وظائف مضمنة ، عدة جديدة أنواع البيانات (بما في ذلك long long int
و complex
نوع لتمثيل الأعداد المركبة )، صفائف متغيرة الطول و أعضاء مجموعة مرنة ، وتحسين الدعم ل IEEE 754 نقطة، دعم عائمة ل وحدات الماكرو variadic (وحدات الماكرو من متغير arity ) ، ودعم التعليقات ذات السطر الواحد التي تبدأ بـ //
، كما في BCPL أو C ++. تم بالفعل تنفيذ العديد من هذه كإمتدادات في العديد من برامج التحويل البرمجي للغة C.
C99 متوافق في الغالب مع الإصدارات السابقة مع C90 ، ولكنه أكثر صرامة من بعض النواحي ؛ على وجه الخصوص ، التصريح الذي يفتقر إلى محدد النوع لم يعد int
يفترض ضمنيًا. __STDC_VERSION__
يتم تعريف الماكرو القياسي بقيمة 199901L
للإشارة إلى توفر دعم C99. يدعم كل من GCC و Solaris Studio ومجمعي C الآخرين الآن العديد من الميزات الجديدة لـ C99 أو جميعها. ومع ذلك ، فإن مترجم C في Microsoft Visual C ++ ، يطبق معيار C89 وتلك الأجزاء من C99 المطلوبة للتوافق مع C ++ 11 . [19] [ بحاجة إلى تحديث ]
بالإضافة إلى ذلك ، فإن دعم معرفات Unicode (أسماء المتغيرات / الوظائف) في شكل أحرف تم تجاوزها (على سبيل المثال \U0001f431
) مطلوب الآن. دعم أسماء Unicode الأولية اختياري.
C11
في عام 2007 ، بدأ العمل على مراجعة أخرى لمعيار C ، تسمى بشكل غير رسمي "C1X" حتى نشرها رسميًا في 2011-12-08. اعتمدت لجنة معايير C مبادئ توجيهية للحد من اعتماد الميزات الجديدة التي لم يتم اختبارها من خلال التطبيقات الحالية.
يضيف معيار C11 العديد من الميزات الجديدة إلى C والمكتبة ، بما في ذلك نوع وحدات الماكرو العامة ، والهياكل المجهولة ، ودعم Unicode المحسن ، والعمليات الذرية ، والوظائف متعددة مؤشرات الترابط ، وفحص الحدود. كما أنه يجعل بعض أجزاء مكتبة C99 الحالية اختيارية ، ويحسن التوافق مع C ++. __STDC_VERSION__
يتم تعريف الماكرو القياسي 201112L
للإشارة إلى توفر دعم C11.
C17
تم نشر C17 في يونيو 2018 ، وهو المعيار الحالي للغة البرمجة C. لا يقدم أي ميزات لغوية جديدة ، فقط التصحيحات الفنية والتوضيحات للعيوب الموجودة في C11. __STDC_VERSION__
يتم تعريف الماكرو القياسي على أنه 201710L
.
C2x
C2x هو اسم غير رسمي للمراجعة القياسية الرئيسية التالية (بعد C17) للغة C. من غير المتوقع أن يتم التصويت عليها حتى ديسمبر 2021.
مضمن C
من الناحية التاريخية ، تتطلب برمجة C المدمجة امتدادات غير قياسية للغة C من أجل دعم الميزات الغريبة مثل حساب النقاط الثابتة ، وبنوك ذاكرة مميزة متعددة ، وعمليات الإدخال / الإخراج الأساسية.
في عام 2008 ، نشرت لجنة المعايير C تقريرًا تقنيًا يوسع لغة C [20] لمعالجة هذه القضايا من خلال توفير معيار مشترك لجميع عمليات التنفيذ للالتزام بها. يتضمن عددًا من الميزات غير المتوفرة في لغة C العادية ، مثل حساب النقطة الثابتة ، ومساحات العناوين المسماة ، وعناوين أجهزة الإدخال / الإخراج الأساسية.
بناء الجملة
لغة C لديها قواعد نحوية محددة بمعيار C. [21] نهايات السطر ليست مهمة بشكل عام في C ؛ ومع ذلك ، فإن حدود الخط لها أهمية أثناء مرحلة ما قبل المعالجة. قد تظهر التعليقات إما بين المحددات /*
و */
، أو (منذ C99) بعد ذلك //
حتى نهاية السطر. تعليقات محددة بواسطة /*
و */
لا العش، وعدم تفسير هذه تسلسل الأحرف كمحددات تعليق إذا كانت تظهر داخل سلسلة أو حرف حرفية. [22]
تحتوي ملفات المصدر C على تعريفات ووظائف. تحتوي تعريفات الوظائف ، بدورها ، على إعلانات وبيانات . الإعلانات إما تحدد أنواع جديدة باستخدام كلمات رئيسية مثل struct
، union
و enum
، أو أنواع تعيين لوالتخزين ربما الاحتياط للمتغيرات جديدة، عادة عن طريق كتابة نوع متبوعا باسم متغير. مثل كلمات كما char
و int
تحديدها المدمج في أنواع. أرفقت مقاطع التعليمات البرمجية في الأقواس ( {
و }
، التي تسمى أحيانا "الأقواس") للحد من نطاق الإعلانات وليكون بمثابة بيان واحد لهياكل المراقبة.
كلغة حتمية ، يستخدم C عبارات لتحديد الإجراءات. العبارة الأكثر شيوعًا هي عبارة تعبير ، تتكون من تعبير يتم تقييمه ، متبوعًا بفاصلة منقوطة ؛ كما أثر جانبي للتقييم، قد تكون وظائف ودعا ويمكن المتغيرات المخصصة قيم جديدة. لتعديل التنفيذ المتسلسل العادي للبيانات ، توفر لغة C العديد من عبارات التحكم في التدفق المحددة بواسطة الكلمات الرئيسية المحجوزة. برمجة منظم تدعمه if
(- else
) تنفيذ الشرطي و do
- while
، while
و for
تنفيذ تكرارية (حلقات). الfor
يحتوي البيان على تعبيرات تهيئة واختبار وإعادة تهيئة منفصلة ، يمكن حذف أي منها أو جميعها. break
و continue
يمكن استخدامها لمغادرة بيان أرفق حلقة الأعمق أو انتقل إلى reinitialization لها. يوجد أيضًا بيان غير منظم goto
يتفرع مباشرة إلى التسمية المحددة داخل الوظيفة. switch
يختار a case
ليتم تنفيذه بناءً على قيمة تعبير عدد صحيح.
يمكن أن تستخدم التعبيرات مجموعة متنوعة من عوامل التشغيل المضمنة وقد تحتوي على استدعاءات وظيفية. الترتيب الذي يتم فيه تقييم وسيطات الدوال والمعاملات لمعظم المشغلين غير محدد. قد تكون التقييمات متداخلة. ومع ذلك ، ستحدث جميع الآثار الجانبية (بما في ذلك تخزين المتغيرات) قبل " نقطة التسلسل " التالية ؛ تتضمن نقاط التسلسل نهاية كل عبارة تعبير ، والمدخل إلى كل استدعاء دالة والعودة منه. تحدث نقاط تسلسل أيضا أثناء تقييم التعبيرات التي تحتوي على بعض المشغلين ( &&
، ||
، ?:
و مشغل فاصلة). يسمح هذا بدرجة عالية من تحسين التعليمات البرمجية للكائن بواسطة المترجم ، ولكنه يتطلب من مبرمجي C أن يهتموا أكثر للحصول على نتائج موثوقة أكثر مما هو مطلوب للغات البرمجة الأخرى.
يقول Kernighan و Ritchie في مقدمة لغة البرمجة C : "C ، مثل أي لغة أخرى ، لها عيوبها. بعض المشغلين لديهم أسبقية خاطئة ؛ بعض أجزاء بناء الجملة يمكن أن تكون أفضل." [23] لم يحاول المعيار C تصحيح العديد من هذه العيوب ، بسبب تأثير هذه التغييرات على البرامج الموجودة بالفعل.
مجموعة الأحرف
تتضمن مجموعة أحرف مصدر C الأساسية الأحرف التالية:
- الأحرف الصغيرة والأحرف الكبيرة من الأبجدية اللاتينية الأساسية ISO:
a
-z
A
-Z
- أرقام عشرية:
0
-9
- الشخصيات الرسومية:
! " # % & ' ( ) * + , - . / : ; < = > ? [ \ ] ^ _ { | } ~
- أحرف المسافات البيضاء : مسافة ، علامة تبويب أفقية ، علامة تبويب رأسية ، نموذج تغذية ، سطر جديد
يشير الخط الجديد إلى نهاية سطر النص ؛ لا يلزم أن تتوافق مع حرف واحد فعلي ، على الرغم من أن C تعامله على أنه واحد.
يمكن استخدام أحرف مشفرة متعددة البايت إضافية في السلاسل الحرفية ، لكنها ليست محمولة بالكامل . يسمح أحدث معيار C ( C11 ) بتضمين أحرف Unicode متعددة الجنسيات بشكل قابل للنقل داخل نص مصدر C باستخدام \uXXXX
أو \UXXXXXXXX
ترميز (حيث X
تشير الحرف إلى حرف سداسي عشري) ، على الرغم من أن هذه الميزة لم يتم تنفيذها على نطاق واسع حتى الآن.
تحتوي مجموعة أحرف تنفيذ C الأساسية على نفس الأحرف ، جنبًا إلى جنب مع تمثيلات للتنبيه ، ومسافة للخلف ، وعودة إلى أول السطر . زاد دعم وقت التشغيل لمجموعات الأحرف الممتدة مع كل مراجعة لمعيار C.
الكلمات المحجوزة
يحتوي C89 على 32 كلمة محجوزة ، تُعرف أيضًا باسم الكلمات الرئيسية ، وهي الكلمات التي لا يمكن استخدامها لأي أغراض بخلاف تلك التي تم تحديدها مسبقًا من أجلها:
C99 حجزت خمس كلمات أخرى:
حجز C11 سبع كلمات أخرى: [24]
_Alignas
_Alignof
_Atomic
_Generic
_Noreturn
_Static_assert
_Thread_local
تبدأ معظم الكلمات المحجوزة مؤخرًا بشرطة سفلية متبوعة بحرف كبير ، لأن معرفات هذا النموذج كانت محفوظة مسبقًا بواسطة معيار C للاستخدام فقط من خلال عمليات التنفيذ. نظرًا لأن الكود المصدري للبرنامج الحالي لا ينبغي أن يستخدم هذه المعرفات ، فلن يتأثر عندما تبدأ تطبيقات C في دعم هذه الامتدادات للغة البرمجة. تحدد بعض الرؤوس القياسية مرادفات أكثر ملاءمة للمعرفات التي تم تسطيرها أسفل السطر. تضمنت اللغة سابقًا كلمة محجوزة تسمى entry
، ولكن نادرًا ما تم تنفيذها ، وتمت إزالتها الآن ككلمة محجوزة. [25]
عوامل التشغيل
يدعم C مجموعة غنية من العوامل ، وهي رموز مستخدمة في التعبير لتحديد المعالجات التي يجب إجراؤها أثناء تقييم هذا التعبير. لدى C عوامل تشغيل لـ:
- حسابي :
+
،-
،*
،/
،%
- مهمة :
=
- مهمة زيادة :
+=
،-=
،*=
،/=
،%=
،&=
،|=
،^=
،<<=
،>>=
- منطق أحادي :
~
،&
،|
،^
- التحولات المختصة بالبت :
<<
،>>
- منطق منطقي :
!
،&&
،||
- التقييم المشروط :
? :
- اختبار المساواة:
==
،!=
- وظائف الاتصال :
( )
- الزيادة والنقصان :
++
،--
- اختيار الأعضاء :
.
،->
- حجم الكائن:
sizeof
- علاقات النظام :
<
،<=
،>
،>=
- المرجع والاشتقاق :
&
،*
،[ ]
- التسلسل:
,
- تجميع التعبيرات الفرعية :
( )
- نوع التحويل :
(typename)
يستخدم C عامل التشغيل =
(المستخدم في الرياضيات للتعبير عن المساواة) للإشارة إلى التخصيص ، باتباع سابقة Fortran و PL / I ، ولكن على عكس ALGOL ومشتقاته. يستخدم C عامل التشغيل ==
لاختبار المساواة. قد يؤدي التشابه بين هذين العاملين (التخصيص والمساواة) إلى الاستخدام العرضي لأحدهما بدلاً من الآخر ، وفي كثير من الحالات ، لا ينتج عن الخطأ رسالة خطأ (على الرغم من أن بعض المجمعين يصدرون تحذيرات). على سبيل المثال ، if (a == b + 1)
قد تتم كتابة التعبير الشرطي عن طريق الخطأ على أنه if (a = b + 1)
، والذي سيتم تقييمه على أنه صحيح إذا a
لم يكن صفرًا بعد الإسناد. [26]
أسبقية عامل التشغيل C ليست دائمًا بديهية. على سبيل المثال ، ==
يرتبط المشغل بشكل أكثر إحكامًا من (يتم تنفيذه قبل) المشغلين &
(أحاديات AND) و |
(أحاديات OR) في تعبيرات مثل x & 1 == 0
، والتي يجب كتابتها كما (x & 1) == 0
لو كان هذا هو قصد المبرمج. [27]
مثال على "Hello، world"
أصبح مثال " hello، world " ، الذي ظهر في الإصدار الأول من K&R ، نموذجًا لبرنامج تمهيدي في معظم كتب البرمجة المدرسية. يقوم البرنامج بطباعة "hello، world" إلى الإخراج القياسي ، والذي يكون عادةً شاشة عرض طرفية أو شاشة.
النسخة الأصلية كانت: [28]
رئيسي ()
{
printf ( "hello، world \ n " )؛
}
برنامج "hello، world" المطابق للمعايير هو: [a]
# تشمل <stdio.h>
int main ( باطل )
{
printf ( "hello، world \ n " )؛
}
يحتوي السطر الأول من البرنامج على توجيه معالجة مسبقة ، يُشار إليه بواسطة #include
. يؤدي هذا إلى قيام المترجم باستبدال هذا السطر بالنص الكامل stdio.h
للرأس القياسي ، والذي يحتوي على إعلانات لوظائف الإدخال والإخراج القياسية مثل printf
و scanf
. تشير أقواس الزاوية المحيطة stdio.h
إلى أنه stdio.h
موجود باستخدام إستراتيجية بحث تفضل الرؤوس المتوفرة مع المترجم على الرؤوس الأخرى التي لها نفس الاسم ، على عكس علامات الاقتباس المزدوجة التي تتضمن عادةً ملفات رأس محلية أو خاصة بالمشروع.
يشير السطر التالي إلى أنه main
يتم تعريف دالة مسماة . و main
تخدم وظيفة غرض خاص في برامج C. تستدعي بيئة وقت التشغيل main
الوظيفة لبدء تنفيذ البرنامج. int
يشير محدد النوع إلى أن القيمة التي يتم إرجاعها إلى المستدعي (في هذه الحالة بيئة وقت التشغيل) نتيجة لتقييم main
الوظيفة ، هي عدد صحيح. تشير الكلمة الأساسية void
كقائمة معلمات إلى أن هذه الوظيفة لا تأخذ أي وسيطات. [ب]
يشير قوس الفتح المتعرج إلى بداية تعريف main
الوظيفة.
يستدعي السطر التالي (يحول التنفيذ إلى) وظيفة مسماة printf
، والتي يتم توفيرها في هذه الحالة من مكتبة النظام . في هذا الاستدعاء ، printf
يتم تمرير الوظيفة (مع توفير) وسيطة واحدة ، عنوان الحرف الأول في السلسلة الحرفية "hello, world\n"
. السلسلة الحرفية عبارة عن مصفوفة غير مسماة مع عناصر من النوع char
، يتم إعدادها تلقائيًا بواسطة المترجم باستخدام حرف 0 نهائي لتحديد نهاية المصفوفة ( printf
تحتاج إلى معرفة ذلك). و \n
هو تسلسل هروب أن C يترجم إلى السطر حرف، مما يدل على الانتاج نهاية السطر الحالي. القيمة المرجعة لـprintf
الوظيفة من النوع int
، ولكن يتم تجاهلها بصمت نظرًا لعدم استخدامها. (قد يختبر برنامج أكثر حرصًا قيمة الإرجاع لتحديد ما إذا كانت printf
الوظيفة قد نجحت أم لا .) ;
تنهي الفاصلة المنقوطة العبارة.
يشير قوس الإغلاق المتعرج إلى نهاية رمز main
الوظيفة. وفقًا لمواصفات C99 والإصدارات الأحدث ، فإن main
الوظيفة ، على عكس أي دالة أخرى ، ستُرجع ضمنيًا قيمة 0
عند الوصول إلى }
ذلك إنهاء الوظيفة. ( return 0;
كان مطلوبًا سابقًا عبارة صريحة .) يتم تفسير ذلك من خلال نظام وقت التشغيل على أنه رمز خروج يشير إلى التنفيذ الناجح. [29]
أنواع البيانات
و نوع نظام في C هو ثابت و كتابة ضعيفة ، مما يجعله على غرار نظام نوع من ALGOL أحفاد مثل باسكال . [30] هناك أنواع مضمنة للأعداد الصحيحة ذات الأحجام المختلفة ، سواء الموقعة أو غير الموقعة ، وأرقام الفاصلة العائمة ، والأنواع المعددة ( enum
). char
غالبًا ما يستخدم النوع الصحيح للأحرف أحادية البايت. أضاف C99 نوع بيانات منطقي . وهناك أيضا أنواع المستمدة بما في ذلك المصفوفات ، المؤشرات ، سجلات ( struct
)، و النقابات ( union
).
C is often used in low-level systems programming where escapes from the type system may be necessary. The compiler attempts to ensure type correctness of most expressions, but the programmer can override the checks in various ways, either by using a type cast to explicitly convert a value from one type to another, or by using pointers or unions to reinterpret the underlying bits of a data object in some other way.
Some find C's declaration syntax unintuitive, particularly for function pointers. (Ritchie's idea was to declare identifiers in contexts resembling their use: "declaration reflects use".)[31]
C's usual arithmetic conversions allow for efficient code to be generated, but can sometimes produce unexpected results. For example, a comparison of signed and unsigned integers of equal width requires a conversion of the signed value to unsigned. This can generate unexpected results if the signed value is negative.
Pointers
C supports the use of pointers, a type of reference that records the address or location of an object or function in memory. Pointers can be dereferenced to access data stored at the address pointed to, or to invoke a pointed-to function. Pointers can be manipulated using assignment or pointer arithmetic. The run-time representation of a pointer value is typically a raw memory address (perhaps augmented by an offset-within-word field), but since a pointer's type includes the type of the thing pointed to, expressions including pointers can be type-checked at compile time. Pointer arithmetic is automatically scaled by the size of the pointed-to data type. Pointers are used for many purposes in C. Text strings are commonly manipulated using pointers into arrays of characters. Dynamic memory allocation is performed using pointers. Many data types, such as trees, are commonly implemented as dynamically allocated struct
objects linked together using pointers. Pointers to functions are useful for passing functions as arguments to higher-order functions (such as qsort or bsearch) or as callbacks to be invoked by event handlers.[29]
A null pointer value explicitly points to no valid location. Dereferencing a null pointer value is undefined, often resulting in a segmentation fault. Null pointer values are useful for indicating special cases such as no "next" pointer in the final node of a linked list, or as an error indication from functions returning pointers. In appropriate contexts in source code, such as for assigning to a pointer variable, a null pointer constant can be written as 0
, with or without explicit casting to a pointer type, or as the NULL
macro defined by several standard headers. In conditional contexts, null pointer values evaluate to false, while all other pointer values evaluate to true.
Void pointers (void *
) point to objects of unspecified type, and can therefore be used as "generic" data pointers. Since the size and type of the pointed-to object is not known, void pointers cannot be dereferenced, nor is pointer arithmetic on them allowed, although they can easily be (and in many contexts implicitly are) converted to and from any other object pointer type.[29]
Careless use of pointers is potentially dangerous. Because they are typically unchecked, a pointer variable can be made to point to any arbitrary location, which can cause undesirable effects. Although properly used pointers point to safe places, they can be made to point to unsafe places by using invalid pointer arithmetic; the objects they point to may continue to be used after deallocation (dangling pointers); they may be used without having been initialized (wild pointers); or they may be directly assigned an unsafe value using a cast, union, or through another corrupt pointer. In general, C is permissive in allowing manipulation of and conversion between pointer types, although compilers typically provide options for various levels of checking. Some other programming languages address these problems by using more restrictive reference types.
Arrays
Array types in C are traditionally of a fixed, static size specified at compile time. (The more recent C99 standard also allows a form of variable-length arrays.) However, it is also possible to allocate a block of memory (of arbitrary size) at run-time, using the standard library's malloc
function, and treat it as an array. C's unification of arrays and pointers means that declared arrays and these dynamically allocated simulated arrays are virtually interchangeable.
Since arrays are always accessed (in effect) via pointers, array accesses are typically not checked against the underlying array size, although some compilers may provide bounds checking as an option.[32][33] Array bounds violations are therefore possible and rather common in carelessly written code, and can lead to various repercussions, including illegal memory accesses, corruption of data, buffer overruns, and run-time exceptions. If bounds checking is desired, it must be done manually.
C does not have a special provision for declaring multi-dimensional arrays, but rather relies on recursion within the type system to declare arrays of arrays, which effectively accomplishes the same thing. The index values of the resulting "multi-dimensional array" can be thought of as increasing in row-major order.
Multi-dimensional arrays are commonly used in numerical algorithms (mainly from applied linear algebra) to store matrices. The structure of the C array is well suited to this particular task. However, since arrays are passed merely as pointers, the bounds of the array must be known fixed values or else explicitly passed to any subroutine that requires them, and dynamically sized arrays of arrays cannot be accessed using double indexing. (A workaround for this is to allocate the array with an additional "row vector" of pointers to the columns.)
C99 introduced "variable-length arrays" which address some, but not all, of the issues with ordinary C arrays.
Array–pointer interchangeability
The subscript notation x[i]
(where x
designates a pointer) is syntactic sugar for *(x+i)
.[34] Taking advantage of the compiler's knowledge of the pointer type, the address that x + i
points to is not the base address (pointed to by x
) incremented by i
bytes, but rather is defined to be the base address incremented by i
multiplied by the size of an element that x
points to. Thus, x[i]
designates the i+1
th element of the array.
Furthermore, in most expression contexts (a notable exception is as operand of sizeof
), the name of an array is automatically converted to a pointer to the array's first element. This implies that an array is never copied as a whole when named as an argument to a function, but rather only the address of its first element is passed. Therefore, although function calls in C use pass-by-value semantics, arrays are in effect passed by reference.
The size of an element can be determined by applying the operator sizeof
to any dereferenced element of x
, as in n = sizeof *x
or n = sizeof x[0]
, and the number of elements in a declared array A
can be determined as sizeof A / sizeof A[0]
. The latter only applies to array names: variables declared with subscripts (int A[20]
). Due to the semantics of C, it is not possible to determine the entire size of arrays through pointers to arrays, such as arrays created by dynamic allocation (malloc
) or array function parameters; code such as sizeof arr / sizeof arr[0]
(where arr
designates a pointer) will not work since the compiler assumes the size of the pointer itself is being requested.[35][36] Since array name arguments to sizeof
are not converted to pointers, they do not exhibit such ambiguity. However, arrays created by dynamic allocation are accessed by pointers rather than true array variables, so they suffer from the same sizeof
issues as array pointers.
Thus, despite this apparent equivalence between array and pointer variables, there is still a distinction to be made between them. Even though the name of an array is, in most expression contexts, converted into a pointer (to its first element), this pointer does not itself occupy any storage; the array name is not an l-value, and its address is a constant, unlike a pointer variable. Consequently, what an array "points to" cannot be changed, and it is impossible to assign a new address to an array name. Array contents may be copied, however, by using the memcpy
function, or by accessing the individual elements.
Memory management
One of the most important functions of a programming language is to provide facilities for managing memory and the objects that are stored in memory. C provides three distinct ways to allocate memory for objects:[29]
- Static memory allocation: space for the object is provided in the binary at compile-time; these objects have an extent (or lifetime) as long as the binary which contains them is loaded into memory.
- Automatic memory allocation: temporary objects can be stored on the stack, and this space is automatically freed and reusable after the block in which they are declared is exited.
- Dynamic memory allocation: blocks of memory of arbitrary size can be requested at run-time using library functions such as
malloc
from a region of memory called the heap; these blocks persist until subsequently freed for reuse by calling the library functionrealloc
orfree
These three approaches are appropriate in different situations and have various trade-offs. For example, static memory allocation has little allocation overhead, automatic allocation may involve slightly more overhead, and dynamic memory allocation can potentially have a great deal of overhead for both allocation and deallocation. The persistent nature of static objects is useful for maintaining state information across function calls, automatic allocation is easy to use but stack space is typically much more limited and transient than either static memory or heap space, and dynamic memory allocation allows convenient allocation of objects whose size is known only at run-time. Most C programs make extensive use of all three.
Where possible, automatic or static allocation is usually simplest because the storage is managed by the compiler, freeing the programmer of the potentially error-prone chore of manually allocating and releasing storage. However, many data structures can change in size at runtime, and since static allocations (and automatic allocations before C99) must have a fixed size at compile-time, there are many situations in which dynamic allocation is necessary.[29] Prior to the C99 standard, variable-sized arrays were a common example of this. (See the article on malloc
for an example of dynamically allocated arrays.) Unlike automatic allocation, which can fail at run time with uncontrolled consequences, the dynamic allocation functions return an indication (in the form of a null pointer value) when the required storage cannot be allocated. (Static allocation that is too large is usually detected by the linker or loader, before the program can even begin execution.)
Unless otherwise specified, static objects contain zero or null pointer values upon program startup. Automatically and dynamically allocated objects are initialized only if an initial value is explicitly specified; otherwise they initially have indeterminate values (typically, whatever bit pattern happens to be present in the storage, which might not even represent a valid value for that type). If the program attempts to access an uninitialized value, the results are undefined. Many modern compilers try to detect and warn about this problem, but both false positives and false negatives can occur.
Heap memory allocation has to be synchronized with its actual usage in any program to be reused as much as possible. For example, if the only pointer to a heap memory allocation goes out of scope or has its value overwritten before it is deallocated explicitly, then that memory cannot be recovered for later reuse and is essentially lost to the program, a phenomenon known as a memory leak. Conversely, it is possible for memory to be freed, but is referenced subsequently, leading to unpredictable results. Typically, the failure symptoms appear in a portion of the program unrelated to the code that causes the error, making it difficult to diagnose the failure. Such issues are ameliorated in languages with automatic garbage collection.
Libraries
The C programming language uses libraries as its primary method of extension. In C, a library is a set of functions contained within a single "archive" file. Each library typically has a header file, which contains the prototypes of the functions contained within the library that may be used by a program, and declarations of special data types and macro symbols used with these functions. In order for a program to use a library, it must include the library's header file, and the library must be linked with the program, which in many cases requires compiler flags (e.g., -lm
, shorthand for "link the math library").[29]
The most common C library is the C standard library, which is specified by the ISO and ANSI C standards and comes with every C implementation (implementations which target limited environments such as embedded systems may provide only a subset of the standard library). This library supports stream input and output, memory allocation, mathematics, character strings, and time values. Several separate standard headers (for example, stdio.h
) specify the interfaces for these and other standard library facilities.
Another common set of C library functions are those used by applications specifically targeted for Unix and Unix-like systems, especially functions which provide an interface to the kernel. These functions are detailed in various standards such as POSIX and the Single UNIX Specification.
Since many programs have been written in C, there are a wide variety of other libraries available. Libraries are often written in C because C compilers generate efficient object code; programmers then create interfaces to the library so that the routines can be used from higher-level languages like Java, Perl, and Python.[29]
File handling and streams
File input and output (I/O) is not part of the C language itself but instead is handled by libraries (such as the C standard library) and their associated header files (e.g. stdio.h
). File handling is generally implemented through high-level I/O which works through streams. A stream is from this perspective a data flow that is independent of devices, while a file is a concrete device. The high level I/O is done through the association of a stream to a file. In the C standard library, a buffer (a memory area or queue) is temporarily used to store data before it's sent to the final destination. This reduces the time spent waiting for slower devices, for example a hard drive or solid state drive. Low-level I/O functions are not part of the standard C library but are generally part of "bare metal" programming (programming that's independent of any operating system such as most embedded programming). With few exceptions, implementations include low-level I/O.
Language tools
A number of tools have been developed to help C programmers find and fix statements with undefined behavior or possibly erroneous expressions, with greater rigor than that provided by the compiler. The tool lint was the first such, leading to many others.
Automated source code checking and auditing are beneficial in any language, and for C many such tools exist, such as Lint. A common practice is to use Lint to detect questionable code when a program is first written. Once a program passes Lint, it is then compiled using the C compiler. Also, many compilers can optionally warn about syntactically valid constructs that are likely to actually be errors. MISRA C is a proprietary set of guidelines to avoid such questionable code, developed for embedded systems.[37]
There are also compilers, libraries, and operating system level mechanisms for performing actions that are not a standard part of C, such as bounds checking for arrays, detection of buffer overflow, serialization, dynamic memory tracking, and automatic garbage collection.
Tools such as Purify or Valgrind and linking with libraries containing special versions of the memory allocation functions can help uncover runtime errors in memory usage.
Uses
C is widely used for systems programming in implementing operating systems and embedded system applications,[39] because C code, when written for portability, can be used for most purposes, yet when needed, system-specific code can be used to access specific hardware addresses and to perform type punning to match externally imposed interface requirements, with a low run-time demand on system resources.
C can be used for website programming using the Common Gateway Interface (CGI) as a "gateway" for information between the Web application, the server, and the browser.[40] C is often chosen over interpreted languages because of its speed, stability, and near-universal availability.[41]
A consequence of C's wide availability and efficiency is that compilers, libraries and interpreters of other programming languages are often implemented in C. For example, the reference implementations of Python, Perl, Ruby, and PHP are written in C.
C enables programmers to create efficient implementations of algorithms and data structures, because the layer of abstraction from hardware is thin, and its overhead is low, an important criterion for computationally intensive programs. For example, the GNU Multiple Precision Arithmetic Library, the GNU Scientific Library, Mathematica, and MATLAB are completely or partially written in C.
C is sometimes used as an intermediate language by implementations of other languages. This approach may be used for portability or convenience; by using C as an intermediate language, additional machine-specific code generators are not necessary. C has some features, such as line-number preprocessor directives and optional superfluous commas at the end of initializer lists, that support compilation of generated code. However, some of C's shortcomings have prompted the development of other C-based languages specifically designed for use as intermediate languages, such as C--.
C has also been widely used to implement end-user applications. However, such applications can also be written in newer, higher-level languages.
Related languages
C has both directly and indirectly influenced many later languages such as C#, D, Go, Java, JavaScript, Limbo, LPC, Perl, PHP, Python, and Unix's C shell.[42] The most pervasive influence has been syntactical; all of the languages mentioned combine the statement and (more or less recognizably) expression syntax of C with type systems, data models, and/or large-scale program structures that differ from those of C, sometimes radically.
Several C or near-C interpreters exist, including Ch and CINT, which can also be used for scripting.
When object-oriented languages became popular, C++ and Objective-C were two different extensions of C that provided object-oriented capabilities. Both languages were originally implemented as source-to-source compilers; source code was translated into C, and then compiled with a C compiler.[43]
The C++ programming language was devised by Bjarne Stroustrup as an approach to providing object-oriented functionality with a C-like syntax.[44] C++ adds greater typing strength, scoping, and other tools useful in object-oriented programming, and permits generic programming via templates. Nearly a superset of C, C++ now supports most of C, with a few exceptions.
Objective-C was originally a very "thin" layer on top of C, and remains a strict superset of C that permits object-oriented programming using a hybrid dynamic/static typing paradigm. Objective-C derives its syntax from both C and Smalltalk: syntax that involves preprocessing, expressions, function declarations, and function calls is inherited from C, while the syntax for object-oriented features was originally taken from Smalltalk.
In addition to C++ and Objective-C, Ch, Cilk, and Unified Parallel C are nearly supersets of C.
See also
- Compatibility of C and C++
- Comparison of Pascal and C
- Comparison of programming languages
- International Obfuscated C Code Contest
- List of C-based programming languages
- List of C compilers
Notes
- ^ The original example code will compile on most modern compilers that are not in strict standard compliance mode, but it does not fully conform to the requirements of either C89 or C99. In fact, C99 requires that a diagnostic message be produced.
- ^ The
main
function actually has two arguments,int argc
andchar *argv[]
, respectively, which can be used to handle command line arguments. The ISO C standard (section 5.1.2.2.1) requires both forms ofmain
to be supported, which is special treatment not afforded to any other function.
References
- ^ a b Kernighan, Brian W.; Ritchie, Dennis M. (February 1978). The C Programming Language (1st ed.). Englewood Cliffs, NJ: Prentice Hall. ISBN 978-0-13-110163-0.
- ^ Ritchie (1993): "Thompson had made a brief attempt to produce a system coded in an early version of C—before structures—in 1972, but gave up the effort."
- ^ Fruderica (December 13, 2020). "History of C". The cppreference.com. Archived from the original on October 24, 2020. Retrieved October 24, 2020.
- ^ Ritchie (1993): "The scheme of type composition adopted by C owes considerable debt to Algol 68, although it did not, perhaps, emerge in a form that Algol's adherents would approve of."
- ^ a b "Verilog HDL (and C)" (PDF). The Research School of Computer Science at the Australian National University. June 3, 2010. Archived from the original (PDF) on November 6, 2013. Retrieved August 19, 2013.
1980s: ; Verilog first introduced ; Verilog inspired by the C programming language
- ^ a b c d e Ritchie (1993)
- ^ "Programming Language Popularity". 2009. Archived from the original on January 16, 2009. Retrieved January 16, 2009.
- ^ "TIOBE Programming Community Index". 2009. Archived from the original on May 4, 2009. Retrieved May 6, 2009.
- ^ a b "History of C". en.cppreference.com. Archived from the original on May 29, 2018. Retrieved May 28, 2018.
- ^ "TIOBE Index for January 2021". Archived from the original on January 12, 2021. Retrieved January 19, 2021.
- ^ Ritchie, Dennis. "BCPL to B to C". Archived from the original on December 12, 2019. Retrieved September 10, 2019.
- ^ a b Johnson, S. C.; Ritchie, D. M. (1978). "Portability of C Programs and the UNIX System". Bell System Tech. J. 57 (6): 2021–2048. CiteSeerX 10.1.1.138.35. doi:10.1002/j.1538-7305.1978.tb02141.x. S2CID 17510065. (Note: The PDF is an OCR scan of the original, and contains a rendering of "IBM 370" as "IBM 310".)
- ^ McIlroy, M. D. (1987). A Research Unix reader: annotated excerpts from the Programmer's Manual, 1971–1986 (PDF) (Technical report). CSTR. Bell Labs. p. 10. 139. Archived (PDF) from the original on November 11, 2017. Retrieved February 1, 2015.
- ^ "C manual pages". FreeBSD Miscellaneous Information Manual (FreeBSD 13.0 ed.). May 30, 2011. Archived from the original on January 21, 2021. Retrieved January 15, 2021. [1] Archived January 21, 2021, at the Wayback Machine
- ^ Kernighan, Brian W.; Ritchie, Dennis M. (March 1988). The C Programming Language (2nd ed.). Englewood Cliffs, NJ: Prentice Hall. ISBN 978-0-13-110362-7.
- ^ Stroustrup, Bjarne (2002). Sibling rivalry: C and C++ (PDF) (Report). AT&T Labs. Archived (PDF) from the original on August 24, 2014. Retrieved April 14, 2014.
- ^ C Integrity. International Organization for Standardization. March 30, 1995. Archived from the original on July 25, 2018. Retrieved July 24, 2018.
- ^ "JTC1/SC22/WG14 – C". Home page. ISO/IEC. Archived from the original on February 12, 2018. Retrieved June 2, 2011.
- ^ Andrew Binstock (October 12, 2011). "Interview with Herb Sutter". Dr. Dobbs. Archived from the original on August 2, 2013. Retrieved September 7, 2013.
- ^ "TR 18037: Embedded C" (PDF). ISO / IEC. Archived (PDF) from the original on February 25, 2021. Retrieved July 26, 2011.
- ^ Harbison, Samuel P.; Steele, Guy L. (2002). C: A Reference Manual (5th ed.). Englewood Cliffs, NJ: Prentice Hall. ISBN 978-0-13-089592-9. Contains a BNF grammar for C.
- ^ Kernighan & Ritchie (1996), p. 192.
- ^ Kernighan & Ritchie (1978), p. 3.
- ^ "ISO/IEC 9899:201x (ISO C11) Committee Draft" (PDF). Archived (PDF) from the original on December 22, 2017. Retrieved September 16, 2011.
- ^ Kernighan & Ritchie (1996), pp. 192, 259.
- ^ "10 Common Programming Mistakes in C++". Cs.ucr.edu. Archived from the original on October 21, 2008. Retrieved June 26, 2009.
- ^ Schultz, Thomas (2004). C and the 8051 (3rd ed.). Otsego, MI: PageFree Publishing Inc. p. 20. ISBN 978-1-58961-237-2. Archived from the original on July 29, 2020. Retrieved February 10, 2012.
- ^ Kernighan & Ritchie (1978), p. 6.
- ^ a b c d e f g Klemens, Ben (2013). 21st Century C. O'Reilly Media. ISBN 978-1-4493-2714-9.
- ^ Feuer, Alan R.; Gehani, Narain H. (March 1982). "Comparison of the Programming Languages C and Pascal". ACM Computing Surveys. 14 (1): 73–92. doi:10.1145/356869.356872. S2CID 3136859.
- ^ Kernighan & Ritchie (1996), p. 122.
- ^ For example, gcc provides _FORTIFY_SOURCE. "Security Features: Compile Time Buffer Checks (FORTIFY_SOURCE)". fedoraproject.org. Archived from the original on January 7, 2007. Retrieved August 5, 2012.
- ^ เอี่ยมสิริวงศ์, โอภาศ (2016). Programming with C. Bangkok, Thailand: SE-EDUCATION PUBLIC COMPANY LIMITED. pp. 225–230. ISBN 978-616-08-2740-4.
- ^ Raymond, Eric S. (October 11, 1996). The New Hacker's Dictionary (3rd ed.). MIT Press. p. 432. ISBN 978-0-262-68092-9. Archived from the original on November 12, 2012. Retrieved August 5, 2012.
- ^ Summit, Steve. "comp.lang.c Frequently Asked Questions 6.23". Archived from the original on June 15, 2013. Retrieved March 6, 2013.
- ^ Summit, Steve. "comp.lang.c Frequently Asked Questions 7.28". Archived from the original on May 9, 2013. Retrieved March 6, 2013.
- ^ "Man Page for lint (freebsd Section 1)". unix.com. May 24, 2001. Retrieved July 15, 2014.
- ^ McMillan, Robert (August 1, 2013). "Is Java Losing Its Mojo?". Wired. Archived from the original on February 15, 2017. Retrieved March 5, 2017.
- ^ Dale, Nell B.; Weems, Chip (2014). Programming and problem solving with C++ (6th ed.). Burlington, MA: Jones & Bartlett Learning. ISBN 978-1449694289. OCLC 894992484.
- ^ Dr. Dobb's Sourcebook. U.S.A.: Miller Freeman, Inc. November–December 1995.
- ^ "Using C for CGI Programming". linuxjournal.com. March 1, 2005. Archived from the original on February 13, 2010. Retrieved January 4, 2010.
- ^ O'Regan, Gerard (September 24, 2015). Pillars of computing : a compendium of select, pivotal technology firms. ISBN 978-3319214641. OCLC 922324121.
- ^ Rauchwerger, Lawrence (2004). Languages and compilers for parallel computing : 16th international workshop, LCPC 2003, College Station, TX, USA, October 2-4, 2003 : revised papers. Springer. ISBN 978-3540246442. OCLC 57965544.
- ^ Stroustrup, Bjarne (1993). "A History of C++: 1979−1991" (PDF). Archived (PDF) from the original on February 2, 2019. Retrieved June 9, 2011.
Sources
- Ritchie, Dennis M. (March 1993). "The Development of the C Language". ACM SIGPLAN Notices. ACM. 28 (3): 201–208. doi:10.1145/155360.155580.
Ritchie, Dennis M. (1993). "The Development of the C Language". The Second ACM SIGPLAN Conference on History of Programming Languages (HOPL-II). ACM. pp. 201–208. doi:10.1145/154766.155580. ISBN 0-89791-570-4. Retrieved November 4, 2014. - Kernighan, Brian W.; Ritchie, Dennis M. (1996). The C Programming Language (2nd ed.). Prentice Hall. ISBN 7-302-02412-X.
Further reading
- Kernighan, Brian; Ritchie, Dennis (1988). The C Programming Language (2 ed.). Prentice Hall. ISBN 978-0131103627. (archive)
- Plauger, P.J. (1992). The Standard C Library (1 ed.). Prentice Hall. ISBN 978-0131315099. (source)
- Banahan, M.; Brady, D.; Doran, M. (1991). The C Book: Featuring the ANSI C Standard (2 ed.). Addison-Wesley. ISBN 978-0201544336. (free)
- Harbison, Samuel; Steele Jr, Guy (2002). C: A Reference Manual (5 ed.). Pearson. ISBN 978-0130895929. (archive)
- King, K.N. (2008). C Programming: A Modern Approach (2 ed.). W. W. Norton. ISBN 978-0393979503. (archive)
- Griffiths, David; Griffiths, Dawn (2012). Head First C (1 ed.). O'Reilly. ISBN 978-1449399917.
- Perry, Greg; Miller, Dean (2013). C Programming: Absolute Beginner's Guide (3 ed.). Que. ISBN 978-0789751980.
- Deitel, Paul; Deitel, Harvey (2015). C: How to Program (8 ed.). Pearson. ISBN 978-0133976892.
- Gustedt, Jens (2019). Modern C (2 ed.). Manning. ISBN 978-1617295812. (free)
External links
- ISO C Working Group official website
- ISO/IEC 9899, publicly available official C documents, including the C99 Rationale
- "C99 with Technical corrigenda TC1, TC2, and TC3 included" (PDF). (3.61 MB)
- comp.lang.c Frequently Asked Questions
- A History of C, by Dennis Ritchie
- C (programming language)
- American inventions
- C programming language family
- Cross-platform software
- High-level programming languages
- Procedural programming languages
- Structured programming languages
- Programming languages created in 1972
- Programming languages with an ISO standard
- Statically typed programming languages
- Systems programming languages