
- •Введение
- •Язык программирования Си Элементы языка программирования.
- •Множества символов
- •Буквы и цифры
- •Пробельные символы
- •Знаки пунктуации и специальные символы
- •Операции
- •Константы
- •Целые константы
- •Константы с плавающей точкой
- •Константа-символ
- •Строковые литералы
- •Идентификаторы
- •Ключевые слова
- •Комментарии
- •Лексемы
- •Структура программы
- •Исходная программа
- •Исходные файлы
- •Выполнение программ
- •Время жизни и видимость
- •Классы имен
- •Объявления
- •Спецификаторы типов
- •Область значений величин
- •Деклараторы
- •Деклараторы массивов, функций и указателей
- •Составные деклараторы
- •Объявления переменной
- •Объявление простой переменной
- •Объявление перечисления
- •Объявления структур
- •Объявление совмещений
- •Объявление массива
- •Объявление указателей
- •Объявление функций
- •Объявление классов
- •Классы памяти
- •Объявления переменной на внешнем уровне
- •Объявление переменной на внутреннем уровне
- •Объявление функции на внешнем и внутреннем уровнях
- •Инициализация
- •Базовые типы и типы указателей
- •Составные типы
- •Строковые инициализаторы
- •Объявления типов
- •Типы структур, совмещений и перечислений
- •Объявления typedef
- •Имена типов
- •Выражения и присваивания
- •Введение
- •Операнды
- •Константы
- •Идентификаторы
- •Вызовы функций
- •Индексные выражения
- •Выражение выбора структурного элемента
- •Выражения с операциями
- •Выражения в скобках
- •Type-cast выражения
- •Константные выражения
- •Операции
- •Обычные арифметические преобразования.
- •Операции дополнения
- •Операция адресации и разадресации
- •Операция sizeof
- •Мультипликативные операции
- •Аддитивные операции
- •Операции сдвига
- •Операции отношений
- •Побитовые операции
- •Логические операции
- •Операция последовательного вычисления
- •Условная операция
- •Операции присваивания
- •Lvalue-выражения
- •Унарные инкремент и декремент
- •Простое присваивание
- •Составное присваивание
- •Старшинство и порядок выполнения
- •Побочные эффекты
- •Преобразования типов
- •Преобразование типов при присваивании
- •Преобразования type-cast
- •Преобразования, выполняемые операциями
- •Преобразования при вызовах функций
- •Операторы
- •Введение
- •Оператор break
- •Составной оператор
- •Оператор continue
- •Оператор do
- •Оператор-выражение
- •Оператор for
- •Goto и помеченные операторы
- •Оператор if
- •Оператор null
- •Оператор return
- •Оператор switch
- •Оператор while
- •Функции
- •Введение
- •Определение функции
- •Класс памяти
- •Тип возврата
- •Формальные параметры
- •Тело функции
- •Объявления функции
- •Вызовы функций
- •Фактические аргументы
- •Вызовы с переменным числом аргументов
- •Рекурсивные вызовы
- •Директивы препроцессора и указания компилятору
- •Поименованные константы и макросы
- •Директива # define
- •Директива #undef
- •#Include файлы
- •Условная компиляция
- •Директивы #if, #elif, #else, #endif
- •Директивы #ifdef и #ifndef
- •Управление нумерацией строк
Исходные файлы
Исходные программы могут быть разделены на несколько файлов. Исходный файл Си- это текстовый файл, который содержит часть или всю исходную программу. Он может, например, содержать только некоторые функции, требуемые программе. При компиляции исходной программы каждый из исходных файлов должен быть прокомпилирован отдельно, а затем обработан сборщиком. Отдельные исходные файлы перед компиляцией можно соединять в один большой исходный файл посредством директивы #include.
Исходный файл может содержать любую комбинацию наборов: директив, указаний компилятору, объявлений и определений. Такие объекты, как определения функций или большие структуры данных, не могут разрываться, начинаясь в одном файле и продолжаясь в другом.
Исходный файл не обязательно должен содержать выполняемые операторы. Иногда полезно размещать описания переменных в одном файле с тем, чтобы использовать их путем объявления ссылок из других файлов. В этом случае определения становятся легко доступными для поиска и модификации. Из тех же самых соображений константы и макросы часто организуют в отдельных #include- файлах и включают их, если требуется, в исходные файлы.
Директивы исходного файла относятся только к этому исходному файлу и файлам, включающим его (посредством #include). Кроме того, каждая директива относится только к части файла, которая следует за ней. Если множество директив должно относиться ко всей исходной программе, то все исходные файлы должны содержать эти директивы.
Указания компилятору обычно эффективны для отдельных областей исходного файла. Специфические действия компилятора, задаваемые указаниями, определяются содержанием последних.
Подробнее о действиях отдельных указаний компилятору описано в разделе 8.4 руководства.
В нижеследующем примере исходная программа состоит из двух исходных файлов. Функции main и max представлены в отдельных файлах. Функция main использует функцию max при своем выполнении.
/***********************************************
Sourse file 1 - main function
***********************************************/
#define ONE 1
#define TWO 2
#define THREE 3
extern int max(int, int); /* Function declaration */
int main () /* Function definition */
{
int w = ONE, x = TWO, y = THREE;
int z = 0;
z = max(x,y);
w = max(z,w);
return 0;
}
/*************************************************
Sourse file 2 - max function
*************************************************/
int max(int a, int b) /* Function definition */
{
if ( a > b )
return (a);
else
return (b);
}
В первом исходном файле функция max объявлена без ее определения. Это объявление известно как "forward"- объявление. Определение функции main включает вызов функции max.
Строки, начинающиеся с символа "номер" (#), являются директивами препроцессора. Директивы инструктируют препроцессор о замене в первом исходном файле имен ONE, TWO, THREE на соответствующие им значения. Область действия деректив не распространяется на второй исходный файл.
Второй исходный файл содержит описание функции max. Это определение соответствует вызовам max из первого исходного файла.