54. Укажите способы инициализации указателей, используя операции new и new[].
int *p;
p = new int;
int *a;
a = new int [size];
55. Опишите использование операций delete и delete[].
Операции delete и delete[] предназначены для очистки неиспользуемой памяти при ручной работе с динамической памятью. Т.е. для удаления элементов созданных при помощи команд new и new[] соответсвенно.
delete имя указателя;// удалить область памяти по адресу
delete []имя указателя;// удалить массив по адресу
56. Проинтерпретируйте выражение int *(*p[10])()
Массив из 10 указателей на функции которые ничего не принимают и возвращают указатель на int.
57. Проинтерпретируйте выражение int *(*p[10])(int *)
Массив из 10 указателей на функции которые принимают указатель на тип int и возвращают указатель на тип int.
58. Укажите особенности выполнения операций ++ --
Оператор ++ увеличивает на 1 значение переменной, которая стоит справа (слева) от него. (Стоит заметить, что при использовании с указателями данный оператор увеличивает значение указателя не на единицу, а на n, где n – размер в байтах того типа данных, на который указывает указатель).
Данный оператор имеет две формы: префиксную и постфиксную. Различие в том, что происходит раньше: использование значения переменной в выражении или же инкремент переменной.
Наприме:
1)
int x, y = 10;
x = ++y; // префиксная форма – сначала происходит инкремент переменной y, а затем полученное значение присваивается переменной x
cout << x << " " << y;
В итоге в консоль будет выведено:
11 11
2)
int x, y = 10;
x = y++; // постфиксная форма – сначала значение y, равное 10, присваивается переменной х, а затем происходит инкремент переменной у.
cout << x << " " << y;
В итоге в консоль будет выведено:
10 11
Обе формы возвращают значение того же типа данных, что и операнд. Но важное различие заключается в том, что значение, возвращаемое префиксной формой, является l-value, в то время как значение, возвращаемое постфиксной формой оператора ++, не является l-value.
Справка:
l-value - это то, чему можно присваивать значение, т.е. выражение, которое может быть расположено слева от оператора присваивания (=). На самом деле это не совсем так, но для понимания проще всего.
Формально, l-value - выражение типа, отличного от void, ссылающееся на область памяти. При этом l-value может быть и не модифицируемым. Например, переменная, объявленная как const является l-value, однако ее значение нельзя изменять:
const int i = 0;
i = 1; // error C3892: 'i': you cannot assign to a variable that is const
l-value может быть:
- идентификатор переменной любого из следующих типов:
- целочисленного
- с плавающей точкой
- указатель
- структура (struct)
- или союз (union)
- выражение с индексом ([ ]) не являющееся само массивом
- обращение к члену (–> или.)
- выражение взятия значения (*) не являющееся массивом
- любое l-value в скобках
- любое l-value со спецификатором const (немодифицируемое l-value)
То есть можно считать, что префиксная форма возвращает ссылку на операнд (имеющий уже измененное значение), а постфиксная форма возвращает просто значение операнда (причем не измененное значение, так как инкремент будет произведен позже).
То же самое касается и оператора – с той лишь разницей, что он осуществляет не инкремент, а обратную операцию - декремент (т.е. уменьшение на единицу).
59. Укажите особенности выполнения операций + - для указателей. Укажите особенности выполне-ния операций ++ -- для указателей.
Операции + и -:
К указателю можно прибавить целое число, причем выражение
p = p + i;
где p – указатель на переменную типа Type, а i – переменная типа int, не означает, что значение указателя увеличится на i.
В такой ситуации значение указатля увеличится на i*sizeof(Type), т.е. произойдет сдвиг указателя на i блоков памяти, какждый из которых по количеству занимаемой памяти равен переменной типа Type.
Аналогично для -.
Перегружена также разность для указателей, которая вернёт кол-во объектов типа, на который указывают указатели, находящихся между ними.
Пусть p1, p2 - указатели на type и имеют адреса c1 и с2 (в интах)
Тогда значение выражения (p2 - p1) равно (c2 - c1) / sizeof(type).
Сложение двух указателей невозможно!!!
Операции ++ и --:
Изменение указателя зависит от размера типа на который он указывает. ++i/--i – l-value, i++/i-- - не l-value.