Указатели и массивы

Содержание

Слайд 2

Указатели

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

Указатели Инициализация указателей При объявлении указателя надо стремиться выполнить его инициализацию, то
ему некоторое начальное значение. Использование неинициализированного указателя – распространенный источник ошибок в программе. Инициализатор записывается после имени указателя после знака равенства или в круглых скобках.

Слайд 3

Указатели

Существуют следующие способы инициализации указателей:
Присваивание указателю адреса существующего объекта:
- с помощью операции

Указатели Существуют следующие способы инициализации указателей: Присваивание указателю адреса существующего объекта: -
получения адреса &
int var_int = 6338;
int *ptr_int = &var_int; // или
int *ptr_int(&var_int);

Слайд 4

Указатели

Еще один пример:
struct Test
{
int test_int;
char test_char;
double tetst_double;
} test={10, 'A', 4.78};

Указатели Еще один пример: struct Test { int test_int; char test_char; double

Слайд 5

Указатели

int main()
{
Test *ptr_Test = &test;
cout << ptr_Test -> test_int << ' '

Указатели int main() { Test *ptr_Test = &test; cout test_int test_char tetst_double system("pause"); return 0; }

<< ptr_Test -> test_char << ' '
<< ptr_Test -> tetst_double << endl;
system("pause");
return 0;
}

Слайд 6

Указатели

- с помощью значения другого инициализированного указателя
float var_float = 3.55f;
float *ptr_float_1 =

Указатели - с помощью значения другого инициализированного указателя float var_float = 3.55f;
&var_float;
float *ptr_float_2 = ptr_float_1;

Слайд 7

Указатели

- с помощью имени массива
unsigned array_int[] = {33, 51, 78, 4, 15};
int

Указатели - с помощью имени массива unsigned array_int[] = {33, 51, 78,
main()
{
unsigned *ptr_array = &array_int; // & - не обязательно
cout << *(ptr_array + 3) << endl;
system("pause");
return 0;
}

Слайд 8

Указатели

Известно, что имя массива является указателем на его первый элемент, поэтому следующие

Указатели Известно, что имя массива является указателем на его первый элемент, поэтому
выражения эквивалентны:
cout << *ptr_array << endl;
cout << *array_int << endl;
В обоих случаях получим значение первого элемента массива.

Слайд 9

Указатели

- с помощью имени функции
void func(int,char){ // ……};
void (*ptr_fun)(int,char) = &func;
Знак операции

Указатели - с помощью имени функции void func(int,char){ // ……}; void (*ptr_fun)(int,char)
взятия адреса & здесь также не обязателен, так как имя функции трактуется как адрес ячейки памяти, начиная с которого находится объектный код данной функции.

Слайд 10

Указатели

2. Присваивание указателю адреса области памяти в явном виде:
char *vp = (char

Указатели 2. Присваивание указателю адреса области памяти в явном виде: char *vp
*)0xB8000000;
int main()
{
cout << *vp << endl; // ???????
system("pause");
return 0;
}

Слайд 11

Указатели

3. Присваивание пустого указателя:
short *ptr_short = NULL;
long *ptr_long = 0;
4. Выделение участка

Указатели 3. Присваивание пустого указателя: short *ptr_short = NULL; long *ptr_long =
динамической памяти:
- с помощью операции new:
int *p_i = new int;

Слайд 12

Указатели

Здесь в динамической памяти выделяется место для хранения величины типа int.
int *p_j

Указатели Здесь в динамической памяти выделяется место для хранения величины типа int.
= new int(100);
Здесь помимо выделение памяти, заносится значение 100.
int *p_array new int[10];
Здесь выделяется место в динамической области памяти для хранения массива целых чисел.

Слайд 13

Указатели

- с помощью функции malloc:
int *p_i = (int *)malloc(sizeof(int));
Функция malloc заимствована из

Указатели - с помощью функции malloc: int *p_i = (int *)malloc(sizeof(int)); Функция
языка С, тем не менее, она работает.
При работе с динамической областью памяти необходимо следить за тем, чтобы указатель не вышел за пределы области видимости. В этом случае память отведенная под указатель освобождается, указатель обнуляется, а переменная становится недоступной.

Слайд 14

Указатели

На программистском сленге это означает появление «мусора» в памяти.
Полезный совет при попытке

Указатели На программистском сленге это означает появление «мусора» в памяти. Полезный совет
выделения памяти в динамической области. Проверяйте значение указателя после выполнения операции new или функции malloc на равенство нулю. Если указатель нулевой, то операционной системе не удалось найти достаточного свободного объема. Это предотвратит последующие ошибки.

Слайд 15

Указатели

int main()
{
float *ptr_float = new float(67.44f);
if(!ptr_float)
{
cout << " Недостаточно памяти " <<

Указатели int main() { float *ptr_float = new float(67.44f); if(!ptr_float) { cout
endl;
exit(1);
}
else cout << " Ok " << endl;
system("pause");
return 0;
}

Слайд 16

Указатели

Операции над указателями
Как уже было сказано, указатели – переменные, хранящие адреса ячеек

Указатели Операции над указателями Как уже было сказано, указатели – переменные, хранящие
памяти, то есть, величины, относящиеся к без знаковому целому типу. Не сложно догадаться, что к величинам данного типа применимы арифметические операции, но не все. Кроме того над ними допускаются и другие операции.

Слайд 17

Указатели

Определим основные операции допустимые над указателями:
операция разадресации (разыменования), косвенное обращение к объекту

Указатели Определим основные операции допустимые над указателями: операция разадресации (разыменования), косвенное обращение
(*);
присваивание;
сложение с константой;
вычитание константы;
инкремент (--);
декремент (++);

Слайд 18

Указатели

сравнение;
приведение типов.
При работе с указателями очень часто используется операция получения (взятия) адреса

Указатели сравнение; приведение типов. При работе с указателями очень часто используется операция
(&).
Основной операцией над указателями является операция разадресации или разыменования, которая предназначена для доступа к величине, на которую указывает указатель.

Слайд 19

Указатели

Эта операция симметрична, то есть с ее помощью можно получить значение объекта

Указатели Эта операция симметрична, то есть с ее помощью можно получить значение
или изменить его.
Рассмотрим пример:
int main()
{
typedef unsigned long int UINT;
//
UINT *ptr_UINT = new UINT(12L);
// объявление и инициализация указателя на объект UINT
cout << " Величина UINT " << *ptr_UINT << endl;
// получение значения по указателю
return 0;
}

Слайд 20

Указатели

Эта операция применима только к указателям на объект какого-либо типа и на

Указатели Эта операция применима только к указателям на объект какого-либо типа и
тип void. К указателям на функцию она не имеет смысла.
Арифметические операции над указателями, в частности, сложение с константой, вычитание константы, инкремент, декремент допустимы, но не над всеми видами указателей.

Слайд 21

Указатели

Например, при работе с массивами они допустимы, а с указателями на обычные

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

Слайд 22

Указатели

Рассмотрим пример использования арифметических операций:
float array_float = {3.2, -44.6, -0.073, 12, 5.0};
//

Указатели Рассмотрим пример использования арифметических операций: float array_float = {3.2, -44.6, -0.073,
….
float summa_array(float arr[])
{
float rez = 0;
for(int i =0; i<5; i++)
rez += *(arr+i); //сложение указателя с константой
return rez;
}

Слайд 23

Указатели

Операции инкременты, декремента, вычитание константы рассмотреть самостоятельно.
Важную операцию представляет операция преобразования указателей.

Указатели Операции инкременты, декремента, вычитание константы рассмотреть самостоятельно. Важную операцию представляет операция
Преобразование указателей в С++ допускается двумя способами:
унаследованным от языка С. Общий формат оператора преобразования следующий:
(тип *) имя_указателя;, или
тип * (имя_указателя);.

Слайд 24

Указатели

- в стиле языка С++, используя операции static_cast, dynamic_cast, reinterpret_cast, например,
static_cast

Указатели - в стиле языка С++, используя операции static_cast, dynamic_cast, reinterpret_cast, например,
*> (ptr_int);
Операции преобразования широко используются при преобразовании в иерархии родственных классов в условиях наследования.

Слайд 25

Указатели

Обычно операция преобразования используется при выполнении операции присваивания. Присваивание без явного преобразования

Указатели Обычно операция преобразования используется при выполнении операции присваивания. Присваивание без явного
допускается если в левой части выражения используется указатель на тип void или типы указателей совпадают. Значение 0 неявно приводится к указателю на любой тип.
Присваивание указателей на объекты указателям на функции и наоборот не допускается.

Слайд 26

Ссылки

Ссылки
Ссылка (ссылочный тип данных) – синоним имени, указанного при инициализации ссылки. Ссылку

Ссылки Ссылки Ссылка (ссылочный тип данных) – синоним имени, указанного при инициализации
можно рассматривать как указатель, который не надо разыменовывать. Формат объявления ссылки следующий:
тип_ссылки &имя_ссылки = инициализация;

Слайд 27

Ссылки

Пример объявления ссылки:
int var_int = 57;
int &ref_int = var_int;
const char &ref_char =

Ссылки Пример объявления ссылки: int var_int = 57; int &ref_int = var_int;
‘\n’;
Следует запомнить следующие правила определения и использования ссылок:
- переменная-ссылка должна явно инициализироваться при ее описании, кроме случаев, когда она является параметром функции, описана как extern или ссылается на поле данных класса;

Слайд 28

Ссылки

- тип ссылки должен совпадать с типом величины, на которую она ссылается;
-

Ссылки - тип ссылки должен совпадать с типом величины, на которую она
не разрешается определять указатели на ссылки, создавать массивы ссылок и ссылки на ссылки.
Ссылки применяются чаще всего в качестве параметров функций и типов возвращаемых функциями результатов

Слайд 29

Ссылки

Ссылки позволяют использовать в функциях переменные, передаваемые по адресу, без операции разыменования,

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

Слайд 30

Массивы

При использовании простых переменных каждой области памяти для хранения данных соответствует свое

Массивы При использовании простых переменных каждой области памяти для хранения данных соответствует
имя. Если с группой величин (объектов) необходимо выполнить однообразные действия, им дают одно имя, а различают по порядковому номеру (индексу). Конечная именованная область памяти, содержащая однотипные элементы, называется массивом.

Слайд 31

Массивы

Общий формат описания массива:
тип_массива имя_массива[размерность] =
{инициализация};
Массивы в С++ имеют ряд особенностей:
нумерация (индексация)

Массивы Общий формат описания массива: тип_массива имя_массива[размерность] = {инициализация}; Массивы в С++
элементов начинается с нуля;
компилятор не отслеживает границ массива.

Слайд 32

Массивы

Примеры объявлений массивов:
double array_double[20];
// объявление массива из 20 чисел типа double
int array_int[10]

Массивы Примеры объявлений массивов: double array_double[20]; // объявление массива из 20 чисел
= {34, 86, -53, 1024, 0, -778};
// объявление массива из 10 целых чисел с инициализацией
int array_int[] = {553, 749, -503, 46, 120, 59};
// тоже, но без указания размерности

Слайд 33

Массивы

Рассмотрим пример:
int array_int[10] = {32, -453, 6, 562, -322, 78};
int main()
{
for(int i=0;

Массивы Рассмотрим пример: int array_int[10] = {32, -453, 6, 562, -322, 78};
i<=5; i++)
cout << " Array: " << array_int[i] << ' ';
cout << endl;
return 0;
}

Слайд 34

Массивы

Здесь объявлен массив целых чисел array_int[10] и инициализирован значениями. Инициализация массива осуществлена

Массивы Здесь объявлен массив целых чисел array_int[10] и инициализирован значениями. Инициализация массива
не полностью, только первые 6 элементов. Все остальные заполняются нулями целого типа. Если при объявлении не указана размерность, инициализация массива обязательна.

Слайд 35

Массивы

Обращение к элементам массива можно осуществлять двумя способами:
с помощью операции индексирования –

Массивы Обращение к элементам массива можно осуществлять двумя способами: с помощью операции
[n], как в приведенном выше примере;
через указатель.
Как уже было сказано, имя массива компилятором понимается как указатель на его первый элемент.

Слайд 36

Массивы

Поэтому выражение
cout << " Array: " << array_int[i] << ' ';
можно

Массивы Поэтому выражение cout можно записать в следующем виде: cout В памяти
записать в следующем виде:
cout << " Array: " << *(array_int+i) << ' ';
В памяти машины все элементы массива будут расположены в последовательных ячейках ОЗУ.

Слайд 37

Массивы
Размерность массива принято задавать с помощью именованных констант, например:
const int n_str=10, n_stb=15;,
поскольку

Массивы Размерность массива принято задавать с помощью именованных констант, например: const int
при таком подходе значение константы достаточно скорректировать только в одном месте.

32

-453

6

562

-322

0

78

0

0

0

array_int *

Слайд 38

Массивы

Многомерные массивы
Многомерные массивы задаются указанием каждого измерения в отдельных квадратных скобках, например,
int

Массивы Многомерные массивы Многомерные массивы задаются указанием каждого измерения в отдельных квадратных
matr[6][8];.
Здесь задается двумерный массив целых чисел, состоящий из 6 строк и 8 столбцов.

Слайд 39

Массивы

Инициализация многомерного массива также допускается, например,
int arr_int[3][3] = {{1,2,3}, {2,3,4}, {3,4,5}}; или

Массивы Инициализация многомерного массива также допускается, например, int arr_int[3][3] = {{1,2,3}, {2,3,4},
же:
int arr_int[3][3] = {1,2,3,2,3,4,3,4,5};
Для доступа к многомерному массиву можно использовать операцию индексирования -
arr_int[2,1] или посредством указателя - *(*(arr_int+2)+1).

Слайд 40

Массивы

Многомерные массивы размещаются в памяти так, что при переходе к следующему элементу,

Массивы Многомерные массивы размещаются в памяти так, что при переходе к следующему
быстрее всех изменяется последний индекс.
Массивы можно объявлять в динамической области памяти, например,
const int nstr =5, nstb =6;

Слайд 41

Массивы

int **array_int = new int *[nstr];
for(int i=0; i array_int[i] = new int[nstb];

Массивы int **array_int = new int *[nstr]; for(int i=0; i array_int[i] = new int[nstb];

Слайд 42

Массивы

Строки
Строка – это массив символов, заканчивающийся нуль-символом (‘\0’).
По положению нуль-символа компилятор определяет

Массивы Строки Строка – это массив символов, заканчивающийся нуль-символом (‘\0’). По положению
конец строки. В отличие от обычного массива строка занимает на один элемент больше (под нуль-символ).

Слайд 43

Массивы

Рассмотрим простой пример:
char str[10] = "Hello!";
int main()
{
int i=0;
while(str[i] != '\0')
{
cout << str[i];
i++;
}
cout

Массивы Рассмотрим простой пример: char str[10] = "Hello!"; int main() { int
<< endl;
return 0;
}

Слайд 44

Массивы

Строку можно задать как указатель на константную величину:
char *str = "Hello!";
Изменение элементов

Массивы Строку можно задать как указатель на константную величину: char *str =
этой строки не допускается.
Операции над строками можно осуществлять через операторы цикла, кроме того, много операций определено в стандартной библиотеке.
Стандартная библиотека размещена в файле .

Слайд 45

Массивы

До сих пор мы говорили о массивах, содержащих объекты стандартные типы. А

Массивы До сих пор мы говорили о массивах, содержащих объекты стандартные типы.
можно ли создавать массивы объектов пользовательского типа?
Рассмотрим пример простой структуры:
struct Student
{
string Name;
int Age;
};

Слайд 46

Массивы

Объявим массив типа Student:
Student arr_Student[10];
Воспользуемся этим массивом
arr_Student[0].Name = "Иван";
arr_Student[0].Age =

Массивы Объявим массив типа Student: Student arr_Student[10]; Воспользуемся этим массивом arr_Student[0].Name =
20;
arr_Student[1].Name = "Маша";
arr_Student[1].Age = 19;

Слайд 47

Массивы

Заметим, что отличия в обращении к элементам такого массива есть, в частности,

Массивы Заметим, что отличия в обращении к элементам такого массива есть, в
используется операция доступа к полям структуры (‘ . ’).
Еще один вариант обращения – через указатель (имя массива – указатель на его первый элемент):
(arr_Student+2)->Name = "Вася";
(arr_Student+2)->Age = 19;

Слайд 48

Массивы

И здесь есть отличие – использование операции доступа ‘ -> ’ производит

Массивы И здесь есть отличие – использование операции доступа ‘ -> ’
автоматическое разыменование указателя и поэтому символ звездочки перед указателем не ставится.

Слайд 49

Массивы

Следующий пример связан с объявлением массива указателей на функции.
Предположим, что есть

Массивы Следующий пример связан с объявлением массива указателей на функции. Предположим, что
ряд одинаковых функций, выполняющих разные действия:
int add(int a, int b)
{
return a+b;
}

Слайд 50

Массивы

int sub(int a, int b)
{
return a-b;
}
int mul(int a, int b)
{
return a*b;
}

Массивы int sub(int a, int b) { return a-b; } int mul(int

Слайд 51

Массивы

Объявим массив указателей на функции:
typedef int (*PF)(int,int);
PF ptr_fun[5] = {&add, &sub, &mul,0,0};
Теперь

Массивы Объявим массив указателей на функции: typedef int (*PF)(int,int); PF ptr_fun[5] =
можно вызывать функции, обращаясь к элементам массива:
int v_int_1 = 10, v_int_2 = 5;
cout << (ptr_fun)[0](v_int_1, v_int_2) << endl;
cout << (ptr_fun)[1](v_int_1, v_int_2) << endl;
cout << (ptr_fun)[2](v_int_1, v_int_2) << endl;

Слайд 52

Массивы

Результат посмотреть обязательно.
Следующий вариант вызова функции в работу – через указатель:
cout <<

Массивы Результат посмотреть обязательно. Следующий вариант вызова функции в работу – через указатель: cout
(*(ptr_fun+1))(v_int_1, v_int_2) << endl;

Слайд 53

Массивы

Массивы

Слайд 54

Массивы

Массивы

Слайд 55

Массивы

Массивы

Слайд 56

Массивы

Массивы

Слайд 57

Массивы

Массивы
Имя файла: Указатели-и-массивы.pptx
Количество просмотров: 29
Количество скачиваний: 0