C () — універсальна, процедурна, імперативна мова програмування загального призначення, розроблена у 1972 році Деннісом Рітчі у Bell Telephone Laboratories з метою написання нею операційної системи UNIX.

Хоча С і було розроблено для написання системного програмного забезпечення, наразі вона досить часто використовується для написання прикладного програмного забезпечення.

С імовірно, є найпопулярнішою у світі мовою програмування за кількістю вже написаного нею програмного забезпечення, доступного під вільними ліцензіями коду та кількості програмістів, котрі її знають. Версії компіляторів для мови С існують для багатьох операційних систем та апаратних архітектур. C здійснила великий вплив на інші мови програмування, особливо на C++, яку спочатку проєктували як розширення для С, а також на Java та C#, які запозичили у С синтаксис.

В 2023 році, у категорії найпопулярніших мов програмування серед IT-спеціалістів згідно рейтингу IEEE Spectrum, який охоплював 59 мов програмування, топ-5 виглядав так: Python, Java, C++, C, JavaScriptIEEE Spectrum опублікувала рейтинг найпопулярніших мов програмування 2023 року. // Автор: Артем Житкевич. 30.08.2023.

Філософія С — мінімалістична мова програмування. Серед її головних цілей: можливість прямолінійної реалізації компіляції, використовуючи відносно простий компілятор, забезпечити низькорівневий доступ до оперативної пам'яті, формувати лише кілька інструкцій машинної мови для кожного елементу мови і не вимагати великої динамічної підтримки. У результаті код С придатний для більшості системного програмного забезпечення, яке традиційно писали асемблером.

Попри її низькорівневі можливості, мову проєктували для платформонезалежного програмування. Сумісна зі стандартами та платформонезалежна написана мовою C програма може легко компілюватися на великій кількості апаратних платформ та операційних систем з мінімальними змінами. Мова стала доступною для великої кількості платформ — від вбудованих мікроконтролерів до суперкомп'ютерів.

Мінімалізм Мову С проєктували з розрахунком на те, щоб використовувати у системному програмуванні. Отже, вона не вимагає додаткового часу на виконання перевірок різноманітних умов, які ніколи не відбудуться у правильно написаній програмі, а забезпечує простий, прямий доступ до адреси будь-якого об'єкта (наприклад, карти пам'яті, пристрою контролю регістрів), і її початковий код компілюється у послідовність примітивних машинних операцій.

Б'ярн Страуструп якось написав про неї: «С робить так, щоб вам було легко вистрілити собі в ногу» Іншими словами, С дозволяє здійснення низки операцій, котрі часто є небажаними, а тому чимало помилок у коді не виявляє компілятор, і вони не можуть бути очевидними під час виконання. Якщо під час програмування та підтримки програмного забезпечення не дотримуватися низки суворих правил, пізніше може виникнути немало проблем зі швидкодією, стабільністю та безпекою програмного забезпечення. (Хоча, виною подібних проблем найчастіше є програмісти, бо С сама по собі забезпечує низький рівень захисту).

З часом було розроблено багато утиліт для додаткових перевірок коду на наявність помилок перед компіляцією та під час його роботи. Ніщо не заважає компіляторові здійснювати додаткові перевірки коду, не передбачені специфікацією мови, однак для деякого системного програмного забезпечення вони є неприпустимими, бо зменшують швидкість виконання коду.

У відповідь на критику мови C як сильно типізованої мови Керніган та Рітчі послалися на основу філософії дизайну C: «З усім тим, C зберігає основний принцип, який передбачає, що програмісти добре знають, що вони роблять, і вимагає лише, щоб вони чітко давали компіляторові знати про свої наміри»Brian W. Kernighan and Dennis M. Ritchie: The C Programming Language, 2nd ed., Prentice Hall, 1988, c. 3.

Характеристика

Як і більшість імперативних мов, заснованих на традиції АЛГОЛ, C має можливості для структурного програмування і дозволяє здійснювати рекурсії, у той час, як система статичної типізації даних запобігає виникненню багатьох непередбачуваних операцій. У С увесь виконуваний код міститься у функціях. Параметри функції завжди передаються за значеннями. Передача параметрів за вказівником реалізовується шляхом передачі значення вказівника. Гетерогенні сукупності типів даних (структури) дозволяють пов'язаним типам даних бути об'єднаними і маніпулювати ними, як єдиним цілим.

C також має такі специфічні властивості: змінні можуть бути прихованими у вкладених блоках слабка типізація; наприклад, символи можуть використовуватися, як цілі числа низькорівневий доступ до оперативної пам'яті шляхом перетворення машинних адрес на вказівники вказівники на функції і дані підтримують динамічний поліморфізм індексація масивів як вторинне поняття, визначається у термінах арифметики вказівників стандартизований препроцесор C для макроозначення, включення файлу з джерельним кодом, умовної трансляції тощо. відсутність вбудованих операторів вводу-виводу, потоків, обробки рядків і чисел з рухомою комою. Вся ця функціональність реалізується у бібліотеках виконання. відносно невелика кількість зарезервованих слів (32 у С89, і 37 у C99) Лексичні структури, які нагадують B більше за ALGOL, наприклад: { ... } на відміну від ALGOL'івського begin ... end знак рівності для призначення (копіювання), як це робиться у мові Fortran два знаки рівності використовуються для перевірки рівності (подібно до .EQ. у Fortran'і або одного знаку рівності у BASIC) && та || на відміну від ALGOL'івськихand та or (цим вона семантично відрізняється від бітових операторів & та |). велика кількість арифметичних і логічних операторів, на кшталт +=, ++, &=,……

Відсутня функціональність С має брак наступних можливостей, які є в інших мовах програмування, (хоча далеко не завжди брак деяких можливостей, наявних в якихось мовах, є недоліком): Відсутність нескалярних операцій, на зразок копіювання масивів або рядків. Відсутність автоматичного керування пам'яттю (збір сміття) Відсутня перевірка меж масиву Відсутність напівдинамічних масивів аж до С99 Відсутність синтаксису для масивів, на зразок А..В, котрі використовують, як старіші, так і новіші мови програмування Відсутність вкладених функцій (хоча, ця можливість є з деякими компіляторами, наприклад GCC). Однак знову ж, є суперечливою сама потреба вкладених функцій. Відсутність обробки винятків Відсутність рудиментарної підтримки модульного програмування Відсутність статичного поліморфізму у формі перевантаження функцій або операторів Відсутність підтримки об'єктноорієнтованого програмування Відсутність вбудованої підтримки багатозадачності та роботи з мережами, хоча ці можливості забезпечуються популярними бібліотеками Відсутність стандартних бібліотек для роботи з графікою та деяких інших бібліотек для прикладного програмування

Ці моменти абсолютно не завадили мові бути добре прийнятою спеціалістами. Швидко були створені компілятори для різних платформ. А значною мірою низькорівнева природа мови, надала програмістам можливість якісно контролювати роботу програм, дозволяючи оптимізувати їх під конкретні завдання. Це дозволило кодові ефективно працювати на дуже обмеженому апаратному забезпеченні, такому як вбудовані системи, що сьогодні мають таку високу функціональність завдяки початковому використанню мови С.

Можливості мови підвищуються у спосіб використання сторонніх бібліотек. Більшість об'єктноорієнтованих функцій включають спеціальний вказівник «цей»(this у C++, Java), який посилається на поточний об'єкт. Передаючи цей вказівник як аргумент функції у С, ті ж функціональні можливості можуть бути використані у С. Для прикладу, у C++ можна написати: stack->push(val); у той час, як у С це виглядало б, приміром, так: push(stack, val); де аргумент stack у С є вказівником на структуру (struct), що є еквівалентною цьому вказівнику у С++, який є вказівником на об'єкт.

Синтаксис і семантика

Лексеми

Абетка мови У мові використовуються всі символи латинської абетки, цифри та деякі спеціальні символи.

+Склад абетки мови програмування C Символи латинської абеткиA, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z Цифри0, 1, 2, 3, 4, 5, 6, 7, 8, 9 Спеціальні символи, (кома), ;,. (крапка), +, -, *, ^, & (амперсанд), =, ~ (тильда), !, /, <, >, (, ), {, }, [, ], |, %, ?, ' (апостроф), " (лапки), : (двокрапка), _ (знак підкреслення), \, #

З допустимих символів формуються лексеми — ідентифікатори, ключові слова, літерали (константи), знаки операцій та інші роздільники.

Ключові слова Ключові слова — це слова, значення яких зарезервовано для деяких потреб компілятора. +Ключові слова мови CКлючові словаПризначенняСтандартsizeofОтримання розміру об'єкта чи типа на етапі компіляціїC89typedefЗавдання альтернативного імені типуauto, registerПідказки компілятору щодо місця зберігання зміннихexternВказівка компілятору шукати об'єкт поза поточним файломstaticОголошення статичного об'єктаvoidМаркер відсутності значення; у покажчиках означає довільні даніchar, short,int, longЦілочисленні типи та модифікатори їхнього розміруsigned, unsignedМодифікатори цілих типів, що визначають їх як знакові чи беззнаковіfloat, doubleДійсні типи данихconstМодифікатор, що унеможливлює зміну деякого значенняvolatileВказівка компілятору на можливість зміни значення змінної ззовніstructТип даних — структура з набором полівenumТип даних, що зберігає одне з набору цілих значеньunionТип даних, у якому можна зберігати дані одного з декількох обраних типівdo, for, whileОператори циклуif, elseУмовний операторswitch, case, defaultОператор вибору за цілим параметромbreak, continueОператори переривання циклуgotoОператор безумовного переходуreturnПовернення з функціїinlineОголошення вбудовуваної функціїC99restrictОголошення покажчика, який посилається на блок пам'яті, на який не посилається ніякий інший покажчик_BoolЛогічний тип даних_Complex, _ImaginaryТипи, використовувані у обчисленнях з комплексними числами_AtomicМодифікатор типу, який робить його атомарнимC11_AlignasЯвне завдання вирівнювання в байтах для даних_AlignofОтримання вирівнювання для заданого типу даних на етапі компіляції_GenericВибір одного з набору значень на етапі компіляції, виходячи з контрольованого типу даних_NoreturnВказівка компілятору, що функція неспроможна завершуватися нормально (тобто за допомогою оператора return)_Static_assertВказівка тверджень, які перевіряються на етапі компіляції_Thread_localОголошення локальної для потоку змінної

Типи даних

Історія

Рання розробка Початковий етап розробки Сі відбувся у стінах Bell Labs між 1969 та 1973 роками; Деніс Рітчі стверджує, що найбільш творчим був 1972 рік. Мову було названо «Сі» через те, що багато її можливостей було отримано від раніше створеної мови B.

Існує чимало легенд щодо походження мови Сі, і пов'язаної з нею операційної системи UNIX, серед них: Розробка Сі стала результатом того, що його майбутні автори любили комп'ютерну гру, схожу на популярну гру Asteroids (Астероїди). Вони вже давно грали у неї на головному сервері компанії, який був недостатньо потужним, і повинен був обслуговувати близько ста користувачів. Томпсон і Рітчі вирішилили, що їм не вистачає контролю над космічним кораблем для того, щоб уникати зіткнень з деякими каменями. Тому вони вирішили перенести гру на вільний PDP-7, що стоїть в офісі. Проте цей комп'ютер не мав операційної системи, що змусило їх її написати. Врешті-решт, вони вирішили перенести цю операційну систему ще й на офісний PDP-11, що було дуже важко, оскільки її код був цілком написаний на асемблері. Було винесено пропозицію використати якусь високорівневу портативну мову, щоб можна було легко переносити ОС з одного комп'ютера на іншій. Мова B, яку вони спершу хотіли використати, виявилася позбавленою функціональності, здатної використовувати нові можливості PDP-11. Тому вони й зупинилися на розробці мови С.