Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
otvety_infa.docx
Скачиваний:
1
Добавлен:
04.08.2019
Размер:
187.42 Кб
Скачать
  1. Указатели: Определение и использование (примеры)

Указатель - это адрес памяти, распределяемой для размещения идентификатора (в качестве идентификатора может выступать имя переменной, массива, структуры, строкового литерала). В том случае, если переменная объявлена как указатель, то она содержит адрес памяти, по которому может находится скалярная величина любого типа. При объявлении переменной типа указатель, необходимо определить тип объекта данных, адрес которых будет содержать переменная, и имя указателя с предшествующей звездочкой (или группой звездочек). Формат объявления указателя:

спецификатор-типа [ модификатор ] * описатель.

Спецификатор-типа задает тип объекта и может быть любого основного типа

Указатели необходимо использвать когда

а) у вас есть объект, который нельзя или затруднительно копировать.

б) есть объект, который инициализируется в неопределённый заранее момент

в) необходимо создать заранее неизвестное количество объектов

г) требуется использовать полиморфизм

д) функция может менять аргумент

В случаях а), г), д) лучше использовать ссылки, а не указатели

Примеры:

а) int sum(std::list<int>&);

Функция суммирует элементы списка. Если бы ссылки не было, то при вызове пришлось бы копировать в новую память целый список, что очень затратно по ресурсам

б) class A;

...

A* obj=NULL;

if(need_object())

{ obj=new A;

}

....

В этом случае, передавая NULL мы сообщает, что объекта нет

в)

int col;

std::cin>>col;

A* objs=new A[col];

создаём неизвестное заранее количество объектов

г)

class expression

{ public: virtual void print()const=0;

};

class number:public expression

{ int n;

public: virtual void print(ostream& o)const{o<<n;}

};

class variable:public expression

{ string name;

public: virtual void print(ostream& o)const{o<<name;}

};

ostream& operator<< (ostream&o, const expression& expr)

{ expr.print(o);

return o;

}

...

number num;

variable var;

....

cout<<num;

cout<<var;

//Здесь o со ссылкой потому, что его нельзя копировать, а expr, для использования полиморфизма

д)

void inc(int& a)

{ ++a;

}сток.

  1. Операции над указателями и адресами.

Над указателями можно выполнять унарные операции: инкремент и декремент. При выполнении операций ++ и -- значение указателя увеличивается или уменьшается на длину типа, на который ссылается используемый указатель.

Пример:

int *ptr, a[10];

ptr=&a[5];

ptr++; /* равно адресу элемента a[6] */

ptr--; /* равно адресу элемента a[5] */

В бинарных операциях сложения и вычитания могут участвовать указатель и величина типа int. При этом результатом операции будет указатель на исходный тип, а его значение будет на указанное число элементов больше или меньше исходного.

Пример:

int *ptr1, *ptr2, a[10];

int i=2;

ptr1=a+(i+4); /* равно адресу элемента a[6] */

ptr2=ptr1-i; /* равно адресу элемента a[4] */

В операции вычитания могут участвовать два указателя на один и тот же тип. Результат такой операции имеет тип int и равен числу элементов исходного типа между уменьшаемым и вычитаемым, причем если первый адрес младше, то результат имеет отрицательное значение.

Пример:

int *ptr1, *ptr2, a[10];

int i;

ptr1=a+4;

ptr2=a+9;

i=ptr1-ptr2; /* равно 5 */

i=ptr2-ptr1; /* равно -5 */

Значения двух указателей на одинаковые типы можно сравнивать в операциях ==, !=, <, <=",">, >= при этом значения указателей рассматриваются просто как целые числа, а результат сравнения равен 0 (ложь) или 1 (истина).

Пример:

int *ptr1, *ptr2, a[10];

ptr1=a+5;

ptr2=a+7;

if (prt1>ptr2) a[3]=4;

В данном примере значение ptr1 меньше значения ptr2 и поэтому оператор a[3]=4 не будет выполнен.

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]