- •Введение
- •Язык программирования Си Элементы языка программирования.
- •Множества символов
- •Буквы и цифры
- •Пробельные символы
- •Знаки пунктуации и специальные символы
- •Операции
- •Константы
- •Целые константы
- •Константы с плавающей точкой
- •Константа-символ
- •Строковые литералы
- •Идентификаторы
- •Ключевые слова
- •Комментарии
- •Лексемы
- •Структура программы
- •Исходная программа
- •Исходные файлы
- •Выполнение программ
- •Время жизни и видимость
- •Классы имен
- •Объявления
- •Спецификаторы типов
- •Область значений величин
- •Деклараторы
- •Деклараторы массивов, функций и указателей
- •Составные деклараторы
- •Объявления переменной
- •Объявление простой переменной
- •Объявление перечисления
- •Объявления структур
- •Объявление совмещений
- •Объявление массива
- •Объявление указателей
- •Объявление функций
- •Объявление классов
- •Классы памяти
- •Объявления переменной на внешнем уровне
- •Объявление переменной на внутреннем уровне
- •Объявление функции на внешнем и внутреннем уровнях
- •Инициализация
- •Базовые типы и типы указателей
- •Составные типы
- •Строковые инициализаторы
- •Объявления типов
- •Типы структур, совмещений и перечислений
- •Объявления 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
- •Управление нумерацией строк
Выполнение программ
Каждая программа содержит главную программную функцию. В Си главная программная функция должна быть поименована как main. Функция main служит точкой старта при выполнении программы и обычно управляет выполнением программы, организуя вызовы других функций. Программа обычно завершает выполнение по окончанию функции main, хотя она может завершиться и в других точках, в зависимости от окружающей обстановки.
Исходная программа обычно включает в себя несколько функций, каждая из которых предназначена для выполнения определенного задания. Функция main может вызывать эти функции с тем, чтобы выполнить то или иное задание. Функция возвращает управление при выполнении оператора return или по окончанию самой функции (выход на конец функции).
Все функции, включая функцию main, могут быть объявлены с параметрами. Вызываемые функции получают значения параметров из вызывающих функций. Значения параметров функции main могут быть переданы из внешнего окружения. Например, они могут быть переданы из командной строки.
Соглашение Си требует, чтобы первые два параметра функции main назывались argc и argv.
Параметр argc определяет общее число аргументов, передаваемых функции main. Параметр argv объявляется как массив указателей, каждый элемент которого ссылается на строковое представление аргумента, передаваемого функции main. Третий параметр функции main (если он есть) традиционно задается с именем envp. Однако Си не требует этого имени. Параметр envp- это указатель на массив указателей строковых величин, которые определяют окружение, в котором выполняется программа.
Операционная система поддерживает передачу значений для argc, argv, и envp параметров, а пользователь поддерживает задание значений фактических параметров для функции main. Соглашение о передаче параметров в большей степени определяется операционной системой, чем самим языком Си.
Формальные параметры функции должны быть объявлены во время описания функции.
Время жизни и видимость
Концепции "Время жизни" и "Видимость" являются очень важными для понимания структуры программ на Си. Время жизни переменной может быть или "глобальным" или "локальным". Объект с глобальным временем жизни характеризуется определенной памятью и значением на протяжении всей жизни программы. Объект с локальным временем жизни захватывает новую память при каждом входе в "блок", в котором он определен или объявлен. Когда блок завершается, локальный объект пропадает, а следовательно пропадает его значение. Определение блоков описывается ниже.
Объект считается "видимым" в блоке или исходном файле, если известны тип и имя объекта в блоке или исходном файле. Объект может быть "глобально видимым", когда имеется в виду, что он видим или может быть объявлен видимым на протяжении всего исходного файла, образующего программу. Видимость между исходными файлами рассматривается в разделе 3.5 Классы имен.
Блок- это составной оператор. Составные операторы состоят из объявлений и операторов, как это описано в разделе 6.2 "Составной оператор". Блоки могут быть вложенными.
Структура функции представляет собой совокупность составных операторов. Таким образом, функции имеют блочную структуру, блоки, в свою очередь, могут содержать внутри себя другие блоки.
Объявления и определения внутри блоков находятся на "внутреннем уровне". Объявления и определения вне блоков находятся на "внешнем уровне". Переменные и функции могут быть объявлены как на внешнем уровне, так и на внутреннем. Переменные также могут быть определены на внутреннем и на внешнем уровне, а функции определяются только на внешнем уровне.
Все функции имеют глобальное время жизни, невзирая на то, где они объявлены. Переменные, объявленные на внешнем уровне, всегда имеют глобальное время жизни. Переменные, объявленные на внутреннем уровне, всегда имеют локальное время жизни, однако, классы памяти, специфицированные как static и extern, могут быть использованы для объявления глобальных переменных или ссылок на них внутри блока.
Переменные, объявленные или определенные на внешнем уровне, видимы от точки, в которой они объявлялись или определялись, до конца файла. Эти переменные можно сделать видимыми в других исходных файлах путем их объявления, как описано в разделе 3.5 "Классы памяти".
Однако,переменные, заданные классом памяти "static" на внешнем уровне, видимы только внутри исходного файла, в котором они определены.
В общем случае, переменные, объявленные или определенные на внутреннем уровне, видимы от точки, в которой они объявлены или определены, до конца блока, в котором представлены объявления или определения. Эти переменные называются локальными. Если переменная, объявленная внутри блока, имеет то же самое имя, как и переменная, объявленная на внешнем уровне, то определение переменной в блоке заменяет (имеет предпочтение) определение внешнего уровня на протяжении блока. Видимость переменной внешнего уровня восстанавливается при завершении блока.
Блочная видимость может вкладываться. Это значит, что блок, вложенный внутрь другого блока, может содержать объявления, которые переопределяют переменные, объявленные во внешнем блоке. Переопределение переменной имеет силу во внутреннем блоке, но первоначальное определение восстанавливается, когда управление возвращается внешнему блоку. Переменные из внешних блоков видимы внутри всех внутренних блоков до тех пор, пока они не переопределены во внутреннем блоке.
Функции класса памяти static видимы только в исходном файле, в котором они определены. Все другие функции являются глобально видимыми.
В Таблица 3-8 подытожены основные факторы, которые определяют время жизни и видимость функций и переменных. В таблице, однако, не рассматриваются абсолютно все случаи. Более подробная информация дана в разделе 4.5 "Классы памяти".
Уровень |
Объект |
Спецификатор класса памяти |
Время жизни |
Видимость |
Внешний |
Переменная объявление |
static |
Глобальное |
Ограничивается отдельным исходым файлом |
Переменная объявление |
extern |
Глобальное |
Остаток исходного файла | |
Функция объявление или определение |
static |
Глобальное |
Ограничивается отдельным исходным файлом | |
Функция объявление или определение |
extern |
Глобальное |
Остаток исходного файла | |
Внутренний |
Переменная обявление или определение |
extern или static |
Глобальное |
Блок |
Переменная обявление или определение |
auto или register |
Локальное |
Блок |
Таблица 3‑8 Время жизни и видимость
В следующем примере программы иллюстрируются блоки, вложения и видимость переменных.
/* i defined at external level */
int i = 1;
/* main function defined at external level */
main ()
{
/* prints 1 (value of external level i) */
printf("%d\n", i);
/* first nested block */
{
/* i and j defined at internal level */
int i = 2, j = 3;
/* prints 2, 3 */
printf("%d\n%d\n", i, j);
/* second nested block */
{
/* i is redefined */
int i = 0;
/* prints 0, 3 */
printf("%d\n%d\n", i, j);
/* end of second nested block */
}
/* prints 2 (outer definition restored) */
printf("%d\n", i);
/* end of first nested block */
}
/* prints 1 (external level definition restored */
printf("%d\n", i);
}
В этом примере показано 4 уровня видимости: самый внешний уровень и три уровня, образованных блоками. Предполагается, что функция printf определена где- нибудь в другом месте программы. Функция main печатает значения 1, 2, 3, 0, 3, 2, 1.