Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

2 Commits
 
 
 
 
 
 
 
 

Repository files navigation

Программирование на С часть 2

Группа: 25.Б43-мм

Telegram: imaxde.t.me


Язык C — это компилируемый процедурный язык программирования общего назначения, разработанный в начале 1970-х годов в исследовательском центре Bell Labs, главным образом Dennis Ritchie. Он возник как инструмент для реализации операционной системы Unix, и именно поэтому его устройство тесно связано с архитектурой вычислительных систем и принципами работы операционных систем. В отличие от более поздних языков высокого уровня, C не стремится скрывать устройство машины; наоборот, его модель вычислений практически напрямую отражает модель памяти и исполнения программы на процессоре. Именно поэтому C часто называют языком среднего уровня: он сочетает синтаксис, характерный для высокоуровневых языков, с возможностью прямого управления памятью, адресами и битовыми представлениями данных.

Формально язык C основан на императивной парадигме программирования. Императивная парадигма — это подход, при котором программа описывает последовательность команд, изменяющих состояние вычислительной системы. Состояние здесь означает совокупность значений всех переменных и содержимого памяти в определённый момент времени. Команда или инструкция изменяет это состояние, например присваивая новое значение переменной или записывая данные по адресу памяти. Такая модель напрямую соответствует архитектуре большинства процессоров, где выполнение программы представляет собой последовательное исполнение машинных инструкций.

Центральным понятием языка C является объект. Объект — это область памяти, имеющая определённый тип, размер и время жизни. Тип определяет интерпретацию битов, находящихся в этой области памяти. Например, тип int интерпретирует определённое количество битов как целое число, тогда как тип float интерпретирует те же биты согласно стандарту представления чисел с плавающей точкой IEEE 754. Важно понимать, что тип не изменяет сами биты памяти; он определяет правила их чтения и обработки компилятором и программой.

Память в C представляется как линейное адресное пространство. Адрес — это числовое значение, идентифицирующее конкретную ячейку памяти. Ячейка памяти — минимальная адресуемая единица памяти, обычно один байт, где байт — это группа из восьми битов, а бит — это элементарная единица информации, принимающая значение 0 или 1. Когда программа объявляет переменную, компилятор резервирует некоторую последовательность байтов в памяти и связывает её с именем переменной. Однако язык C позволяет обращаться к этим байтам не только по имени переменной, но и напрямую по их адресу.

Для этого используется механизм указателей. Указатель — это переменная, значением которой является адрес другой области памяти. Если переменная содержит данные, например целое число, то указатель содержит адрес, по которому эти данные расположены. Операция разыменования указателя означает доступ к данным по этому адресу. Таким образом, указатели позволяют программе оперировать не только значениями, но и местоположением этих значений в памяти. Именно благодаря указателям C предоставляет мощные возможности низкоуровневого управления памятью, однако эта же особенность делает язык потенциально опасным: ошибка в адресе может привести к повреждению памяти или неопределённому поведению программы.

Неопределённое поведение — это термин стандарта языка, обозначающий ситуацию, в которой спецификация языка не предписывает никакого конкретного результата выполнения программы. Это не означает случайность; это означает отсутствие гарантий. Компилятор может генерировать любой код, и программа может вести себя непредсказуемо. Примером является обращение к памяти за пределами массива. Массив — это непрерывная последовательность объектов одного типа, размещённых подряд в памяти. Если программа пытается читать или записывать элемент за пределами выделенного диапазона, стандарт языка не определяет последствия.

Важной характеристикой C является минимализм его абстракций. Абстракция — это механизм представления сложной системы через упрощённую модель, скрывающую детали реализации. В C абстракций относительно мало: функции, структуры, объединения, перечисления и указатели. Структура — это составной тип данных, объединяющий несколько объектов различных типов в одну логическую единицу. Объединение отличается тем, что все его поля разделяют одну и ту же область памяти, поэтому в один момент времени корректно интерпретируется только одно из них. Перечисление представляет набор именованных целочисленных констант.

Функции в C являются основным механизмом организации кода. Функция — это именованный блок инструкций, который может принимать аргументы и возвращать значение. Внутренне вызов функции связан с механизмом стека вызовов. Стек — это структура данных типа LIFO, где последний помещённый элемент извлекается первым. При вызове функции в стек помещается информация о текущем состоянии программы: адрес возврата, аргументы и локальные переменные. После завершения функции эта информация удаляется, и управление возвращается к месту вызова.

Компиляция программы на C включает несколько этапов. Сначала выполняется препроцессор. Препроцессор — это текстовый трансформатор, который обрабатывает директивы, начинающиеся символом #. Например, директива #include вставляет содержимое другого файла, а #define создаёт макрос. Макрос — это правило текстовой подстановки, выполняемое до компиляции. Важно, что препроцессор не понимает синтаксис языка; он оперирует только текстом.

После препроцессора исходный код передаётся компилятору. Компилятор анализирует синтаксис программы и преобразует её в машинный код или промежуточное представление. Машинный код — это последовательность инструкций, непосредственно исполняемых процессором. Эти инструкции зависят от архитектуры процессора, например x86 или ARM. В результате компиляции получается объектный файл. Объектный файл содержит машинный код, но ещё не является полной программой, потому что может зависеть от других объектных файлов и библиотек.

На следующем этапе работает компоновщик. Компоновщик объединяет объектные файлы и библиотеки в единый исполняемый файл. Библиотека — это набор заранее скомпилированных функций, которые можно использовать в программе. В стандартной библиотеке C присутствуют функции для работы с вводом-выводом, строками, памятью и математическими операциями.

Одной из причин долгой жизни языка C является его близость к аппаратному уровню и высокая переносимость. Переносимость означает возможность компилировать одну и ту же программу на разных аппаратных платформах с минимальными изменениями. Это достигается благодаря тому, что стандарт языка определяет поведение программ на абстрактной машине C — формальной модели исполнения, которая не привязана к конкретному процессору. Компилятор реализует соответствие между этой абстрактной машиной и реальным оборудованием.

Однако переносимость в C не абсолютна. Некоторые аспекты языка зависят от реализации. Например, размер типа int или порядок байтов в памяти. Порядок байтов называется эндianness. Endianness — это правило расположения байтов многобайтового числа в памяти. В системе little-endian младший байт числа хранится по меньшему адресу, а в системе big-endian — наоборот.

Таким образом, язык C представляет собой компромисс между контролем над аппаратурой и абстракцией программирования. Он предоставляет программисту прямой доступ к памяти и структурам данных на низком уровне, при этом сохраняя достаточно высокий уровень выразительности, чтобы писать большие и сложные программы. Именно по этой причине C стал фундаментом огромного количества программных систем: операционных систем, компиляторов, сетевых стеков, баз данных и встроенного программного обеспечения. Несмотря на появление более современных языков, C продолжает оставаться одним из ключевых инструментов системного программирования, во многом потому, что его модель вычислений практически совпадает с тем, как на самом деле работает компьютер.

About

Программирование на C | Домашки | Подписаться

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors