- •Введение
- •Соглашения о нотации
- •Часть 1 описание языка си элементы языка си
- •Алфавит
- •Буквы и цифры
- •Пробельные символы
- •Разделители
- •Специальные символы
- •Операции
- •Константы
- •Целые константы
- •Константы с плавающей точкой
- •Символьные константы
- •Символьные строки
- •Идентификаторы
- •Ключевые слова
- •Комментарии
- •Структура программы Исходная программа
- •Исходные файлы
- •Выполнение программы
- •Время жизни и область действия
- •Пространства имен
- •Объявления
- •Базовые типы данных
- •Спецификации типов и их сокращения
- •Области значений
- •Размер памяти и область значений типов
- •Описатели Синтаксис описателей
- •Интерпретация составных описателей
- •Описатели с модификаторами
- •Интерпретация описателей с модификаторами
- •Модификаторы const и volatile
- •Модификаторы cdecl и pascal
- •Модификатор pascal
- •Модификаторы near, far, huge
- •Модификатор interrupt
- •Объявление переменных
- •Объявление простой переменной
- •Объявление переменной перечислимого типа
- •Объявление структуры
- •Битовые поля
- •Объявление объединения
- •Объявление массива
- •Объявление указателя
- •Объявление функции (прототип)
- •Список типов аргументов
- •Классы памяти
- •Объявление переменной на внешнем уровне
- •Объявление переменной на внутреннем уровне
- •Инициализация
- •Базовые типы и указатели
- •Составные типы
- •Строковые инициализаторы
- •Объявление типа
- •Объявление тега
- •Объявление typedef
- •Абстрактные имена типов
- •Выражения Введение
- •Операнды
- •Идентификаторы
- •Константы
- •Символьные строки
- •Вызовы функций
- •Индексные выражения
- •Доступ к многомерному массиву
- •Выбор элемента
- •Операции и l-выражения
- •Скобочные выражения
- •Константные выражения
- •Операции
- •Преобразования по умолчанию
- •Унарные операции Унарный минус (-)
- •Логическое отрицание (!)
- •Адресация "&"
- •Косвенная адресация "*"
- •Операция sizeof
- •Мультипликативные операции
- •Умножение (*)
- •Деление (/)
- •Остаток от деления (%)
- •Аддитивные операции
- •Вычитание (-)
- •Адресная арифметика
- •Операции сдвига
- •Операции отношения
- •Поразрядные операции
- •Логические операции
- •Логическое и (&&)
- •Логическое или (||)
- •Операция последовательного вычисления
- •Условная операция
- •Операции присваивания
- •Операции инкремента и декремента
- •Простое присваивание
- •Составное присваивание
- •Приоритет и порядок выполнения
- •Приоритет и ассоциативность операций в языке Си
- •Побочные эффекты
- •Преобразования типов
- •Преобразования типов при присваивании
- •Преобразование знаковых целых типов
- •Преобразование беззнаковых целых типов
- •Преобразование беззнаковых целых типов
- •Преобразование указателей
- •Преобразования других типов
- •Явные преобразования типов
- •Преобразования типов при вызовах функций
- •Операторы Введение
- •Пустой оператор
- •Составной оператор
- •Оператор-выражение
- •Условный оператор if
- •Вложенность
- •Оператор пошагового цикла for
- •Оператор цикла с предусловием while
- •Оператор цикла с постусловием do
- •Оператор продолжения continue
- •Оператор-переключатель switch
- •Оператор разрыва break
- •Оператор перехода goto
- •Оператор возврата return
- •Функции Введение
- •Определение функции
- •Класс памяти
- •Модификаторы типа функции
- •Типы возвращаемых значений
- •Формальные параметры
- •Тело функции
- •Объявление функции
- •Вызов функции
- •Фактические аргументы
- •Вызов функции с переменным числом аргументов
- •Рекурсивные вызовы
- •Директивы препроцессора и указания компилятору Введение
- •Именованные константы и макроопределения
- •Директива #define
- •Склейка лексем и преобразование аргументов макроопределений
- •Директива #undef
- •Включение файлов
- •Условная компиляция
- •Директивы #if, #elif, #else, #endif
- •Директивы #ifdef и #ifndef
- •Управление нумерацией строк
- •Директива обработки ошибок
- •Пустая директива
- •Указания компилятору языка Си
- •Псевдопеременные
- •Модели памяти
- •Виды моделей
- •Малая модель
- •Средняя модель
- •Компактная модель
- •Большая модель
- •Максимальная модель
- •Модификация стандартной модели памяти
- •Объявление данных
- •Объявление функций
- •Модели памяти сп тс
- •Часть II
- •Краткое описание библиотеки
- •Работа с областями памяти и строками
- •Определение класса символов и преобразование символов
- •Форматные преобразования данных
- •Работа с каталогами файловой системы
- •Операции над файлами
- •Ввод и вывод
- •Функции вода/вывода высокого уровня
- •Высокоуровневое открытие файлов
- •Стандартные потоки: stdin, stdout, stdeir, stdaux, stdprn.
- •Управление буферизацией потоков
- •Закрытие потоков
- •Чтение и запись данных
- •Обнаружение ошибок
- •Функции вода/вывода нижнего уровня
- •Открытие файлов
- •9.6.2.2. Переопределение дескрипторов (handle)
- •Чтение и запись данных
- •Закрытие файлов
- •Функции вода/вывода с консольного терминала и порта
- •Математические функции
- •Динамическое распределение памяти
- •Использование системных вызовов операционной системы ms-dos
- •Управление процессами
- •Поиск и сортировка
- •Функции работы со временем
- •Функции работы со списком аргументов
- •Другие функции
Доступ к многомерному массиву
Индексное выражение может иметь более одного индекса. Синтаксис такого выражения следующий:
<выражение1 >[<выражение2 >][<выражение3 >]…
Индексное выражение интерпретируется слева направо. Сначала вычисляется самое левое индексное выражение — <выражение1 >[<выражение2 >]. С адресом, полученным в результате сложения <выражения1 > и <выражения2 >, складывается (по правилам сложения указателя и целого) <выражение3 > и т. д. <ВыражениеЗ > и последующие <выражения > имеют целый тип. Операция косвенной адресации осуществляется после вычисления последнего индексного выражения. Однако, если значение последнего указателя адресует значение типа массив, операция косвенной адресации не применяется (смотри третий и четвертый примеры ниже).
Выражения с несколькими индексами ссылаются на элементы многомерных массивов. Многомерный массив в языке Си понимается как массив, элементами которого являются массивы. Например, элементами трехмерного массива являются двумерные массивы.
Примеры:
int рrор[3][4][6];
int i, *ip, (*ipp)[6];
i = prop[0][0][1]; /* пример 1 */
i = prop[2][1][3]; /* пример 2 */
ip = prop[2][1]; /* пример 3 */
ipp = prop[2]; /* пример 4 */
Массив с именем prop содержит 3 элемента, каждый из которых является двумерным массивом значений типа int . В примере 1 показано, каким образом получить доступ ко второму элементу (типа int ) массива prop . Поскольку массив заполняется построчно, последний индекс меняется наиболее быстро. Выражение prop [0][0][2] ссылается на следующий (третий) элемент массива и т. д.
Во втором примере выражение вычисляется следующим образом:
1) Первый индекс 2 умножается на размер двумерного массива (4 на 6), затем на размер типа int и прибавляется к значению указателя prop . Результат будет указывать на третий двумерный массив (размером 4 на 6 элементов) в трехмерном массиве prop .
2) Второй индекс 1 умножается на размер 6-элементного массива типа int и прибавляется к адресу, представляемому выражением prop [2].
3) Каждый элемент 6-элементного массива имеет тип int , поэтому индекс 3 умножается на размер типа int и прибавляется к адресу, представляемому выражением prop [2][1]. Результирующий указатель адресует четвертый элемент массива из шести элементов.
4) На последнем шаге вычисления выражения рrор [2][1][3] выполняется косвенная адресация по указателю. Результатом является элемент типа int , расположенный по вычисленному адресу.
В примерах 3 и 4 представлены случаи, когда косвенная адресация не применяется. В примере 3 выражение prop [2][1] представляет указатель на массив из шести элементов в трехмерном массиве prop . Поскольку значение указателя адресует массив, операция косвенной адресации не применяется. Аналогично, результатом вычисления выражения prop [2] в примере 4 является значение указателя, адресующего двумерный массив.
Выбор элемента
Синтаксис:
< выражение > .< идентификатор >
< выражение > -> <идентификатор >
Выражение выбора элемента позволяет получить доступ к элементу структуры или объединения. Выражение имеет значение и тип выбранного элемента.
В первой синтаксической форме <выражение > представляет значение типа struct или union , а идентификатор именует элемент специфицированной структуры или объединения. Во второй синтаксической форме <выражение > представляет указатель на структуру или объединение, а идентификатор именует элемент специфицированной структуры.
Обе синтаксические формы выражения выбора элемента дают одинаковый результат. Запись
<выражение > -> <идентификатор >
для случая, когда <выражение > имеет тип указатель, эквивалентна записи
(*< выражение > ).< идентификатор >
однако более наглядна.
Примеры:
struct pair {
int a;
inl b;
struct pair *sp;
} item, list[10];
item.sp = &item; /* пример 1 */
(item.sp)->a = 24; /* пример 2 */
list[8].b = 12; /* пример 3 */
В первом примере адрес структуры Нет присваивается элементу sp этой же структуры. В результате структура item содержит указатель на себя.
Во втором примере используется адресное выражение item.sp с операцией выбора элемента ->, присваивающее значение элементу а . Учитывая результат примера 1, пример 2 эквивалентен записи
item.a = 24;
В третьем примере показано, каким образом в массиве структур осуществить доступ к элементу отдельной структуры.