I. Что такое C
Язык C — универсальный язык программирования, созданный в 1972 году для операционной системы UNIX. Сама ОС и большинство её прикладных программ написаны на C. Однако он не привязан исключительно к UNIX и работает на любом компьютере или системе. Его часто называют «системным языком программирования»: на нём создают операционные системы и компиляторы, а также любые обычные программы.
Предшественником C является язык B (произошедший из BCPL). B и BCPL — языки без типов данных, а в C реализована полноценная система типов данных.
II. Основные особенности
1) Многообразие типов данных
По сравнению с предшественником языком B C предлагает широкий набор типов данных.
Базовые типы: символы, целые числа разных разрядностей, числа с плавающей точкой (десятичные дроби)
Производные типы: указатели, массивы, структуры и объединения. Указатели позволяют напрямую работать с адресами памяти независимо от архитектуры оборудования.
Правила: операторы комбинируются в выражения; любое выражение (присвоение, вызов функции) может выступать как самостоятельная инструкция.
2) Полное управление потоком выполнения программы
Поддерживаются условные переходы (if-else), множественный выбор (switch), два вида циклов (while/for проверяют условие перед выполнением, do — после), досрочный выход из цикла (break) и другие конструкции. Эти операторы потока позволяют реализовать сложную логику программы.
3) Функции
Функция — это набор фиксированных операций, объединённых под одним именем. Достаточно вызвать это имя, и вся последовательность действий выполнится автоматически.
Пример из повседневной жизни:
Предположим, что «испечь хлеб» — это одна функция.
Не нужно каждый раз прописывать весь алгоритм: замес теста → формовка → выпечка в духовке.
Достаточно вызвать «испечь хлеб», и все шаги выполнятся сами — это действие называется вызов функции.
Если нужно испечь хлеб дважды, достаточно дважды вызвать функцию «испечь хлеб».
Перенесём это понятие на язык C:
Функция
printfсодержит полный набор операций для вывода текста на экран. Достаточно написатьprintf("Привет"), не описывая вручную все шаги управления дисплеем компьютера.
Функции могут возвращать данные любого типа: целые числа, структуры, указатели и т.д.
Поддерживается рекурсивный вызов (функция вызывает сама себя). Локальные переменные внутри функции создаются заново при каждом вызове; вкладывать определение одной функции в другую нельзя, но переменные можно объявлять внутри отдельных блоков кода.
Исходный код проекта можно разделить на несколько файлов .c и компилировать их по отдельности.
Переменные имеют три области видимости: только внутри функции, глобальная в пределах одного файла, доступна во всей программе.
4) Препроцессор
Перед запуском компиляции работает препроцессор: массовая замена текста макросами, подключение внешних исходных файлов, условная компиляция отдельных участков кода.
Препроцессор обрабатывает директивы, не входящие в основной синтаксис C, до начала компиляции. Эти дополнительные инструменты упрощают разработку и повышают эффективность в основном за счёт макросов. Мы подробно разберём их в следующих главах.
III. Лаконичный низкоуровневый язык
Термин «низкоуровневый» здесь не имеет негативного оттенка. C работает только с базовыми примитивными элементами компьютера: символами, числовыми значениями и адресами памяти, используя аппаратную арифметическую логику, благодаря чему имеет крайне высокую скорость выполнения.
Другими словами, он позволяет взаимодействовать с глубинными внутренними механизмами компьютера. В отличие от многих других языков C даёт прямой доступ к адресам памяти и даже к аппаратным периферийным устройствам.
Минимальный набор встроенных возможностей; сложные функции реализуются через библиотеки
В языке C нет встроенной поддержки строк, массивов, коллекций, файлового ввода-вывода и консольных операций:
Нельзя выполнить операцию сразу над всей строкой или массивом; только структуры допускают полное копирование значения.
Отсутствует автоматическое управление памятью и сборщик мусора — память разработчик выделяет и освобождает вручную.
Нет ключевых слов read/write для чтения и записи; вывод текста и ввод с клавиатуры реализуются исключительно вызовом библиотечных функций.
Поддерживается только базовый однопоточный поток выполнения, нет встроенных средств многозадачности, параллельных операций, синхронизации и корутин.
Библиотека — это набор готовых функций, написанных на C или других языках. Разработчики могут вызывать эти готовые функции для реализации возможностей, не создавая базовую логику с нуля.
Хотя многие задачи требуют вызова библиотек, сам язык компактный, с небольшим набором правил, поэтому его легко изучить и полностью освоить.
IV. Стандартизация языка C: ANSI C (1988)
Стандартизация стала необходимой, когда C получил широкое распространение: множество разработчиков и компаний создавали собственные вариации языка, из-за чего синтаксис и поведение кода различались на разных платформах. Создан специализированный орган для формирования единых универсальных правил — аналогично стандартам на USB-порты или электрические розетки.
ANSI = American National Standards Institute
Разбор термина
Американский национальный институт стандартов — частная американская организация по стандартизации. Она не создаёт программное обеспечение и не пишет исходный код, но разрабатывает унифицированные спецификации для всех отраслей: промышленности, электроники, вычислительной техники и языков программирования.
Что такое ANSI C?
В 1983 году ANSI сформировала комитет для унификации синтаксиса языка C, в конце 1988 года был опубликован первый официальный стандарт языка, известный как ANSI C (также C89).
V. Дополнение к стандарту ANSI: Стандартная библиотека
Стандарт ввёл унифицированную стандартную библиотеку с кроссплатформенными утилитами для работы с файлами, форматированным вводом-выводом, выделением памяти, обработкой строк и другими задачами; доступ к ней осуществляется через унифицированные заголовочные файлы.
Базовый синтаксис C намеренно минималистичен, он описывает только примитивы: переменные, условные операторы, циклы, функции, указатели. В нём нет встроенных возможностей для вывода текста, чтения с клавиатуры, работы с файлами, математических вычислений и обработки строк.
Спецификация ANSI C определяет универсальный набор утилитарных функций, совместимых со всеми компиляторами на любых операционных системах — этот набор инструментов называется Стандартная библиотека.
Способ подключения: разработчики импортируют заголовочные файлы директивой #include имя_файла.h.
Примеры:
#include <stdio.h> // Библиотека ввода-вывода: printf (вывод текста), scanf (чтение ввода пользователя)
#include <stdlib.h> // Выделение памяти, завершение программы, генерация случайных чисел
#include <string.h> // Копирование и сравнение строк
#include <math.h> // Математические функции sin(), sqrt() и другиеCode language: HTML, XML (xml)
До появления стандарта ANSI функции вывода работали по-разному в UNIX и Windows, из-за чего код выдавал ошибки при переносе между системами. После создания стандартной библиотеки код вида printf("hello") работает одинаково на Windows, Linux и macOS без изменений. Это значительно снизило нагрузку на разработчиков и ускорило глобальное распространение языка C.
На каких языках написана стандартная библиотека?
Большинство возможностей библиотеки реализовано на C, небольшая часть использует ассемблер и другие низкоуровневые языки.
Функции, не взаимодействующие напрямую с оборудованием или операционной системой — например, копирование строк strcpy, математические вычисления, копирование блоков памяти — написаны почти полностью на чистом C.
Операции, требующие прямого взаимодействия с оборудованием или ядром ОС, невозможно реализовать только на C; для этого нужны вспомогательные низкоуровневые языки, в первую очередь ассемблер.
VI. Переносимость и безопасность типов
Один и тот же исходный код можно скомпилировать и запустить на разных операционных системах с минимальными правками или вовсе без них.
После прочтения этого введения у вас должно сформироваться базовое понимание языка C. Если некоторые концепции всё ещё непонятны, не беспокойтесь: сухие текстовые описания сложны для усвоения. В следующих главах мы разберём каждую тему на практических примерах кода для закрепления знаний.