Указатели

Содержание

Слайд 2

ПЛАН

Понятие указателя, виды указателей в C++
Способы инициализации указателей
Операции с указателями в C++
Динамические

ПЛАН Понятие указателя, виды указателей в C++ Способы инициализации указателей Операции с
массивы
Литература

Слайд 3

УКАЗАТЕЛЬ

Когда компилятор обрабатывает оператор определения переменной (например, int i=10;), он выделяет память

УКАЗАТЕЛЬ Когда компилятор обрабатывает оператор определения переменной (например, int i=10;), он выделяет
в соответствии с типом (int) и инициализирует ее указанным значением (10).
Все обращения в программе к переменной по ее имени (i) заменяются компилятором на адрес области памяти, в которой хранится значение переменной.
Программист может определить собственные переменные для хранения адресов областей памяти. Такие переменные называются указателями.

Слайд 4

УКАЗАТЕЛЬ

Указатели предназначены для хранения адресов областей памяти.

УКАЗАТЕЛЬ Указатели предназначены для хранения адресов областей памяти.

Слайд 5

«КУЧА»

Указатели чаще всего используют при работе с динамической памятью, называемой «кучей» (англ.

«КУЧА» Указатели чаще всего используют при работе с динамической памятью, называемой «кучей»
heap).
Это свободная память, в которой можно во время выполнения программы выделять место в соответствии с потребностями.
Доступ к выделенным участкам динамической памяти (динамическим переменным) производится только через указатели.
Время жизни динамических переменных — от точки создания до конца программы или до явного освобождения памяти.

Слайд 6

ВИДЫ УКАЗАТЕЛЕЙ В C++

ВИДЫ УКАЗАТЕЛЕЙ В C++

Слайд 7

УКАЗАТЕЛЬ НА ФУНКЦИЮ

Содержит адрес в сегменте кода, по которому располагается исполняемый код

УКАЗАТЕЛЬ НА ФУНКЦИЮ Содержит адрес в сегменте кода, по которому располагается исполняемый
функции, то есть адрес, по которому передается управление при вызове функции.
Указатели на функции используются для косвенного вызова функции (не через ее имя, а через обращение к переменной, хранящей ее адрес), а также для передачи имени функции в другую функцию в качестве параметра.

Слайд 8

УКАЗАТЕЛЬ НА ФУНКЦИЮ

Указатель на функцию имеет тип «указатель на функцию, возвращающую значение

УКАЗАТЕЛЬ НА ФУНКЦИЮ Указатель на функцию имеет тип «указатель на функцию, возвращающую
заданного типа и имеющую аргументы заданного типа»:
тип (*имя) (список_типов_аргументов);
Например, объявление:
int (*fun) (double, double);
задает указатель с именем fun на функцию, возвращающую значение типа int и имеющую два аргумента типа double.

Слайд 9

УКАЗАТЕЛЬ НА ОБЪЕКТ

Содержит адрес области памяти, в которой хранятся данные определенного типа

УКАЗАТЕЛЬ НА ОБЪЕКТ Содержит адрес области памяти, в которой хранятся данные определенного
(основного или составного).
Простейшее объявление указателя на объект (в дальнейшем «указателя») имеет вид:
тип *имя;
где тип может быть любым, кроме ссылки и битового поля.
Можно определить указатель на указатель и др.

Слайд 10

УКАЗАТЕЛЬ НА ОБЪЕКТ

Звездочка относится непосредственно к имени, поэтому для того, чтобы объявить

УКАЗАТЕЛЬ НА ОБЪЕКТ Звездочка относится непосредственно к имени, поэтому для того, чтобы
несколько указателей, требуется ставить * перед именем каждого из них.
Например, в операторе: int *a, b, *с;
описываются два указателя на целое с именами а и с, а также целая переменная b.
Размер указателя зависит от модели памяти.

Слайд 11

УКАЗАТЕЛЬ НА VOID

Применяется в тех случаях, когда конкретный тип объекта, адрес которого

УКАЗАТЕЛЬ НА VOID Применяется в тех случаях, когда конкретный тип объекта, адрес
требуется хранить, не определен (например, если в одной и той же переменной в разные моменты времени требуется хранить адреса объектов различных типов).
Указателю на void можно присвоить значение указателя любого типа, а также сравнивать его с любыми указателями, но перед выполнением каких-либо действий с областью памяти, на которую он ссылается, требуется преобразовать его к конкретному типу явным образом.

Слайд 12

УКАЗАТЕЛЬ

Указатель может быть константой или переменной, а также указывать на константу или

УКАЗАТЕЛЬ Указатель может быть константой или переменной, а также указывать на константу
переменную.
Рассмотрим примеры:
int i; //целая переменная
const int ci = 1; //целая константа
Int *pi; //указатель на целую переменную
const int *pci; //указатель на целую константу
int *const ср = &i; //указатель-константа на целую //переменную const int *const срс = &ci; //указатель-константа на //целую константу

Слайд 13

УКАЗАТЕЛЬ

Модификатор const, находящийся между звездочкой и именем указателя, относится к самому указателю

УКАЗАТЕЛЬ Модификатор const, находящийся между звездочкой и именем указателя, относится к самому
и запрещает его изменение, а const слева от звездочки задает постоянство значения, на которое он указывает.
Для инициализации указателей использована операция получения адреса &.

План

Слайд 14

ПРИСВАИВАНИЕ УКАЗАТЕЛЮ АДРЕСА СУЩЕСТВУЮЩЕГО ОБЪЕКТА

с помощью операции получения адреса: int а = 5;

ПРИСВАИВАНИЕ УКАЗАТЕЛЮ АДРЕСА СУЩЕСТВУЮЩЕГО ОБЪЕКТА с помощью операции получения адреса: int а
//целая переменная int *р = &а; //в указатель записывается адрес а int *р (&а); //то же самое другим способом
с помощью значения другого инициализированного указателя: int *r = р;
с помощью имени массива или функции, которые трактуются как адрес: int b[10]; //массив, имя массива хранит адрес первого элемента int *t = b; //присваивание адреса начала массива void f(int а ){ /* ... * / } // определение функции void (*pf)(int); // указатель на функцию pf = f; // присваивание адреса функции

Слайд 15

ВЫДЕЛЕНИЕ УЧАСТКА ДИНАМИЧЕСКОЙ ПАМЯТИ И ПРИСВАИВАНИЕ ЕЕ АДРЕСА УКАЗАТЕЛЮ

тип_данных *имя_указателя = new

ВЫДЕЛЕНИЕ УЧАСТКА ДИНАМИЧЕСКОЙ ПАМЯТИ И ПРИСВАИВАНИЕ ЕЕ АДРЕСА УКАЗАТЕЛЮ тип_данных *имя_указателя =
тип_данных;
int *n = new int; //выделение памяти под величину типа int int *m = new int (10); //выделение памяти под величину типа int, //инициализация выделенной динамической памяти значением 10 int *q = new int [10]; //выделение памяти под массив //из 10 целых чисел

Слайд 16

ОСВОБОЖДЕНИЕ ПАМЯТИ

Освобождение памяти, выделенной с помощью операции new, должно выполняться с помощью

ОСВОБОЖДЕНИЕ ПАМЯТИ Освобождение памяти, выделенной с помощью операции new, должно выполняться с
delete.
При этом переменная-указатель сохраняется и может инициализироваться повторно. Приведенные выше динамические переменные уничтожаются следующим образом:
delete n; delete m; delete [ ] q;

План

Слайд 17

ОПЕРАЦИИ С УКАЗАТЕЛЯМИ В C++

ОПЕРАЦИИ С УКАЗАТЕЛЯМИ В C++

Слайд 18

РАЗАДРЕСАЦИЯ

Операция разадресации, или разыменования, предназначена для доступа к величине, адрес которой хранится

РАЗАДРЕСАЦИЯ Операция разадресации, или разыменования, предназначена для доступа к величине, адрес которой
в указателе.
Эту операцию можно использовать как для получения, так и для изменения значения величины (если она не объявлена как константа).

char а; //переменная типа char char *р = new char; /* выделение памяти под указатель и под динамическую переменную типа char */ *р = 'Ю'; а = *р; // присваивание значения обеим переменным

Слайд 19

ПРИСВАИВАНИЕ

Указателю можно присвоить либо адрес объекта того же типа, либо значение другого

ПРИСВАИВАНИЕ Указателю можно присвоить либо адрес объекта того же типа, либо значение
указателя.
Для получения адреса объекта используется операция &.
Например:
int a = 10;
int *pa = &a;   // указатель pa хранит адрес переменной a
При этом указатель и переменная должны иметь один и тот же тип, в данном случае это тип int.

Слайд 20

ПРИСВАИВАНИЕ

Когда указателю присваивается другой указатель, то первый указатель начинает указывать на тот

ПРИСВАИВАНИЕ Когда указателю присваивается другой указатель, то первый указатель начинает указывать на
же адрес, на который указывает второй.
Например:
int a = 10; int b = 2;
       int *pa = &a; int *pb = &b;
pa = pb;

На какой адрес указывает pa?

Слайд 21

НУЛЕВОЙ УКАЗАТЕЛЬ

Нулевой указатель (англ. null pointer) – это указатель, который не указывает

НУЛЕВОЙ УКАЗАТЕЛЬ Нулевой указатель (англ. null pointer) – это указатель, который не
ни на какой объект.
Для создания нулевого указателя можно применять следующие способы:
int *p2 = NULL;
int *p3 = 0;

Слайд 22

СРАВНЕНИЕ

К указателям могут применяться операции сравнения >, >=, <, <=,==, !=.
Операции

СРАВНЕНИЕ К указателям могут применяться операции сравнения >, >=, Операции сравнения применяются
сравнения применяются только к указателям одного типа и к значениям NULL.
Для сравнения используются адреса, на которые ссылаются указатели.

Слайд 23

ПРИВЕДЕНИЕ ТИПОВ

Иногда требуется присвоить указателю одного типа значение указателя другого типа.
В

ПРИВЕДЕНИЕ ТИПОВ Иногда требуется присвоить указателю одного типа значение указателя другого типа.
этом случае следует выполнить операцию приведения типов с помощью операции
(тип_указателя *)
В скобках указывается тип, к которому следует выполнить преобразование.
Например:
char c = 'N';
     char *pc = &c;
    int *pd = (int *)pc; //преобразование к int
     void *pv = (void*)pc; //преобразование к void

Слайд 24

АРИФМЕТИЧЕСКИЕ ОПЕРАЦИИ

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

АРИФМЕТИЧЕСКИЕ ОПЕРАЦИИ Указатели могут участвовать в арифметических операциях (инкремент, декремент, сложение, вычитание).
++ увеличивает значение на единицу. В случае с указателем увеличение на единицу будет означать увеличение адреса, который хранится в указателе, на размер типа указателя.
Операция декремента -- уменьшает значение на единицу. В случае с указателем уменьшение на единицу будет означать уменьшение адреса, который хранится в указателе, на размер типа указателя.

Слайд 25

АРИФМЕТИЧЕСКИЕ ОПЕРАЦИИ

Аналогично указатель будет изменяться при прибавлении/вычитании не единицы, а какого-то другого

АРИФМЕТИЧЕСКИЕ ОПЕРАЦИИ Аналогично указатель будет изменяться при прибавлении/вычитании не единицы, а какого-то
числа.
Например, добавление к указателю типа double числа 2 будет означать, увеличение адреса, который хранится в указателе, два раза на размер типа указателя.

Слайд 26

ПРИМЕР 1


int main()
{ double *x, *y; //указатели на величины типа double
x =

ПРИМЕР 1 … int main() { double *x, *y; //указатели на величины
new double(10);
y = new double;
*y = (pow(*x, 2) - 7*(*x) + 10) /
(pow(*x, 2) - 8*(*x) + 12);
cout << *y << endl;
delete x; delete y;
return 0; }

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

Слайд 27

ПРИМЕР 2

#include "stdafx.h"
#include
#include
using namespace std;
void vmas(int *a, int k)
{

ПРИМЕР 2 #include "stdafx.h" #include #include using namespace std; void vmas(int *a,
for (int i = 0; i < k; i++) cout << a[i] << " ";
cout << endl; }

Напишите программу для решения задачи, используя указатель на массив: если в массиве А(10) есть элемент, равный кубу последнего элемента, то все элементы, следующие за ним, возвести в куб, иначе вывести массив без изменений.

Слайд 28

ПРИМЕР 2

int main()
{int n = 10;
int *mas = new int[n] {2,5,6,7,8,3,2,4,9,2};

ПРИМЕР 2 int main() {int n = 10; int *mas = new
//указатель на массив
vmas(mas, n); //вывод массива
int nmas = -1; //нет элементов равных кубу последнего элемента
for (int i = 0; i < n-1; i++)
if (mas[i] == pow(mas[n-1], 3)) {nmas = i; break;}
if (nmas != -1)
for (int i = nmas+1; i < n; i++) mas[i] = pow(mas[i], 3);
vmas(mas, n); //вывод массива
return 0; }

План

Слайд 29

ДИНАМИЧЕСКИЕ МАССИВЫ

При объявлении статического массива, его размером является числовая константа, например:
int n

ДИНАМИЧЕСКИЕ МАССИВЫ При объявлении статического массива, его размером является числовая константа, например:
= 10;
int arr[n];
Но в некоторых случаях изначально неизвестно сколько элементов окажется в массиве, например, их количество задаст пользователь.
В этом случае используются динамические массивы.

Слайд 30

СОЗДАНИЕ ОДНОМЕРНОГО ДИНАМИЧЕСКОГО МАССИВА

int main()
{ int num; //размер массива
cout << "Enter

СОЗДАНИЕ ОДНОМЕРНОГО ДИНАМИЧЕСКОГО МАССИВА int main() { int num; //размер массива cout
integer value: ";
cin >> num; //получение от пользователя размера массива
  int *p = new int[num]; //выделение памяти для массива
for (int i = 0; i < num; i++) //заполнение и вывод массива
{ p[i] = i;
cout << "Value of " << i << " element is " << p[i] << endl; }
delete [] p; //очистка памяти
return 0; }

Динамические массивы нельзя инициализировать при создании.

Слайд 31

ДОСТУП К ЭЛЕМЕНТАМ ДИНАМИЧЕСКОГО МАССИВА

Доступ к элементам динамического массива осуществляется так же,

ДОСТУП К ЭЛЕМЕНТАМ ДИНАМИЧЕСКОГО МАССИВА Доступ к элементам динамического массива осуществляется так
как к статическим.
Например, к элементу номер 5 приведенного ранее массива можно обратиться как p[5] или *(p+5).

Слайд 32

СОЗДАНИЕ ДВУМЕРНОГО ДИНАМИЧЕСКОГО МАССИВА


int nstr, nstb;
cout « "Введите количество строк и столбцов

СОЗДАНИЕ ДВУМЕРНОГО ДИНАМИЧЕСКОГО МАССИВА … int nstr, nstb; cout « "Введите количество
:";
cin » nstr » nstb;
int **a = new int *[nstr]; // 1
for (int i = 0; ia[i] = new int [nstb]; // 3

Слайд 33

СОЗДАНИЕ ДВУМЕРНОГО ДИНАМИЧЕСКОГО МАССИВА

В операторе 1 объявляется переменная типа «указатель на указатель

СОЗДАНИЕ ДВУМЕРНОГО ДИНАМИЧЕСКОГО МАССИВА В операторе 1 объявляется переменная типа «указатель на
на int» и выделяется память под массив указателей на строки массива (количество строк — nstr).
В операторе 2 организуется цикл для выделения памяти под каждую строку массива.
В операторе 3 каждому элементу массива указателей на строки присваивается адрес начала участка памяти, выделенного под строку двумерного массива.
Каждая строка состоит из nstb элементов типа int.

Слайд 34

СОЗДАНИЕ ДВУМЕРНОГО ДИНАМИЧЕСКОГО МАССИВА

План

СОЗДАНИЕ ДВУМЕРНОГО ДИНАМИЧЕСКОГО МАССИВА План
Имя файла: Указатели.pptx
Количество просмотров: 28
Количество скачиваний: 0