384.00K
Категория: ПрограммированиеПрограммирование

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

1.

Контроль знаний
1. Дайте определение массива.
2. Заполните пробелы в следующих утверждениях
а) Элементы массива связаны тем, что они имеют
одно и то же ________ и _______.
б) Число, используемое для обращения к
отдельному элементу массива, называется
___________.
в) Для объявления размера массива должна
использоваться _______.
г) Процесс упорядоченного размещения
элементов в массиве называется ______.

2.

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

3.

Контроль знаний
4. Найдите и исправьте ошибку в каждом из следующих
фрагментов
а) #include<iostream.h>;
б) arraySize = 10; // arraySize ранее объявлена как константа
в) int array[10] = {0};
for (int i = 0; i <=10; i++) array[i] = 5;
г) int N=5;
float Y[N] = {2, 3 , 4};
5. Допустим, что int A[7] = {5, 6, 2, 1, 5, 7, 9}, B[7];
Напишите программный код для задачи :
«Присвоить элементы массива А массиву B »

4.

МАССИВЫ и УКАЗАТЕЛИ
Лекция 7
Растопшина Т.С.

5.

Описание переменных
Область памяти, отведенная для
хранения данных делится на три части:
•Сегмент данных (глобальные переменные)
•Стек (локальные переменные)
•Динамически распределяемая область
Глобальные - описанные вне блоков;
Локальные - описанные внутри блоков

6.

Описание переменных
int a;
// глобальная переменная
int main( )
{
// локальная статическая переменная
static int b = 1;
int c;
// локальная переменная
return 0;
}

7.

int a;
int main( )
{ static int b = 1;
int c;
return 0;
}
Имя
Размещение
Время жизни
// глобальная переменная
// локальная статическая переменная
// локальная переменная
Глобальная Локальная
статическая
a
b
сегмент
сегмент
данных
данных
вся
вся
программа программа
файл
блок
Область
видимости
Инициализация да
да
Локальная
c
сегмент стека
блок
блок
нет

8.

9.

Классы памяти
auto – это автоматические переменные
которые создаются в стеке при входе в
блок и освобождаются при выходе из нее;
static - располагаются в фиксированном
блоке памяти, выделяемом перед началом
выполнения программы,
инициализируются нулевым значением;
Для переменных целого типа определен
класс register.

10.

Блок А
Блок B
Блок C
Блок D
Блок F
Блок E

11.

12.

Указатели
В С++ есть три вида указателей, отличающихся
свойствами и набором допустимых операций:
- типизированные указатели,
- бестиповые указатели
- указатели на функцию.

13.

Указатели
Указатель – переменная, которая во время
работы программы содержит адреса других
переменных.
Описываются
символа *:
Тип * имя;
указатели
при
помощи

14.

int *q;
// переменная q представляет
// собой указатель на тип int
unsigned int * a; // переменная а представляет
// собой указатель на тип unsigned int
double * x; // переменная х указывает на тип
//данных с плавающей точкой
//удвоенной точности
char * fuffer ; // объявляется указатель с именем
//fuffer который указывает на
// переменную типа char

15.

При помощи операции получения адреса
(&)
указатель
устанавливается
на
существующую переменную:
int *q;
int r = 1;
q = & r;
// q – адрес переменной r, где
//хранится число 1.
int k= *q; // k=1
&r
q
1
r , *q
1
k

16.

Указатели можно инициализировать нулем, адресом
переменной того же типа, адресом поля структуры
того же типа или значением другого указателя:
int a = 3;
// инициализация целой переменной a
int *pa = &a; // инициализация указателя pa адресом a
int *h ( &a ); // инициализация указателя h адресом a
int *r = h;
// инициализация другим указателем
string *ps = 0; // нулевой указатель на строку
vector<string> *pv = NULL; // нулевой указатель на
// вектор строк

17.

Опишем массив и указатель
int а[5] = {1, 2, 3, 4, 5};
int *p = а;
а и p – указатель первого элемента
массива а[0]
&a[0]
p
1
a , *p
2
3
4
5

18.

Арифметика указателей
•Сравнение указателей
р= =q, р !=q;
•Сложение указателя с числом
Следующие выражения эквивалентны:
a[0] *q;
a[1] *(q+1);

a[n-1] *(q+n-1);

19.

Арифметика указателей
• Вычитание из указателя целого числа;
• Операции ++ и - - :
++q,
q++;
•Разность двух указателей :
дает количество элементов
соответствующего типа в промежутке
между двумя указателями.

20.

int main( )
{
char *t = "text";
char *q = t;
cout << "Pointer *q" << endl;
while (*q) cout << *q++; //Вывод строки посимвольно
cout << "\nLength: " << q - t <<endl;
return 0;
}

21.

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

22.

Указатели и динамическая память
Любой динамический объект не имеет явного имени
и доступен только косвенно — через указатель.
Время жизни динамической переменной не зависит
от локальности и глобальности, а видимость
определяется областью видимости указателя,
который на нее ссылается.
Для
создания
динамической
переменной
используется операция new, для уничтожения —
операция delete.

23.

Выделение памяти под переменную в
процессе работы программы :
new тип;
Например:
int *q = new int;
int *p = new int[n];

24.

Освобождается выделенная область памяти
оператором
delete
Например:
delete q;
delete [ ] p;

25.

int main( )
{ const int n = 10;
int *q, *p= new int [n];
int i=0 ;
for (q=p, i=0; i<n; i++)
cout << (*q++ = rand( ) % 100) << endl;
delete[ ] p;
return 0;
}

26.

СОРТИРОВКА МАССИВА
6
4
3
7
11
6
4
3
7
11
4
6
3
7
11
3
6
4
7
11
3
6
4
7
11
А
1 этап

27.

2 этап
3
6
4
7
11
3
4
6
7
11
3
4
6
7
11
3
4
6
7
11
3
4
6
7
11
3
4
6
7
11
А
3 этап
4 этап

28.

int main( )
{ const int n =5;
int A[n] = {6, 4, 3, 7, 11};
for ( int i = 0; i < n-1; i++) // сортировка
for (int j = i+1; j < n; j++)
if ( A[i] > A[j] )
{int z = A[i]; A[i] = A[j]; A[j] = z;}
cout << Rus("Новый массив ",s) << endl;
for( i = 0; i < n; ++i) cout << A[i] << " ";
return 0;}

29.

int main( )
{ const int n = 10;
int *q, *p= new int [n];
int i , j, z;
cout << Rus("Исходный массив ",s) << endl;
for (q=p, i=0; i<n; i++)
cout << (*q++ = rand( ) % 100) << " ";
cout<<endl;

30.

for ( i = 0; i < n-1; i++) // сортировка
for ( j = i+1; j<n; j++)
if (p[i]>p[j])
{ z = p[i]; p[i] = p[j]; p[j] = z;}
cout << Rus("Новый массив ",s) << endl;
for ( i = 0; i < n; ++i) cout << p[i] << " ";
cout<<endl;
delete[ ] p;
return 0; }

31.

Многомерные МАССИВЫ
Тип имя [размер1] [размер2]…
Например, двумерный массив
double q[3][4];
q[0][0] q[0][1] q[0][2] q[0][3] q[1][0] q[1][1]
double x;
x = *q;
// x = q[0][0]
x = *(q+2); // x = q[0][2]
x = *(q+4); // x = q[1][0]
...
q[2][3]

32.

Инициализация многомерного массива
int A[3][3] = { {1,2,3}, {2,3} };
int A[3][3] = { 1,2,3,2,3 };
int A[][3] = { {1,2,3}, {2,3} };
A[0]
A[1]
1
2
3
2
3
0
A[0][0]
A[0][1]
A[0][2]
A[1][0]
A[1][1]
A[1][2]

33.

Ввод элементов двумерного
массива
const int n=3;
int A[n][n];
int i, j;
cout<<endl<< Rus("Ввод массива", s)<<endl;
for ( i=0; i<n; i++)
for ( j=0; j<n; j++)
{
cout << "A [" << i+1 << ',’ << j+1 << "] ->";
cin >> A[ i ] [ j ];
}

34.

Заполнение массива
случайными числами
const int n=3;
int A[n][n];
int i, j;
srand (time(NULL));
for ( i=0; i<n; i++)
for ( j=0; j<n; j++)
A[i][j] = rand()%100-50;

35.

Вывод двумерного массива
for ( i = 0; i < n; i++)
{ cout << endl;
for ( j = 0; j < n; j++)
cout << setw(4) << A[i][j];
}
cout<<endl;

36.

Пример: Найти максимальный
элемент двумерного массива
и его индексы
const int n_max = 50;
int A[n_max][n_max];
int i, j, n;
srand (time(NULL));
cout<< "Введите размер массива (nxn) -> ";
cin >> n;

37.

cout<<endl<< "Массив заполнен
cлучайными числами"<<endl;
for ( i = 0; i < n; i++)
{ cout<<endl;
for ( j=0; j<n; j++)
{
A[i][j]
= rand()%100-50;
cout << setw(4) <<A[i][j];
}
}
int max = A[0][0], maxi = 0, maxj = 0;

38.

for ( i = 0; i < n; i++)
for ( j = 0; j < n; j++)
if (max < A[i][j])
{ max = A[i][j]; maxi = i; maxj = j; }
cout<< "Максимальный элемент в
массиве: " << max << endl;
cout<< "Он находится в " << maxi+1 ;
cout<< " строке и " << maxj+1;
cout << " столбце."<< endl;

39.

40.

Пример. Заполнить массив М размером
n*m следующим образом, например, n=6 и
m=8:
1 2 3 4 5 6 7 8
16 15 14 13 12 11 10 9
17 18 19 20 21 22 23 24
32 31 30 29 28 27 26 25
33 34 35 36 37 38 39 40
48 47 46 45 44 43 42 41
(То есть заполняется в виде “змейки”.)

41.

const int n_max=50;
int A[n_max+1][n_max+1];
int i, j, n, m;
srand (time(NULL));
cout<< Rus("Введите размер массива (nxm) ",
s);
cin>>n>>m;

42.

for ( i = 1; i < n+1; i++)
{
cout<<endl;
for ( j = 1; j < m+1; j++)
{ if ( i&1 ) A[i][j] = (i-1)*m+j;
else A[i][j] = i*m-j+1;
cout << setw(4) <<A[i][j];
}
}
cout<<endl;

43.

44.

Тип имя [размер1] [размер2]…
Например, двумерный массив
double q[3][4];
q[0][0] q[0][1] q[0][2] q[0][3] q[1][0] q[1][1]
double x;
x = *q;
// x = q[0][0]
x = *(q+2); // x = q[0][2]
x = *(q+4); // x = q[1][0]
...
q[2][3]

45.

Динамическое выделение памяти
При выделении динамической памяти для
двумерного массива нам потребуется
описать указатель на указатель **q,
поскольку здесь *q должен быть массивом
указателей на строки массива

46.

Схема выделения памяти
int **q
q
int *[10]
q[0]
q[1]
int [10][10]
q[0][0] q[0][1]
... q[0][9]
q[1][0] q[1][1]
...
q[1][9]
q[9][0] q[9][1]
...
q[9][9]
...
q[9]

47.

int i, j, n=10;
int **q = new int *[n];
for (i = 0; i < n; i++) q [ i ] = new int [n];
for (i = 0; i < n; i++)
{ for ( j = 0; j < n; j++)
{ q [ i ][ j ] = j;
cout << q [ i ][ j ] << ’ \t ';
}
cout << endl;
}
for (i = 0; i < n; i++) delete [ ] q [ i ];
delete [ ]q;

48.

Функция,
выводящая массив на экран:
void Vyvod(int *mas, int n)
{
for(int i=0; i<n; i++)
cout << mas[i] << " ";
cout <<endl;
}

49.

Функция,
выводящая массив на экран:
void Vyvod(int **mas, int n)
{
for(int i=0; i<n; i++)
{
for(int j=0; j<n; j++)
cout << setw(4) << mas[i][j];
cout <<endl;
}
}
English     Русский Правила