Массивы и указатели

Содержание

Слайд 2

Не все компиляторы позволяют определять размер массива переменной величиной:
int n;
cin >>

Не все компиляторы позволяют определять размер массива переменной величиной: int n; cin
n;
float arr[n]; /* Неверно */
При создании статического массива, для указания его размера может использоваться только константа. Размер выделяемой памяти определяется на этапе компиляции и не может изменяться в процессе выполнения.

Массивы

Слайд 3

const int n=10;
float arr[n]; /* Верно */
Индекс массива определяет используемый элемент

const int n=10; float arr[n]; /* Верно */ Индекс массива определяет используемый
массива и указывается в квадратных скобках после имени массива.
Индекс массива – это целочисленное выражение, значение которого может быть в диапазоне от 0 до значения, равного размерности, уменьшенной на 1.
arr[0] arr[1] … arr[9]

Массивы

Слайд 4

Выход за границу массива – обращение к элементу массива, индексы которого выходят

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

Массивы

Слайд 5

В Си понятие массив и указатель взаимосвязаны.
Имя массива, воспринимается как адрес,

В Си понятие массив и указатель взаимосвязаны. Имя массива, воспринимается как адрес,
начиная с которого хранится массив. Этот адрес нельзя изменить, так как имя статического массива является указателем-константой.
Итак, имя массива – это адрес первого элемента массива (с индексом 0),
то есть для массива: int a[10];
a ~ &a[0]
Имя статического массива по определению имеет атрибут const, поэтому не может быть изменен, к нему не может быть применена операция инкремент: a ++

Связь между указателями и массивами фиксированного размера

Слайд 7

имя массива указатель-константа, нельзя изменять

>

имя массива указатель-константа, нельзя изменять >

Слайд 8

В общем случае доступ к заданному элементу массива можно осуществлять двумя способами:

В общем случае доступ к заданному элементу массива можно осуществлять двумя способами:

имя_массива[номер элемента]
a[3] //привычный способ
или
*(имя_массива+номер элемента)
*(a+3) или *(3+a) // через указатель
Например, обращение к элементу a[i] возможно как *(a+i) или *(i+a), а также i[a]

Связь между указателями и массивами фиксированного размера

Слайд 9

Связь между указателями и массивами

Элемент массива a[i] есть элемент массива, на который

Связь между указателями и массивами Элемент массива a[i] есть элемент массива, на
указывает значение *(a+i), где значение а является адресом элемента массива a[0].
Выражение a+i является примером арифметических действий с указателями – целое значение i складывается со значением указателя, адресом первого элемента массива.
Значение этого выражения есть а плюс объем памяти, занимаемый i элементами массива.

Слайд 10

[0]

int ma[4], i=0;
ma[i] = i;
*(ma + i) = i;
i[ma]

[0] int ma[4], i=0; ma[i] = i; *(ma + i) = i; i[ma] = i;
= i;

Слайд 11

Пример:
#include
#include
using namespace std;
int main ()
{
int a[] = {3, 5,

Пример: #include #include using namespace std; int main () { int a[]
1, 6, 2, 4, 8, 3, 7, 2};
cout<<"elementi massiva \n ";
for (int i=0; i {
cout<<*(a+i)<<" ";
}
cout< system("pause");
}

обращение к элементам массива через указатели

операция разыменования

Слайд 12

Указатели на многомерные массивы

Многомерные массивы в языке Си – это массивы, элементами

Указатели на многомерные массивы Многомерные массивы в языке Си – это массивы,
которых являются массивы. При объявлении таких массивов в памяти компьютера создается несколько различных объектов.
Пусть x – имя двумерного массива.
x ~ &x[0][0]
Массивы хранятся записанными по строкам, элементы каждой строки занимают непрерывную область памяти.
Таким образом x[i] является указателем на строку массива x (подмассив).
x[i] – адрес первого элемента i-ой строки,
т.е. (x+i)

Слайд 13

Указатели на многомерные массивы

Например, при объявлении двумерного массива
int a[3][4] ;
в памяти

Указатели на многомерные массивы Например, при объявлении двумерного массива int a[3][4] ;
выделяется участок для хранения значения переменной a, которая является указателем на массив из трех указателей a[0], a[1], a[2] на три строки.

Слайд 14

переменная a – является указателем на массив из трех указателей

каждый

переменная a – является указателем на массив из трех указателей каждый из
из трех указателей содержит адрес массива из четырех элементов типа int

Указатели на многомерные массивы

Слайд 15

Связь между указателями и массивами

Для двумерного массива
int a [3][4];
обращение к a

Связь между указателями и массивами Для двумерного массива int a [3][4]; обращение
[2][3] можно заменить на *(a+2*4+3)
для a [i][j] заменить на *(a+i*4+j) или *(*(a+i)+j)
По индукции для ссылки на элемент трехмерного массива x[i][j][k] справедливо выражение: *(*(*(x+i)+j)+k)

число столбцов

число элементов в строке

Слайд 16

Идентификатор двумерного массива - указатель на массив указателей

int a[3][4];
for ( int i

Идентификатор двумерного массива - указатель на массив указателей int a[3][4]; for (
= 0; i < 3; i++ )
for ( int j = 0; j < 4; j++ )
a[i][j] = 10*i+j;
*(a[i] + j) = 10*i+j;
*(*(a + i) + j) = 10*i+j;

Распределение памяти для двумерного массива

2293520

2293536

2293552

massiv6.cpp и massiv61.cpp

Слайд 17

Связь между указателями и массивами

Для иллюстрации работы с массивами и с указателями

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

Слайд 18

Динамические массивы

Часто возникают ситуации, когда заранее не известно, сколько объектов – чисел, строк

Динамические массивы Часто возникают ситуации, когда заранее не известно, сколько объектов –
текста и прочих данных будет хранить программа.
В этом случае используется динамическое выделение памяти, когда память занимается и освобождается в процессе исполнения программы.
Динамическое выделение памяти необходимо для эффективного использования памяти компьютера.

Слайд 19

Функции распределения памяти

Функции распределения памяти

Слайд 20

Динамические массивы

Каждая из функций malloc() и сalloc() резервирует непрерывный блок ячеек для

Динамические массивы Каждая из функций malloc() и сalloc() резервирует непрерывный блок ячеек
хранения указанного объекта и возвращает бестиповый указатель на первую ячейку этого блока.
Функция free(указатель); освобождает ранее резервированный блок и возвращает эти ячейки в динамическую область для последующего использования.

Слайд 21

При динамическом распределении памяти для массивов необходимо сначала описать указатель на массив.
I:

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

1. Описать указатель:
тип *имя_указателя; //указатель на одномерный массив
2. Затем присвоить указателю значение одной из функций:
имя_указателя = (тип *) функция;
II. Другой вариант описание с инициализацией:
тип *имя_указателя = (тип *) функция;

Динамические массивы

Слайд 22

Прототипы функций:
void *calloc( кол-во_элементов, размер_элементов) ;
void *malloc( суммарный_размер_элементов) ;

Динамические массивы

Прототипы функций: void *calloc( кол-во_элементов, размер_элементов) ; void *malloc( суммарный_размер_элементов) ; Динамические массивы

Слайд 23

Динамическое размещение массивов с помощью функции: calloc( )
Выделить память под одномерный массив

Динамическое размещение массивов с помощью функции: calloc( ) Выделить память под одномерный
a[10] из элементов типа int можно следующим образом:
#include //подключить заголовочный файл библиотеки
{ int *a;
a=(int *) calloc(10, sizeof(int));

free(a);
}
Для определения необходимого объема памяти используется функция sizeof:
sizeof (выражение); sizeof (тип);

объявление указателя на одномерный массив

размерность массива

размерность элементов массива

ненужную для дальнейшей работы программы память необходимо освобождать

Слайд 24

Массивы

{ float *pf;
int n=30;
pf=(float *) malloc(n* sizeof(float));

free (pf); //

Массивы { float *pf; int n=30; pf=(float *) malloc(n* sizeof(float)); … free
освобождение памяти:
}

Выделение памяти под одномерный динамический массив:

Слайд 25

Массивы

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

Массивы Для создания двумерного массива сначала необходимо распределить память для массива указателей
одномерные массивы, а затем распределять память для одномерных массивов. Пусть требуется объявить массив a[n][m]:
{float **a;
int n, m, i;
printf("Vvedite razmernosti massiva \n“);
scanf("%d%d",&n,&m);
a=(float **) calloc(n, sizeof(float *));
for (i=0; i a[i] = (float*) calloc(m, sizeof(float));

for (i=0; i free(a[i]);
free (a); }

Слайд 26

Массивы

Выделение памяти под двумерный динамический массив:

{ float **b;
int n=5, m=8;
b=(float **)

Массивы Выделение памяти под двумерный динамический массив: { float **b; int n=5,
malloc(n*sizeof(float*));
for (i=0; i *(b+i) = (float *) malloc(m*sizeof(float));

for (i=0; i free(*(b+i);
free (b); // освобождение памяти:
}

Слайд 27

Кол-во эл-тов умножить на размер эл-тов

Кол-во эл-тов умножить на размер эл-тов

Слайд 28

Массивы

Функции new() и delete встроенные функции С++, поэтому подключение дополнительной библиотеки не

Массивы Функции new() и delete встроенные функции С++, поэтому подключение дополнительной библиотеки
требуется.
{int n=20;
int *parray=new int [n]; //совместили объявление указателя и выделение памяти под массив

delete [] parray; }

Слайд 29

Массивы

new <тип элементов массива>[число_элементов]
Операция new возвратит указатель, значением которого служит адрес

Массивы new [число_элементов] Операция new возвратит указатель, значением которого служит адрес первого
первого элемента массива. При выделении динамической памяти для массива его размеры должны быть полностью определены:
float (*fp) [4]; // объявили указатель на массив
fp=new float [3][4]; //выделили память для двумерного массива
Объявлен указатель на двумерный массив. В определении указателя круглые скобки обязательны. Указатель fp является средством доступа к участку динамической памяти с размерами 3*4*sizeof(float) байтов.
Массив не имеет имя, указатель fp позволяет перемещаться по элементам массива. Для освобождения памяти:
delete [ ] fp;
освободит память, выделенную для двумерного массива, если fp адресует на его начало.

Слайд 30

#include
#include
using namespace std;
int main ()
{ int *ip, x=0, N, M, L;

#include #include using namespace std; int main () { int *ip, x=0,
cout << "Kol-vo strok massiva: "; cin >> N;
cout << "Kol-vo stolbhcov massiva: "; cin >> M;
cout << "Kol-vo znacheniy v stolbhce: "; cin >> L;
ip= new int [N*M*L]; //Резервирование места в куче под одномерный массив
for (int i=0;i for (int j=0;j for (int k=0;k *(ip+i*(M*L)+j*L+k)=++x; //Заполнение массива значениями
cout << “Полученный массив:" << endl;
for (int i=0; i { cout << i << " stroka: " << endl;
for (int j=0; j { cout << '\t' << j << " stolbezh: " << endl;
cout << "\t\t znacheniya: " ;
for (int k=0; k cout << *(ip+i*(M*L)+j*L+k) << " ";
cout << endl; }
}
delete [] ip;
system("pause");}