- •Введение
- •Язык программирования Си Элементы языка программирования.
- •Множества символов
- •Буквы и цифры
- •Пробельные символы
- •Знаки пунктуации и специальные символы
- •Операции
- •Константы
- •Целые константы
- •Константы с плавающей точкой
- •Константа-символ
- •Строковые литералы
- •Идентификаторы
- •Ключевые слова
- •Комментарии
- •Лексемы
- •Структура программы
- •Исходная программа
- •Исходные файлы
- •Выполнение программ
- •Время жизни и видимость
- •Классы имен
- •Объявления
- •Спецификаторы типов
- •Область значений величин
- •Деклараторы
- •Деклараторы массивов, функций и указателей
- •Составные деклараторы
- •Объявления переменной
- •Объявление простой переменной
- •Объявление перечисления
- •Объявления структур
- •Объявление совмещений
- •Объявление массива
- •Объявление указателей
- •Объявление функций
- •Объявление классов
- •Классы памяти
- •Объявления переменной на внешнем уровне
- •Объявление переменной на внутреннем уровне
- •Объявление функции на внешнем и внутреннем уровнях
- •Инициализация
- •Базовые типы и типы указателей
- •Составные типы
- •Строковые инициализаторы
- •Объявления типов
- •Типы структур, совмещений и перечислений
- •Объявления 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
- •Управление нумерацией строк
Операции дополнения
Арифметическое отрицание "-".
Операция арифметического отрицания "-" вырабатывает отрицание своего операнда. Операнд должен быть целой или плавающей величиной. При выполнении операции осуществляются обычные арифметические преобразования (смотри предыдущий раздел).
Двоичное дополнение "~"
Операция двоичного дополнения вырабатывает двоичное дополнение своего операнда. Операнд должен быть целого типа. Обычные арифметические преобразования осуществляются. Результат имеет тип преобразованного операнда.
Логическое не "!"
Операция логического не "!" вырабатывает значение 0, если операнд есть true и значение 1, если операнд есть false. Результат имеет тип int. Операнд должен быть целого, плавающего или адресного типа.
Примеры :
/ * ... example 1 ... * /
short x = 987;
x = - x;
/ * ... example 2 ... */
unsigned short y = 0xaaaa;
y = ~y;
/* ... example 3 ...*/
if (!(x < y));
В первом примере новое значение х является отрицанием 987, т.е. -987.
Во втором примере переменной y присваивается новое значение, которое является дополнением беззнаковой величины 0xaaaa, т.е. 0x5555.
В третьем примере если x больше или равно y, то результат выражения равен 1 (true). Если x меньше y, то результат равен 0 (false).
Операция адресации и разадресации
Разадресация "*"
Разадресуемая величина доступна операции разадресации через указатель. Операнд должен быть указателем величины. Результатом операции является величина, на которую указывает операнд. Типом результата является тип, адресуемый указателем. Если значение указателя равно нулю, то программа будет принудительно завершена.
Адресация "&"
Операция адресации "&" вырабатывает адрес своего операнда. Операндом может быть любая величина, которая допустима в качестве любого операнда операции присваивания. (Операция присваивания обсуждается в разделе 5.4.). Результат операции адресации является указателем на операнд. Тип, адресуемый указателем, является типом операнда.
Операция адресации не может применяться к битовым полям памяти структур, она не может быть применена также к идентификаторам класса памяти register.
Примеры
int *pa, x;
int a[20];
double d;
pa = &a[5]; /* Example 1 */
x = *pa; /* Example 2 */
if (x == *&x) /* Example 3 */
printf("True\n");
d = *(double*)(&x); /* Example 4 */
В первом примере операция адресации вырабатывает адрес шестого элемента массива a. Результат записывается в адресную переменную (указатель) pa.
Во втором примере использууется операция разадресации для доступа к величине типа int, адрес которой запомнен в pa. Значение результата присваивается целочисленной переменной x.
В третьем примере будет печататься слово True. Здесь показано, что результат применения операции разадресации к адресу x это то же самое, что x.
В четвертом примере показано полезное приложение правил, рассмотренных в примере 3. Адрес x преобразуется cast- операцией к указателю на double. Затем применяется операция разадресации и результатом выражения является величина типа double.
Операция sizeof
Операция sizeof определяет размер памяти, который соответствует идентификатору или типу. Выражение sizeof имеет форму:
sizeof(<name>),
где <name> - или идентификатор или имя типа. Имя типа не может быть void. Значением выражения sizeof является размер памяти в байтах, соответствующий поименованному идентификатору или типу.
Когда операция sizeof применяется к идентификатору массива, то результатом является размер всего массива в байтах, а не размер указателя, соответствующего идентификатору массива.
Когда операция sizeof применяется к тегу типа структуры или совмещения или к идентификатору, имеющему тип структуры или совмещения, то результатом является фактический размер в байтах структуры или совмещения, который может включать участки пространства, используемые для выравнивания элементов структуры или совмещения на границы слова физической памяти. Таким образом, этот результа может не соответствовать размеру, вычисленному путем сложения размеров элементов структуры.
Пример
buffer = calloc(100, sizeof(int));
Используя sizeof- операцию, можно избежать машинной зависимости, специфицируя в программе машинно-зависимые размеры данных. В примере используется операция sizeof, чтобы передать размер int, зависящий от машины, как аргумент функции, поименованной calloc. Значение, возвращаемое функцией, запоминается в буфер.