Цель изучения темы: изучить работу с массивами и указателями.
- описание массива
- многомерные массивы
- указатели
Описание массива
В C++ можно определить массив любого типа.
int mas[3];
Описан массив из 3 целых чисел.
Нумерация в массивах начинается с 0-го элемента. Поэтому массив mas содежит: mas[0], mas[1], mas[2]
Массив можно инициализировать при описании. В этом случае нет необходимости указывать его размер.
int mas[]={23, 25, 81};
Далее создан массив mas из 3-х элементов:
mas[0]= 23,
mas[1]= 25,
mas[2]= 81.
char city [ ] = "Москва";
Массив city будет содержать строку из 7 элементов: 6 букв и 0-символ. 0-символ является признаком конца строки, в программе он обозначается \0.
Такой способ инициализации не подходит, если в дальнейшем в массив city потребуется занести название другого города с длинным названием.
Можно описать название города по-другому.
char city1[ ] = {'М', 'о', 'с' , 'к' , 'в' , 'а' }
Массив city1 - это массив символов, он будет содержать 6 элементов
Таблица 1.7.1.
№ |
City |
№ |
City1 |
---|---|---|---|
0 |
М |
0 |
М |
1 |
О |
1 |
о |
2 |
С |
2 |
с |
3 |
К |
3 |
к |
4 |
В |
4 |
в |
5 |
А |
5 |
а |
6 |
/0 |
|
|
Вышеописанный способ инициализации возможен только при объявлении массива. В программе используйте поэлементную инициализацию.
city [0]='м';
Кроме стандартного доступа к элементам массива C++ обеспечивает еще один. В C++ имя массива представляет собой не только имя, которое вы используете в своих программах, но и является адресом, по которому в памяти находится первый элемент массива. Поэтому к элементам массива можно обращаться следующими способами:
int m[6] = {4, 3 , 1, 4, 7, 8 };
m[3] или (m + 3)[0] Обращение к 4-му элементу массива.
Возможны и другие варианты:
(m + 0)[3]
(m + 2)[1]
(m - 2)[5]
Наиболее полезно использовать такой подход к массивам, содержащим символьные строки.
Пример.
char names [ ]={'Иван', 'Петр', 'Елена' }
будет выглядеть в памяти следующим образом:
Таблица 1.7.2.
0 |
И |
1 |
В |
2 |
А |
3 |
Н |
4 |
\0 |
5 |
П |
6 |
Е |
7 |
Т |
8 |
Р |
9 |
\0 |
10 |
Е |
11 |
Л |
12 |
Е |
13 |
Н |
14 |
А |
15 |
\0 |
Команда cout << names; выведет Иван (до признака конца строки)
cout << names+5; выведет Петр.
Многомерные массивы
Многомерные массивы - это массивы с более чем одним индексом.
Чаще всего используются двумерные массивы.
При описании многомерного массива необходимо указать C++, что массив имеет более чем одно измерение.
Пример 1.
int t[3][4];
Описывается двумерный массив, из 3 строк и 4 столбцов.
Элементы массива:
t[0][0] t[0][1] t[0][2] t[0][3]
t[1][0] t[1][1] t[1][2] t[1][3]
t[2][0] t[2][1] t[2][2] t[2][3]
При выполнении этой команды под массив резервируется место. Элементы массива располагаются в памяти один за другим.
Пусть это линейка памяти:
Рисунок 1.7.1.
Пример 2.
int temp [3] [15] [10];
резервируется место под 3-х мерный массив.
В памяти многомерные массивы представляются как одномерный массив, каждый из элементов которого, в свою очередь, представляет собой массив.
Рассмотрим на примере двумерного массива.
int a[3][2]={4, l, 5,7,2, 9};
Представляется в памяти:
Таблица 1.7.3.
a[0][0] |
заносится значение 4 |
a[0][1] |
заносится значение 1 |
a[1][0] |
заносится значение 5 |
a[1][1] |
заносится значение 7 |
a[2][0] |
заносится значение 2 |
a[2][1] |
заносится значение 9 |
Второй способ инициализации при описании массива
int а[3][2]={ {4,1}, {5, 7}, {2, 9} };
Обращение к элементу массива производится через индексы.
cout<< а[0][0];
Выдаст значение 4.
cout << a[1][1];
Выдаст знaчение 7.
Программа, которая инициализирует массив и выводит его элементы на экран.
#include <iostream.h>
main ()
{
int a[3] [2]={
{1,2}, {3,4}, {5,6}
};
int i,j;
for (i=0; i<=2; i++)
for(j=0;j<=l;j++)
cout <<"\n a["<< i <<"," << j <<"] ="<< a[i]|j];
return 0;
}
Для того, чтобы убрать из программы явные значения размера и массива, можно воспользоваться директивой define
#include < iostream.h>
#define I 3
#define J 2
main()
{ int a[I][J]={ {l,2}, {3,4}, {5,6} };
int i, j;
for ( i=0 ; i< I; i++)
for( j=0; j< J; j++)
cout <<"\n a["<< i <<"," << j << "] ="<< a[i][j];
return 0;
}
При передаче массива в функцию всегда происходит передача его адреса. Т.о. в C++ все массивы передаются по адресу.
Пример.
Вводится квадратная матрица с максимальным размером 10 на 10. Ввод матрицы оформлен в виде отдельной функции vvod. Программа заменяет все отрицательные числа их модулями.
#include <iostream.h>
void vvod (int u[10][10], int n)
{
int i,j;
for (i=0; i<n; i++)
{ cout <<"\nVvedi "<< i<<" stroky";
for (j=0; j< n; j++)
cin>> u[i][j];
}
}
void main()
{
int a[10][10];
int n,i,j,min;
cout<<"\nВведите количество строк и столбцов";
cin>>n;
vvod(a, n);
for (i=0; i< n; i++)
for (j=0; j< n; j++)
if (a[i][j] < 0) a[i][j]=-a[i][j];
// Вывод матрицы
cout <<"\n";
for (i=0; i< n; i++)
{
for (j=0; j< n; j++)
cout<< u[i][j]<<" ";
cout<<"\n";
}
}
Принимающая функция получает не весь массив, а только адрес первогоэлемента массива. Несмотря на то, что в блоке main массив называется а, а в функции vvod - u это один и тот же массив.
Указатели
Указатели - это переменные, которые содержат адрес адреса данных. В С++ указатели могут быть на любой тип данных.
Если необходимо, можно описать массив указателей.
int*ip[ 10 ];
массив указателей на целые значения из 10 элементов.
С указателем можно производить некоторые арифметические операции. Например, при работе с массивами.
Пусть sub содержит номер элемента массива, тогда до этого элемента можно "добраться"
mas [ sub ]
или
*(mas +sub)
Т.к. имя массива фактически является указателем на нулевой элемент массива. Переменная sub указывает на сколько элементов необходимо сместиться. Вы можете инкрементировать и декрементировать указатель. При этом вы смещаетесь на один элемент, независимо от типа элемента.
Допустим uk адрес нулевого элемента массива, тогда
cout<<*uk; // вывод значения 0-го элемента
uk++;
cout<<*uk; // вывод значения 1-го элемента, реально смещение на несколько байтов
uk+=2
cout<<*uk; // вывод значения 3-го элемента.
Наиболее полезное применение массивов указателей - это массив указателей на строки.
Пример.
char names [3] [20]= {
{"Иванов"},
{"Петров"},
{"Сидоров "}
};
Схематично можно изобразить следующим образом
Рисунок 1.7.2.
Для вывода строки можно использовать
cout<< *names; //Печать Иванов