- •Последовательность решения задач на эвм:
- •Состав языка
- •Комментарии
- •Переменные, операции, выражения
- •Базовые алгоритмические конструкции
- •Оператор множественного выбора switch
- •Тернарная условная операция
- •Циклические алгоритмы
- •Операции
- •Операция инкремента и декремента
- •Операции отрицания
- •Операции умножения и деления
- •Операции сдвига
- •Логические операции (&&, ||)
- •Операция присваивания
- •Выражения
- •Работа с памятью Память и указатели
- •Операции адресации и разадресации (&, *)
- •Адресная арифметика
Выражения
В выражениях операции, имеющие одинаковый приоритет, обычно выполняются слева направо. Исключение – операция присваивания.
a – b + c – d = {[(a – b) + c] – d}
С другой стороны, порядок вычисления операндов в выражениях неопределён.
int i = 5;
x = (i --) + (i ++) – скобки могут вычисляться в любом порядке.
Можно явно задать порядок выполнения операций с помощью скобок. Иногда это может быть очень существенно.
int x;
x = (3 * 1) / 2; /1
x = 3 * (1 / 2); /0
Результат выражения характеризуется не только значением, но и типом. Если операнды имеют одинаковый тип, то и выражение имеет тот же тип. Если типы операндов разные, то перед вычислением будет выполнено т.н. неявное приведение типов, обеспечивающее преобразование меньших типов в большие для сохранения значимости и точности. Результат будет иметь больший тип.
double d;
short s; // => d * s – double
Существует возможность выполнять т.н. явное приведение типов.
8.10.2012
Работа с памятью Память и указатели
Упрощённая модель памяти, но достаточно точная с точки зрения программиста:
память компьютера представляет собой набор последовательно расположенных одинаковых ячеек, в которых хранятся данные. Ячейки называются байтами;
все ячейки последовательно пронумерованы и каждая имеет свой уникальный номер, который называется адресом;
одна переменная может занимать более одного байта. В этом случае адресом переменной является адрес её первого байта;
доступ возможен только к тем ячейкам памяти, которые мы предварительно запросили у компьютера (т.н. выделение памяти). После того, как выделенные ячейки более не нужны, их можно вернуть компьютеру и в дальнейшем снова использовать (освобождение памяти);
для обычных переменных выделение памяти происходит в момент объявления, а освобождение – в момент выхода из области действия;
блоки памяти могут выделяться и освобождаться программой независимо от переменных в любой момент времени. Такие блоки не имеют имён, а только адрес.
1000 1004 1008 1012 1016 1020 1024 1028
int x, y; |
▄▄▄▄ |
? |
▄▄▄▄ |
▄▄▄▄ |
▄▄▄▄ |
? |
▄▄▄▄ |
… |
|
x |
|
y |
| ||||
x = 15; |
▄▄▄▄ |
15 |
▄▄▄▄ |
▄▄▄▄ |
▄▄▄▄ |
? |
▄▄▄▄ |
… |
К содержимому ячейки (= переменной) можно обращаться как посредством имени переменной, так и с помощью её адреса. Для реализации такой возможности во многих языках существуют команды адресации и разадресации. Первая позволяет по имени переменной получить её адрес, а вторая – по адресу получить значение, которое там содержится.
Существует также специальный тип, называемый указателями. Переменные данного типа предназначены для хранения адресов. В С++ существует три типа указателей:
указатель на переменную (содержит адрес первого байта переменной);
указатель на функцию (содержит адрес первой команды функции);
указатель на void (применяется в тех случаях, когда тип адресуемого объекта заранее не определён. Ему можно присвоить значение указателя любого типа и сравнить его с любым другим указателем).
Они отличаются свойствами и набором допустимых операций. Указатель – это не самостоятельный тип, он всегда связан с другим конкретным типом.
СИНТАКСИС ОБЪЯВЛЕНИЯ УКАЗАТЕЛЯ: тип * имя;
int *ip;
int *ip1, ip2, ip3; // ip1 – указатель, ip2 и ip3 – переменные
int* ip1, ip2, ip3; // ip1, ip2, ip3 – указатели
Величины типа указателя подчиняются общим правилам определения времени жизни, области действия и видимости. Указатель может быть константой, а также указывать на константу. Константный указатель не может менять своё значение.