Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Ответы ОАиП.docx
Скачиваний:
127
Добавлен:
09.03.2016
Размер:
139.71 Кб
Скачать

54.Использование макроопределений.

Директива #define служит для замены часто использующихся констант, ключевых слов, операторов или выражений некоторыми идентификаторами. Идентификаторы, заменяющие текстовые или числовые константы, называют именованными константами. Идентификаторы, заменяющие фрагменты программ, называют макроопределениями, причем макроопределения могут иметь аргументы.

Директива #define имеет две синтаксические формы: #define идентификатор текст #define идентификатор (список параметров) текст

Эта директива заменяет все последующие вхождения идентификатора на текст. Такой процесс называется макроподстановкой. Текст может представлять собой любой фрагмент программы на СИ, а также может и отсутствовать. В последнем случае все экземпляры идентификатора удаляются из программы.

Пример:#define WIDTH 80 #define LENGTH (WIDTH+10)

Эти директивы изменят в тексте программы каждое слово WIDTH на число 80, а каждое слово LENGTH на выражение (80+10) вместе с окружающими его скобками.

Скобки, содержащиеся в макроопределении, позволяют избежать недоразумений, связанных с порядком вычисления операций. Например, при отсутствии скобок выражение t=LENGTH*7 будет преобразовано в выражение t=80+10*7, а не в выражение t=(80+10)*7, как это получается при наличии скобок, и в результате получится 780, а не 630.

Во второй синтаксической форме в директиве #define имеется список формальных параметров, который может содержать один или несколько идентификаторов, разделенных запятыми. Формальные параметры в тексте макроопределения отмечают позиции на которые должны быть подставлены фактические аргументы макровызова. Каждый формальный параметр может появиться в тексте макроопределения несколько раз.

При макровызове вслед за идентификатором записывается список фактических аргументов, количество которых должно совпадать с количеством формальных параметров.

Пример: #define MAX(x,y) ((x)>(y))?(x):(y) Эта директива заменит фрагмент t=MAX(i,s[i]); на фрагмент t=((i)>(s[i])?(i):(s[i]);

_____________________________________________________________________________

Например, при наличии скобок фрагмент t=MAX(i&j,s[i]||j); будет заменен на фрагмент t=((i&j)>(s[i]||j)?(i&j):(s[i]||j); а при отсутствии скобок - на фрагмент t=(i&j>s[i]||j)?i&j:s[i]||j; в котором условное выражение вычисляется в совершенно другом порядке.

55.Динамические переменные. Основные свойства динамических переменных.

#include <iostream> using namespace std; int main(){ int *a = new int; // Объявление указателя для переменной типа int int *b = new int(5); // Инициализация указателя *a = 10; *b = *a + *b; cout << "b is " << *b << endl; delete b; delete a; return 0;}

Синтаксис первого примера вам уже должен быть знаком. Мы объявляем/инициализируем статичные переменные aиb, после чего выполняем различные операции напрямую с ними.Выделение памятиосуществляется с помощью оператораnewи имеет вид:тип_данных *имя_указателя = new тип_данных;, напримерint *a = new int;. После удачного выполнения такой операции, в оперативной памяти компьютера происходит выделение диапазона ячеек, необходимого для хранения переменной типаint.Инициализация значения, находящегося по адресу указателя выполняется схожим образом, только в конце ставятся круглые скобки с нужным значением:тип данных *имя_указателя = new тип_данных(значение). В нашем примере этоint *b = new int(5).

Для того, чтобы получить адресв памяти, на который ссылается указатель, используется имя переменной-указателя с префиксом&. перед ним

Например, чтобы вывести на экран адрес ячейки памяти, на который ссылается указатель bво втором примере, мы пишемcout << "Address of b is " << &b << endl;. В моей системе, я получил значение0x1aba030. У вас оно может быть другим, потому что адреса в оперативной памяти распределяются таким образом, чтобы максимально уменьшить фрагментацию. Поскольку, в любой системе список запущенных процессов, а также объем и разрядность памяти могут отличаться, система сама распределяет данные для обеспечения минимальной фрагментации.

Для того, чтобы получить значение, которое находитсяпо адресу, на который ссылается указатель,используется префикс *. Данная операция называетсяразыменованием указателя.

Во втором примере мы выводим на экран значение, которое находится в ячейке памяти(у меня это0x1aba030):cout << "b is " << *b << endl;. В этом случае необходимо использовать знак*.

Чтобы изменить значение, находящееся по адресу, на который ссылается указатель, нужно также использовать звездочку, например, как во втором примере — *b = *a + *b;.

  • Когда мы оперируем данными, то используем знак* Когда мы оперируемадресами, то используем знак& В этих вещах очень часто возникают недопонимания, и кстати, не только у новичков. Многие из тех, кто начинал программировать с того же php, также часто испытывают подобную путаницу при работе с памятью.

Для того, чтобы освободить память, выделенную оператором new, используется оператор delete.