- •Основы программирования на языке С
- •Введение
- •1. Базовые понятия программирования
- •1.1. Алгоритмизация задачи
- •1.2. Схема алгоритма программы
- •1.3. Пример алгоритмизации
- •1.4. Этапы трансляции программы
- •2. Особенности языка С
- •2.1. Характеристики языка
- •2.2. Элементы языка
- •2.3. Стандартные типы данных
- •2.4. Компоненты простой программы
- •Вопросы для самопроверки
- •3. Выражения и операции
- •3.1. Операция и выражение присваивания
- •3.2. Бинарные арифметические операции
- •3.3. Операции увеличения (++) и уменьшения (--)
- •3.4. Преобразования типов при вычислении арифметических выражений
- •3.5. Тернарная или условная операция
- •3.6. Логические операции и операции отношения
- •3.7. Поразрядные (побитовые) операции
- •3.8. Операции сдвига
- •3.9. Операция sizeof
- •3.10. Операция следования
- •3.11. Сводная таблица операций языка С
- •Вопросы для самопроверки
- •4. Операторы
- •4.1. Оператор выражение
- •4.2. Пустой оператор
- •4.3. Объявления и составной оператор
- •4.4. Условный оператор
- •4.5. Оператор выбора switch
- •4.6. Циклы
- •4.7. Оператор break
- •4.8. Оператор безусловного перехода goto
- •4.9. Оператор continue
- •4.10. Оператор return
- •Вопросы для самопроверки
- •5. Массивы
- •5.1. Одномерные статические массивы
- •5.2. Объявление массива. Обращение к элементу массива
- •5.3. Инициализация массива
- •5.4. Многомерные массивы
- •5.5. Выход индекса за границы массива
- •5.6. Приемы работы с массивами в вычислительных задачах
- •5.7. Строка как массив символов
- •Вопросы для самопроверки
- •6. Указатели и ссылки
- •6.1. Понятие указателя
- •6.2. Операция получения адреса &
- •6.3. Операция разыменования (*)
- •6.4. Арифметика указателей
- •6.5. Применение указателей в выражениях
- •6.6. Указатели и массивы
- •6.7. Ссылочный тип данных
- •Вопросы для самопроверки
- •7. Время жизни и область видимости переменной
- •7.1. Общие понятия
- •7.2. Классы памяти
- •7.3. Вложенные блоки в программе
- •8. Функции
- •8.1. Общие понятия
- •8.2. Определение функции
- •8.3. Прототип функции
- •8.4. Переменные в функции
- •8.5. Передача параметров в функцию
- •Вопросы для самопроверки
- •9. Пользовательские типы данных
- •9.1. Структурный тип данных
- •9.2. Битовые поля
- •9.3. Объединения или смеси
- •9.4. Перечисления
- •Вопросы для самопроверки
- •10. Динамическая работа с памятью
- •10.1. Универсальный указатель void
- •10.2. Принципы работы с динамическими массивами
- •Вопросы для самопроверки
- •11. Ввод-вывод данных
- •11.2. Функции ввода-вывода библиотеки iostream
Выражение С=N&0377 передает в переменную С младший байт (8 битов) переменной N, обнуляя все остальные разряды. Двоичное представление константы 0377 будет выглядеть следующим образом:
… 000 000 011 111 111, здесь наглядно видно, что "помечен" младший байт переменной.
В следующем примере переменные инициализируются шестнадцатеричными константами (в комментариях даны соответствующие двоичные представления).
Результат формируется отдельно для каждого бита переменной r, используя в качестве операндов соответствующие биты переменных i и j, согласно таблице истинности логических операций "ИЛИ-НЕ", "И", "ИЛИ".
Например, для r = i^j нулевой бит r равен 0, так как 1^1 равно 0.
Пример: Вспомним, что тип константы определяется по её внешнему виду, если константа начинаются с нуля, то это восьмеричная константа, если же с 0Х (или 0x), то – шестнадцатеричная.
int i=0x47F0; /* |
i |
= |
0100 0111 1111 0000*/ |
|
j=0xA0FF; |
j |
= |
1010 0000 1111 1111*/ |
|
char r; |
|
|
|
|
r = i^j; |
/* r=0xE70F |
= |
1110 0111 0000 1111*/ |
|
r = i|j; |
/* r=0xE7FF |
= |
1110 0111 1111 1111*/ |
|
r = i&j |
/* r=0x00F0 |
= |
0000 0000 1111 0000*/ |
3.8. Операции сдвига
Операции сдвига также оперируют с отдельными битами переменной и являются бинарными операторами. В первом операнде находится информация, которою необходимо сдвигать, во втором размещается параметр – число сдвигов. Оба операнда должны быть целыми величинами.
Существуют две операции сдвига:
<< – сдвиг влево; >> – сдвиг вправо.
При сдвиге влево правые освобождающиеся биты устанавливаются в нуль.
При сдвиге вправо метод заполнения освобождающихся левых битов зависит от типа первого операнда. Если тип unsigned (беззнаковый), то свободные левые биты устанавливаются в нуль. В противном случае они заполняются копией знакового бита.
Например, Х << 2 сдвигает переменную Х влево на 2 разряда (бита), заполняя освобождающиеся биты нулями, что эквивалентно умножению на 4. Сдвиг вправо переменной unsigned на n битов эквивалентен целочисленному делению левого операнда на 2 в степени n.
Например 5 << 3 дает 40, а 7 >> 2 дает 1.
Пример: int i;
i << 1; // сдвиг влево на 1 бит (умножение i на 2) i >> 2; // сдвиг вправо на 2 бита (деление i на 4)
Отметим, что правый операнд должен быть константным выражением. Если правый операнд отрицателен, а также больше или равен числу битов левого операнда, то результат сдвига не определен.
Типом результата операции сдвига является тип левого операнда.
3.9. Операция sizeof
Унарная операция sizeof() вычисляет размер памяти занимаемой операндом и имеет следующий формат:
sizeof (выражение)
В качестве выражения может быть использован любой идентификатор, либо имя тип, а операндом sizeof() может быть только объект, расположенный в памяти компьютера.
Например, нельзя использовать тип void (так как не существует данных этого типа), также идентификатор не может быть именем битового поля или функции.
Пример: |
|
|
int i,j,k,n=15; |
|
|
double x; |
|
|
i = sizeof(n); |
//i=4 j = sizeof(int); |
// j=4 |
k = sizeof(double) |
// k=8 |
|
Чаще всего оператор sizeof() используется для определения размеров пользовательских типов данных, например для определения размера массива или элемента структуры.
PDF created with FinePrint pdfFactory Pro trial version http://www.fineprint.com
3.10. Операция следования
Символом операции следования является "," (запятая). Выражения, разделенные этим символом, выполняются слева направо строго в том порядке, в котором они перечислены. Результатом операции является результат последнего выражения. Поскольку запятая может использоваться и в качестве разделителя, важно не путать эти два её назначения.
Пример:
//в первой строке запятая – это разделитель, а не операция; int a=3, b=8, c;
//две последующих строки содержат операцию следования c=k++, k+b;
(b--,c)*=3;
Первую операцию следования можно заменить следующей последовательностью команд: c=k++; c=k+b; в результате чего получим с=12.
Вторую операцию следования можно заменить последовательностью команд: b--; c *= 3; , в результате получим b=7, с=36.
Вкачестве разделителя запятая может применяться в следующих случаях:
∙В функциях для разделения аргументов, если их более одного. Например, f1(x,y).
∙При объявлении переменных, например, int q,w,e.
В качестве операции запятая часто используется в операторе for. Примеры будут приведены в соответствующем разделе пособия.
3.11. Сводная таблица операций языка С
Операции приведены в таблице 3.3. в порядке уменьшения приоритета, то есть имеют самый высокий ранг и выполняются, а первую очередь операции ( ) [ ] . и - >.
В последнюю очередь выполняются операции "присваивание" и "запятая".
Таблица 3.3
Знак |
Название |
Ранг |
Порядок |
Операции |
Операции |
Операции |
выполнения |
( ) |
Вызов |
|
|
|
функции |
1 |
|
[ ] |
Индексная |
|
Слева |
|
направо |
||
|
|
|
|
. и - > |
Выбор элемента |
|
|
- |
Отрицание |
|
|
|
арифметическое |
|
|
! |
Отрицание |
|
|
|
логическое |
2 |
|
~ |
Двоичное |
|
|
|
|
||
* |
дополнение |
|
|
|
Косвенная |
|
|
|
адресация |
|
Слева |
& |
Вычисление адреса |
|
направо |
|
|
|
|
++ |
Инкремент |
|
|
Декремент |
|
|
|
- - |
|
|
|
Приведение типа |
|
|
|
(тип) |
|
|
|
Вычисление |
|
|
|
|
|
|
|
sizeof |
размера |
|
|
* |
Умножение |
|
Слева |
|
|
3 |
направо |
PDF created with FinePrint pdfFactory Pro trial version http://www.fineprint.com
/ |
Деление |
|
|
|
% |
Остаток от деления |
|
|
|
+ |
Сложение |
4 |
Слева |
|
|
|
|||
- |
Вычитание |
направо |
||
|
||||
|
|
|||
>> |
Сдвиг вправо |
5 |
Слева |
|
|
|
|||
<< |
Сдвиг влево |
направо |
||
|
||||
|
|
|||
> |
Больше |
6 |
|
|
< |
Меньше |
6 |
|
|
> = |
Больше или равно |
6 |
|
|
< = |
Меньше или равно |
6 |
Слева |
|
направо |
||||
|
|
|
||
= = |
Равно |
7 |
|
|
! = |
Не равно |
7 |
|
|
& |
Поразрядное И |
8 |
|
|
|
Поразрядное |
|
|
|
^ |
исключающее ИЛИ |
9 |
Справа |
|
|
|
|
||
| |
Поразрядное ИЛИ |
10 |
налево |
|
|
|
|
||
&& |
Логическое И |
11 |
Справа |
|
|
|
|
||
| |
Логическое ИЛИ |
12 |
налево |
|
|
||||
?: |
Условная |
13 |
Справа |
|
|
|
|
налево |
|
= |
Присваивание |
14 |
Справа |
|
|
|
|
налево |
|
* = |
|
|
|
|
/ = |
|
|
|
|
% = |
Составное |
14 |
|
|
+ = |
присваивание |
|
|
|
- = |
|
|
Справа |
|
& = |
|
|
налево |
|
? = |
|
|
|
|
> > = |
|
|
|
|
< < = |
|
|
|
|
^= |
|
|
|
|
, |
Последовательное |
15 |
Справа |
|
|
вычисление |
|
налево |
Естественный порядок выполнения выражений может быть изменен с помощью круглых скобок. Например, выражение:
6*r + k/s интерпретируется как (6 *r) + (k/s), но можно изменить этот порядок, поставив скобки:
6 * (r+k)/s.
PDF created with FinePrint pdfFactory Pro trial version http://www.fineprint.com
Вопросы для самопроверки
1.Поясните термин "унарная" (бинарная) операция.
2.Какие группы операций вы знаете?
3.Что такое ранг операции?
4.Какие выражения могут стоять слева от операции присваивания?
5.Какие выражения не могут стоять слева от операции присваивания?
6.Перечислите пять арифметических операций языка Си.
7.Приведите алгоритм работы счетчика, для чего он используется?
8.Что общего и какая разница между счетчиком и аккумулятором.
9.Какая разница между префиксной и постфиксной формой операции инкремента (декремента).
10.Изложите главное правило неявного преобразования типов при вычислении арифметических выражений.
11.Почему условную операцию называют тернарной?
12.Перечислите операции отношения.
13.Перечислите логические операции.
14.Для чего нужны логические операции?
15.Перечислите поразрядные операции. Для чего они используются?
16.Приведите пример использования операции sizeof.
PDF created with FinePrint pdfFactory Pro trial version http://www.fineprint.com