Помимо одномерных массивов вам может понадобиться для работы использование многомерного массива (двумерного, трёхмерного…). В этом уроке будут рассмотрены двумерные массивы. Они самые распространенные, а остальные встречаются крайне редко.
Мы уже рассматривали в предыдущих статьях одномерные массивы и Си-строки (символьные массивы).Там говорилось, что элементы массива размещаются в памяти последовательно – элемент за элементом. Визуально их можно представить в виде одной строки данных в памяти. Чтобы обратиться к какому-либо элементу такого массива, достаточно указать его имя и индекс элемента. Первое отличие двумерного массива от одномерного – его элементы содержат два индекса: int arr [3][4]; Данные такого массива можно представить, как таблицу: 3 х 4.
Первый за именем массива индекс – это индекс строки, второй – индекс столбца.
Когда вы уже посмотрели на эти рисунки, можно сказать о двумерном массиве так – это массив, в котором каждый элемент также является массивом. int arr [3][4]; – это массив из 3-х элементов, каждый из которых это массив из 4-х элементов.
Данные двумерного массива также располагаются в памяти последовательно, но построчно. Сначала строка с индексом 0 – ячейки от 0-й до 3-й, далее строка с индексом 1 – ячейки от 0-й до 3-й …
Что могут хранить элементы двумерных массивов? Например, можно хранить номера парковочных мест в многоэтажном паркинге (6 этажей и на каждом 15 мест для парковки). Для этого надо объявить двумерный массив int floorsAndParkings[6][15]; и записать в его ячейки номера мест на каждом этаже. Двумерный массив может хранить Си-строки. Например: char someStr [3][256]; Так мы объявили массив, который будет хранить 3 строки по 256 символов каждая.
Инициализация двумерного массива.
Записать данные в двумерный массив можно при его объявлении. Рассмотрим на примере с местами парковки. Допустим в паркинге 2 этажа по 4 места парковки на каждом. Объявим массив и инициализируем его:
int floorsAndParkings[2][4] = { { 1, 2, 3, 4 }, { 1, 2, 3, 4 } };
Чтобы такая инициализация выглядела более читабельно, оформим её так:
Как вы помните, согласно стандарту C++11, знак = можно упустить. Строки инициализируются по тому же принципу:
Как вывести на экран данные двумерного массива? Можно пойти длинным путём и обращаться к каждому элементу вручную:
Вывод Си-строк двумерного массива на экран немного легче, так как нам достаточно указать только имя массива и индекс строки. Далее выходной поток cout самостоятельно будет выводить все элементы символьного массива, пока не обнаружит '\0'
Хорошо! А если нам надо заполнить и показать данные массива int floorsAndParkings[20][100] или char someStr[50][256]? Эту неблагодарную работу можно в десятки раз облегчить, используя циклы. Точнее вложенные циклы.
Рассмотрим пример с паркингом. Показать пользователю схему паркинга: этажи и места для парковки. Чтобы забронировать место он должен выбрать номер этажа и номер места. После бронирования – записать значение 0 в соответствующую ячейку, что будет означать “место занято”.
Мы использовали цикл for ,в строках 15 – 24, для записи данных в массив и одновременно отображения их на экране. Если представлять этот двумерный массив как таблицу – то внешний цикл for проходит по индексам строк – от 0-й до 6-й. Вложенный цикл – по индексам столбцов (по ячейкам строк таблицы) – от 0-й до 9-й.
В строках 32 – 82 находится цикл do while. Его роль в том, чтобы снова и снова предлагать забронировать место для автомобиля, пока это необходимо пользователю. В нем находятся два вложенных цикла do while. Они реализовывают выбор этажа и места для парковки с защитой от некорректного ввода значений.
Строки 57 – 81 содержат блок if else , который, в случае корректного выбора пользователя выводит сообщение об успешном бронировании. Если же место занято (ячейка содержит значение 0) – сообщает об этом, предлагает повторить выбор этажа и места и отображает обновлённую схему паркинга, где отмечены забронированные места.
Работает это так:
продолжение…
Предлагаю решить несколько задач по теме двумерные массивы.
Рекомендую посмотреть эти видео – Двумерные массивы
Почему при проверке элементов массива мы отнимаем от floor и parkingPlace единицу?
(floorsAndParkings[floor – 1][parkingPlace – 1])
Потому что нумерация ячеек массива начинается с 0. Например: Человек вводит номер 7 — нам надо проверить ячейку 6.
Почему у меня вышла ошибка “error : name lookup of ‘f’ changed for ISO ‘for’ scoping [-fpermissive]”.
Как поменять столбцы или строки местами? Можно непосредсвенно взять столбец и поменять его место?
Код программы про места на парковке абсолютно не рабочий. При компиляции Microsoft Visual Studio 2017 выдал куеву тучу ошибок .
To Руслан: Чел, все работает. У меня та же самая Visual Studio 2017.
Интересная задача,таких больше!
уже какой раз всё что я пишу так прерывается Т Т можете подсказать почему функция отказывает?
#include
using namespace std;
void showTable(int** arr);
int main(){
const int AMOUNT_FLOOR=7;
const int AMOUNT_PARKING=10;
int **parking_and_floor[AMOUNT_FLOOR][AMOUNT_PARKING];
int exit=1;
do
{
showTable(**parking_and_floor);
int floor=0,parking=0;
for(int i=0; ;i++)
{
cout<>floor;
if(floor8)
{
cout<<"there is no "<<floor<<" floor!Please choose between 1-7: "<0||floor<8);
int sum=0;
for(int i=0;i<10;i++){
sum+=**parking_and_floor[floor][i];
};
if(sum==0){
cout<<"There is no place in this floor"<<endl;
showTable(**parking_and_floor);
}else{
break;
};
};
for(int i=0; ;i++)
{cout<>parking;
if(parking10){
cout<<"There is no parking place "<<parking<<". Please choose between 1-10: "<0||parking<11);
if(parking_and_floor[floor][parking]==0)
{
cout<<"This place is reserved, please choose another one";
showTable(**parking_and_floor);
}else
{ break;
};
};
parking_and_floor[floor][parking]=0;
cout<<"Your choice: floor "<<floor<<endl<<"place: "<<parking<<" ;"<<endl<<" was reserved succesfully!"<<endl<>exit;
}while(exit!=0);
return 0;
}
void showTable(int** arr){
cout<<"Table of parking place"<<endl;
for(int i=0;i<7;i++)
{
cout<<"floor"<<i+1;
for(int j=0;j<10;j++)
{
arr[i][j]=j+1;
cout<<arr[i][j]<<"|";
};
cout<<endl<<"~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~";
};
};
ой там смотрю куски от кода пропали
#include
using namespace std;
void showTable(int** arr);
int main(){
const int AMOUNT_FLOOR=7;
const int AMOUNT_PARKING=10;
int **parking_and_floor[AMOUNT_FLOOR][AMOUNT_PARKING];
int exit=1;
do
{
showTable(**parking_and_floor);
int floor=0,parking=0;
for(int i=0; ;i++)
{
cout<>floor;
if(floor8)
{
cout<<"there is no "<<floor<<" floor!Please choose between 1-7: "<0||floor<8);
int sum=0;
for(int i=0;i<10;i++){
sum+=**parking_and_floor[floor][i];
};
if(sum==0){
cout<<"There is no place in this floor"<<endl;
showTable(**parking_and_floor);
}else{
break;
};
};
for(int i=0; ;i++)
{cout<>parking;
if(parking10){
cout<<"There is no parking place "<<parking<<". Please choose between 1-10: "<0||parking<11);
if(parking_and_floor[floor][parking]==0)
{
cout<<"This place is reserved, please choose another one";
showTable(**parking_and_floor);
}else
{ break;
};
};
parking_and_floor[floor][parking]=0;
cout<<"Your choice: floor "<<floor<<endl<<"place: "<<parking<<" ;"<<endl<<" was reserved succesfully!"<<endl<>exit;
}while(exit!=0);
return 0;
}
void showTable(int** arr){
cout<<"Table of parking place"<<endl;
for(int i=0;i<7;i++)
{
cout<<"floor"<<i+1;
for(int j=0;j<10;j++)
{
arr[i][j]=j+1;
cout<<arr[i][j]<<"|";
};
cout<<endl<<"~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~";
};
};
(floorsAndParkings[floor – 1][parkingPlace – 1] !поясните пожалуйста, что означают единицы в квадратных скобках,что они означают