
- •Структура программы на языке Си. Этапы выполнения программы
- •1.1. Алфавит языка Си
- •1.2. Лексемы
- •1.3. Идентификаторы и ключевые слова
- •1.4. Знаки операций
- •1.5. Литералы (константы)
- •1.6. Комментарии
- •1.7. Общая структура программы на языке Си.
- •1.8. Функциональная и модульная декомпозиции
- •1.9. Этапы обработки программы.
- •1.10. Роль препроцессора.
- •1.11. Ошибки
- •2. Переменные и константы. Типы данных
- •2.1. Основные типы данных
- •2.2. Декларация (объявление) объектов
- •2.3. Константы в программах
- •2.4. Целочисленные константы
- •2.5. Константы вещественного типа
- •2.6. Символьные константы
- •2.7. Строковые константы
- •3. Обзор операций
- •3.1. Операции, выражения
- •3.2. Арифметические операции
- •3.3. Операции сравнения
- •3.4. Логические операции
- •4. Операции (продолжение).
- •4.1. Операция присваивания
- •Примеры недопустимых выражений:
- •4.2. Сокращенная запись операции присваивания
- •4.3. Преобразование типов операндов бинарных операций
- •4.4. Преобразование типов при присваивании.
- •4.5. Операция явного приведения типа
- •4.6. Операция «,» (запятая)
- •5. Стандартная библиотека языка Си
- •5.1. Стандартные математические функции
- •5.2. Потоковый ввод-вывод
- •5.3. Консольные функции вывода данных на экран
- •5.4. Консольные функции ввода информации
- •5.5. Ввод-вывод в оконных приложениях.
- •Советы по программированию
- •6. Операторы языка с.
- •7. Составление разветвляющихся алгоритмов
- •7.1. Условные операторы
- •If (выражение) оператор;
- •If (выражение) оператор 1 ;
- •If (выражение 1) оператор 1;
- •If (выражение 2) оператор 2;
- •If (выражение 3) оператор 3;
- •7.2. Оператор выбора альтернатив (переключатель)
- •7.3. Условная операция «? :»
- •8. Составление циклических алгоритмов
- •8.1. Оператор с предусловием while
- •8.2. Оператор цикла с постусловием do – while
- •8.3. Оператор цикла с предусловием и коррекцией for
- •8.4. Вложенные циклы.
- •9. Операторы передачи управления.
- •9.1. Оператор безусловного перехода goto
- •9.2. Операторы continue, break и return
- •10. Массивы
- •10.1. Одномерные массивы
- •10.2. Примеры алгоритмов, использующих одномерные массивы.
- •10.3. Многомерные массивы
- •10.4. Примеры алгоритмов, использующих двумерные массивы.
- •10.5. Компонента StringGrid
- •11. Размещение данных и программ в памяти пэвм
- •11.1. Общие понятия.
- •11.2. Кодирование целых чисел.
- •11.3. Кодирование вещественных чисел.
- •11.4. Кодирование символов.
- •Примеры кодов символов:
- •Стандартная часть таблицы символов (ascii)
- •Дополнительная часть таблицы символов
- •11.5. Операция sizeof
- •11.6. Побитовые логические операции. Операции над битами
- •11.7. Кодирование программы.
- •11.8. Регистры
- •12.1. Строки как нуль-терминированные массивы char.
- •12.2. Русификация консольных приложений.
- •12.3. Строки как переменные типа AnsiString.
- •12.4. Преобразования строковых типов.
- •12.5. Тип String в консольных приложениях.
- •13. Функции пользователя и классы памяти.
- •13.1. Сущность и предназначение функций.
- •13.2. Определение и вызов функции.
- •13.3. Прототип функции.
- •13.4. Область видимости.
- •13.5. Классы памяти объектов в языке Cи.
- •13.6. Разбиение программы на модули.
- •14. Структуры и объединения
- •14.1. Понятие структуры
- •14.2. Декларация структурного типа данных
- •14.3. Объявление структурных переменных
- •14.4. Обращение к полям структуры
- •14.5. Операции со структурой как единым целым
- •14.6. Вложенные структуры
- •14.7. Массивы структур
- •14.8. Размещение структурных переменных в памяти
- •14.9. Битовые поля
- •14.10. Объединения
- •15. Генерация псевдослучайных чисел.
- •16. Файлы в языке с
- •16.1. Типы файлов.
- •16.2. Открытие файла
- •16.3. Закрытие файла
- •16.4. Запись - чтение информации
- •А) Посимвольный ввод-вывод
- •Б) Построчный и форматированный ввод-вывод
- •В) Блоковый ввод-вывод
- •Int fflush(file *stream);
- •16.5. Текстовые файлы
- •16.6. Перенаправление стандартного ввода-вывода
- •16.7. Бинарные файлы
- •16.8. Дополнительные полезные функции
- •16.9. Простейший пример создания собственной базы данных
- •17. Указатели
- •17.1. Определение указателей
- •17.2. Связь указателей и массивов.
- •17.3. Операции над указателями (косвенная адресация)
- •17.4. Операции над указателями (косвенная адресация)
- •17.5. Массивы указателей.
- •17.6. Указатели на указатели.
- •17.7 . Указатели как параметры функций.
- •Void f1(int, const double *);
- •17.8 . Указатели на структуры
- •17.9. Ссылка
- •17.10. Указатели на функции
- •Id_функции(список аргументов);
- •18. Работа с динамической памятью
- •18.1. Динамическое выделение и освобождение памяти.
- •18.2. Создание одномерного динамического массива.
- •18.3. Создание двуxмерного динамического массива.
- •19. Операция typedef
- •20. Отладка и пошаговое выполнение программы
11.5. Операция sizeof
Данная операция позволяет определить размер объекта по ID или типу, результатом является размер памяти в байтах (тип результата int). Формат записи:
sizeof(параметр);
где: «параметр» – тип или идентификатор объекта (не ID функции).
Если указан идентификатор сложного объекта (массив, структура, объединение), то получаем размер всего сложного объекта. Например:
sizeof(int) размер памяти – 2 байта,
int b[5];
sizeof(b) размер памяти – 10 байт.
При переносе программы с одной платформы на другую нельзя делать предположений, например, о размере типа int, так как для оперативной системы (ОС) MS DOS этот тип имеет размер в два байта, а для ОС Windows 9X – четыре байта. В стандарте языка С поэтому диапазоны значений для основных типов не задаются, а определяются только соотношения между их размерами, например:
sizeof (float) < sizeof (double) < sizeof (long double) ,
sizeof (char) < sizeof (short) < sizeof (int) < sizeof (long) .
11.6. Побитовые логические операции. Операции над битами
В СИ предусмотрен набор операций для работы с отдельными битами слов. Эти операции нельзя применять к переменным вещественного типа (float, double).
Перечень операций над битами и их обозначения:
~ - инвертирование (унарная операция);
& - побитовое И - конъюнкция;
| - побитовое включающее ИЛИ - дизъюнкция;
^ - побитовое исключающее ИЛИ - сложение по модулю 2;
>> - сдвиг вправо;
<< - сдвиг влево.
Пары символов (>>,<<) разделять нельзя.
Общий вид операции инвертирования:
~ <выражение>
Остальные операции над битами имеют вид:
<выражение1> <знак_операции> <выражение2>
Операндами операций над битами могут быть только выражения, приводимые к целому типу. Операнды представляются в двоичной форме, и операции выполняются поразрядно, т.е. над каждым битом (для операций &, |, ^ - над каждой парой соответствующих бит, взятых от первого и второго операндов) (знаковый разряд особо не выделяется).
Операция ~ означает замену значения бита на противоположное (т.е 0 на 1 , а 1 на 0).
Операция & дает 1, если оба участвующих в ней бита равны 1; иначе дает 0.
Операция | дает 1, если хотя бы один из участвующих в ней битов равен 1; иначе дает 0.
Операция ^ дает 1, если один из участвующих в ней битов равен 1, а другой 0; иначе (т.е. если оба бита одинаковы) дает 0.
Примеры:
~0xF0 0x0F
0xFF & 0x0F 0x0F
0xF0 | 0x11 0xF1
0xF4 ^ 0xF5 0x01
Операция & часто используется для маскирования (выделения) некоторого множества битов. Например, оператор w = n & 0177 передает в w семь младших битов n, полагая остальные равными нулю.
Необходимо отличать побитовые операции & и | от логических операций && и ||, которые подразумевают вычисление значения истинности. Если x=1, y=2, то x & y равно нулю, а x && y равно 1.
0x81<<1 0x02
0x81>>1 0x40
Унарная операция (~) дает дополнение к целому. Это означает, что каждый бит со значением 1 получает значение 0 и наоборот. Эта операция обычно оказывается полезной в выражениях типа:
X & (~)077,
где последние 6 битов X маскируются нулем. Это выражение не зависит от длины слова и поэтому предпочтительнее, чем, например:
X & 0177700,
где предполагается, что X занимает 16 битов, такая переносимая форма не требует никаких дополнительных затрат.
Операции сдвига << и >> осуществляют соответственно сдвиг вправо (влево) своего левого операнда, на число битовых позиций, задаваемых правым операндом. Таким образом, x<<2 сдвигает x влево на две позиции, заполняя освобождающиеся биты нулями, что эквивалентно умножению на 4.
Операции сдвига выполняются для всех разрядов с потерей выходящих за границы битов. Если выражение1 имеет тип unsigned, то при сдвиге вправо освобождающиеся разряды гарантированно заполняются нулями (логический сдвиг). Выражения типа signed могут, но не обязательно, сдвигаться вправо с копированием знакового разряда (арифметический сдвиг). При сдвиге влево освобождающиеся разряды всегда заполняются нулями. Выражение2 не должно быть отрицательно.
Операции сдвига вправо на k разрядов весьма эффективны для деления, а сдвиг влево - для умножения целых чисел на 2 в степени k:
x<<1 x*2
x>>1 x/2
x<<3 x*8
Подобное применение операций сдвига безопасно для беззнаковых и положительных значений выражения1.
Двуместные операции над битами (&, |, ^, <<, >>) могут использоваться в сокращенных формах записи операции присваивания:
int i,j,k;
. . .
i |= j i = i | j - включение в поле i единиц из поля j;
i &= 0xFF i = i & 0xFF - выделение в поле i единиц по маске поля 0x00FF;
k ^= j - выделение в поле k отличающихся разрядов в полях k и j;
i ^= i - обнуление всех разрядов поля i .
Операции над битами реализуются, как правило, одной машинной командой и рекомендуются для использования во всех подходящих случаях.
В математическом смысле операнды логических операций над битами можно рассматривать как отображение некоторых множеств с размерностью не более разрядности операнда на значения {0,1}.
Пусть единица означает обладание элемента множества некоторым свойством, тогда очевидна теоретико-множественная интерпретация рассматриваемых операций:
~ - дополнение; | - объединение; & - пересечение.
Простейшее применение - проверка нечетности целого числа:
int i;
...
if (i &1) printf(" Значение i нечетно!");
Комбинирование операций над битами с арифметическими операциями часто позволяет упростить выражения. Например, получение размера области в блоках размером 16 байт для размещения объекта размером x байт:
(x + 15)>>4
Другие возможности оперирования над битами:
- использование структур с битовыми полями;
-
доступ к битам как разрядам арифметических данных.