Многомерные массивы

Задания раздела 3.6
3.43. Напишите три разных версии программы для вывода элементов массива ia. Одна версия должна использовать для управления перебором серийный оператор for, а другие две - обычный цикл for, но в одном случае использовать индексирование, а в другом указатели. Во всех трех программах пишите типы явно, т.е. не используйте псевдонимы типов и спецификаторы auto или decltype для упрощения кода.
3.44. Перепишите программы из предыдущего упражнения, используя псевдоним для типа управляющих переменных цикла.
3.45. Перепишите программы снова, на сей раз используя спецификатор auto.

Многомерных массивов не существует.
Многомерный массив - просто другая запись обычного массива. При использовании многомерного массива проще обратиться к определенному диапазону значений массива, который размечен заранее на строки и столбцы.
int arr[2][3];
int (&row)[4]=arr[1];
В этом примере определяется ссылка на 4 элемента первого ряда массива arr.
Для доступа к вложенным структурам массива с помощью серийного оператора for используют ссылки. Если нужно что-то записать в массив - ссылки во всех операторах, если просто читать - во всех, кроме самого внутреннего.

3.43. Напишите три разных версии программы для вывода элементов массива ia. Одна версия должна использовать для управления перебором серийный оператор for, а другие две - обычный цикл for, но в одном случае использовать индексирование, а в другом указатели. Во всех трех программах пишите типы явно, т.е. не используйте псевдонимы типов и спецификаторы auto или decltype для упрощения кода.
Вот первый вариант с обычным циклом for.

#include <iostream>
int main()
{
constexpr int j=4;
constexpr int k=4;
int arr[j][k]={0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15};
for (int i=0; i!=j; ++i) {
for (int l=0; l!=k; ++l) {
std::cout<< arr[i][l] << " ";
}
std::cout << std::endl;
}
return(0);
}

Вот с серийным оператором for. В этой программе хорошо видно как размечется обычный массив на строки и столбцы.
#include <iostream>
int main()
{
constexpr int j=4;
constexpr int k=4;
int arr[j][k]={{0,1,2,3},{4,5,6,7},{8,9,10,11},{12,13,14,15}};
for (const int (&i)[j] : arr) {
for (const int l : i) {
std::cout<< l << " ";
}
std::cout << std::endl;
}
return(0);
}
А вот программа про указатели. Отмечу, что пока я не огородил внутренность массива фигурными скобками, явно разделив строки и столбцы, программа на указателях не заработала. Вернее заработала, но все что после первых четырех элементов отображалось нулями. А так в этой программе делаю в первом цикле указатель на первый элемент массива, состоящего из 4 элементов. Во втором цикле делаю указатель на указатель на первый элемент массива. В первом цикле указатель содержит адрес первого элемента и итерируется сразу на 4 позиции. Во втором цикле указатель итерируется внутри первого указателя. Синтаксис - не бей лежачего для новичков. Но в принципе достаточно быстро усваиваемый.
#include <iostream>
int main()
{
const int j=4;
const int k=4;
int arr[j][k]={{0,1,2,3},{4,5,6,7},{8,9,10,11},{12,13,14,15}};
for (int (*i)[k]=&arr[0];i!=arr+4;++i) {
for (int* l=*i; l!=*i+4;++l) {
std::cout<< *l << " ";
}
std::cout << std::endl;
}
return(0);
}
Эту программу на указателях можно упростить, если использовать функции begin() и end().
#include <iostream>
int main()
{
const int j=4;
const int k=4;
int arr[j][k]={{0,1,2,3},{4,5,6,7},{8,9,10,11},{12,13,14,15}};
for (int (*i)[4]=std::begin(arr);i!=std::end(arr);++i) {std::cout << (i)[j]<< " ";
for (int* l=std::begin(*i); l!=std::end(*i);++l) {
std::cout<< *l << " ";
}
std::cout << std::endl;
}
return(0);
}
через функции заработало только после жесткого указания в массиве количества элементов литералом или определив как const int переменные массива.

3.44. Перепишите программы из предыдущего упражнения, используя псевдоним для типа управляющих переменных цикла.
Я просто переписал программу как просили. Использую:
using int_array=int[4]; Вот это вот int[4] просто убивает меня. Хотелось бы никогда не использовать typedef или using. Пока что. Еще можно в программе вместо using использовать такое:
typedef int int_array[4];
и программа будет работать. По факту я понимаю что идет замена кусков объявления, но меня лично это больше сбивает с толку чем помогает.
Серийный оператор for:
#include <iostream>
typedef int int_array[4];
int main()
{
constexpr int j=4;
constexpr int k=4;
int arr[j][k]={{0,1,2,3},{4,5,6,7},{8,9,10,11},{12,13,14,15}};
for (const int_array &i : arr) {
for (const int l : i) {
std::cout<< l << " ";
}
std::cout << std::endl;
}
return(0);
}
Через указатели:
#include <iostream>
using int_array=int[4];
int main()
{
const int j=4;
const int k=4;
int arr[j][k]={{0,1,2,3},{4,5,6,7},{8,9,10,11},{12,13,14,15}};
for (int_array *i=arr;i!=arr+4;++i) {
for (int* l=*i; l!=*i+4;++l) {
std::cout<< *l << " ";
}
std::cout << std::endl;
}
return(0);
}
И еще программа:

#include <iostream>
typedef int int_array[4];
int main()
{
const int j=4;
const int k=4;
int arr[j][k]={{0,1,2,3},{4,5,6,7},{8,9,10,11},{12,13,14,15}};
for (int_array *i=std::begin(arr);i!=std::end(arr);++i) {std::cout << (i)[j]<< " ";
for (int* l=std::begin(*i); l!=std::end(*i);++l) {
std::cout<< *l << " ";
}
std::cout << std::endl;
}
return(0);
}

3.45. Перепишите программы снова, на сей раз используя спецификатор auto.
Пишу auto, компилятор трудится, я - деградирую.
С серийным оператором и auto:
#include <iostream>
int main()
{
constexpr int j=4;
constexpr int k=4;
int arr[j][k]={0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15};
for (auto &i : arr) {
for (auto l : i) {
std::cout<< l << " ";
}
std::cout << std::endl;
}
return(0);
}
Через указатели:
#include <iostream>
int main()
{
const int j=4;
const int k=4;
int arr[j][k]={{0,1,2,3},{4,5,6,7},{8,9,10,11},{12,13,14,15}};
for (auto *i=arr;i!=arr+4;++i) {
for (auto *l=*i; l!=*i+4;++l) {
std::cout<< *l << " ";
}
std::cout << std::endl;
}
return(0);
}
Еще немного auto с begin() и end().
#include <iostream>
int main()
{
const int j=4;
const int k=4;
int arr[j][k]={{0,1,2,3},{4,5,6,7},{8,9,10,11},{12,13,14,15}};
for (auto i=std::begin(arr);i!=std::end(arr);++i) {std::cout << (i)[j]<< " ";
for (auto l=std::begin(*i); l!=std::end(*i);++l) {
std::cout<< *l << " ";
}
std::cout << std::endl;
}
return(0);
}

Добавить комментарий