К элементам двухмерных массивов
Рассмотрим объявление и связь указателей и элементов двухмерных массивов. Двухмерный массив в языке С++ рассматривается как совокупность одномерных массивов (его строк), а строка – совокупность элементов одномерного массива.
Объявление двухмерного массива с явным указанием количества элементов массива:
<тип_элементов_массива> <имя_массива>[<кол–во_строк>][<кол–во_столбцов>];
Для обращения к элементам двухмерного массива используется два индекса (индексных выражений):
<имя_массива>[<выражение1>][<выражение2>];
Индексные выражения вычисляются слева направо, полученные значения применяется после вычисления последнего индексного выражения. Элементы массивов располагаются в ОП таким образом, что быстрее изменяются самые правые индексы, т.е. элементы одномерного массива располагаются подряд, а двухмерного – по строкам.
Пример объявления двухмерного массива значений типа:
int a[m][n];
Этот массив состоит из m одномерных массивов (строк), каждый из которых содержит n элементов (столбцов). При работе с этим двухмерным массивом можно использовать одно или два индекса (индексных выражения), например, а[i][j] содержит 2 индекса. Такая запись используется для обращения к элементу, расположенному на пересечении i-й строки и j-го столбца массива. Для получения значения этого элемента вначале вычисляются индексные выражения, затем определяется адрес элемента массива в ОП и извлекается его значение.
a[i] содержит один индекс: подобная запись определяет адрес одномерного массива, т.е адрес начала i-й строки массива.
Имя массива а не содержит индекса и определяет адрес массива, т.е. адрес его нулевого элемента.
Таким образом, обращение к двухмерным массивам с помощью имени и только одного индекса определяет указатель на начало соответствующей строки массива (адрес ее нулевого элемента). Напомним, что в одномерном массиве адрес i-го элемента массива &a[i] формируется в виде а + i*sizeof(int). Используя это, определим соотношения:
a[0] &а[0][0] a + 0*n*sizeof(int);
a[1] &а[1][0] а + 1*n*sizeof(int);
a[i] &а[i][0] а + i*n*sizeof(int);
Обращение к элементам многомерного массива более детально рассмотрим на примере двухмерного массива:
int a[3][4]; //а – указатель-константа
int *р=&а[0][0]; // р – указатель-переменная
После этого указатель р можно использовать вместо указателя а для обращения к строкам или элементам массива. В ОП элементы массива а располагаются таким образом, что быстрее всех изменяется самый правый индекс, т.е. в последовательности: a[0][0] а[0][1] а[0][2] а[0][3] а[1][0] ... а[2][0] а[2][1] а[2][2] а[2][3]
При этом для обращения к массиву а можно использовать имена:
&а а &а[0][0] *а – адрес элемента 0-й строки и 0-го столбца массива а;
*(&а[0][0]) а[0][0] – значение элемента 0-й строки 0-го столбца массива а;
a[i] (а+i) *(а+i) &a[i][0] – адрес начала i-й строки, т.е. адрес элемента i-й строки и 0-го столбца;
*a[i] *(&a[i][0]) a[i][0] – значение 0-го элемента i-й строки;
a[i][j] *(*(a+i)+j) *(a[i]+j) a[i][j] – значение элемента i-й строки j-го столбца массива а;
где (а+i) *(a+i) a[i] – адрес 0-го элемента i-й строки, т.е. &a[i][0];
(*(a+i)+j) – адрес j-го элемента i-й строки, т.е. &a[i][j];
*(*(a+i)+j) – значение j-го элемента i-й строки, т.е. a[i][j].
Значение адреса начала i-й строки (адреса 0-го элемента i-й строки) на машинном уровне формируется в виде:
a[i] а+i (a+i*n*sizeof(int))
где n — количество элементов в одной строке. Таким образом, адрес (i+1)-й строки смещен относительно i-й строки на (n*sizeof(int)) байт, т.е. на одну строку массива. Выражение a[i][j] компилятор С++ переводит в эквивалентное выражение *(*(а+i)+j).
К элементам двухмерного массива можно обратиться и с помощью скалярного указателя на массив.
Например, после объявления:
int a[m][n], *р = &а[0][0];
*(р+i*n+j) // значение j-го элемента в i-й строке;
где n – количество элементов в строке; i*n+j – смещение элемента a[i][j] относительно начала массива а.
Пример 1. Дан одномерный динамический массив. Вычислить среднее арифметическое модулей элементов массива.
Ход выполнения работы
1. Алгоритмы решения задач с использованием динамических массивов схожи с алгоритмами, использующими статические массивы.
2. Написать программу, соответствующую алгоритму:
Алгоритм | Программа |
объявление вещ: *а, sum ; цел: i, n // ввод количества элементов массива ввод n выделить динамическую память под указатель a // ввод элементов массива для i=0 до n-1 шаг 1 ввод ai все для i //сначала сумма элементов равна нулю sum=0 для i=0 до n-1 шаг 1 // в цикле изменяется номер i // элемента массива // нужный элемент добавляется к // сумме sum=sum+ai все_для i // находим среднее арифметическое sum=sum/n // печатаем полученное значение печать sum // вывод массива на экран для i=0 до n-1 шаг 1 вывод ai все_для i освободить выделенную под указатель a динамическую память | #include "stdio.h" #include "stdlib.h" int main ( ) { float *а, sum; int i, n; // ввод n printf ("n=" ); scanf ("%i", &n); a=(float*)malloc(n*sizeof(float)); //ввод одномерного динамического //массива с клавиатуры for ( i=0; i<=n-1; i++ ) { printf(“a%i=”,i); scanf(“%f”,a+i); } // сначала сумма элементов равна нулю sum=0; // вычисление суммы элементов for ( i=0; i<=n-1; i++ ) sum=sum+*(a+i); // находим среднее арифметическое sum=sum/n; // печатаем полученное значение printf("sred_arif=%f\n", sum); // вывод одномерного динамического // массива на экран for (i=0; i<=n-1; i++) printf ("%.3f ", *(а+i)); printf("\n"); free(a); return 1; } |
Примечание. Для выделения динамической памяти под массив из n элементов использовалась библиотечная функция malloc():
Для ввода элементов массива как обычно использовалась функция scanf(). Вторым аргументов этой функции является адрес переменной, которая получает вводимое значение. В данном примере это адрес i-го элемента динамического массива a+i. При вычислении суммы значение i-го элемента получали с помощью записи
Вывод элементов массива осуществляется при помощи функции printf(), где для вывода элементов применялась та же форма записи.
3. Создать проект и реализовать данную задачу в среде Visual C++ 6.0.
Пример 2. Сформировать двухмерный динамический массив по закону .
Ход выполнения работы
1. Алгоритмы решения задач с использованием динамических массивов схожи с алгоритмами, использующими статические массивы.
2. Написать программу, соответствующую алгоритму:
Алгоритм | Программа |
объявление вещ: *а ; цел: i, n // ввод количества строк массива ввод n // ввод количества столбцов массива ввод m выделить динамическую память под указатель a // формирование массива построчно для i=0 до n-1 шаг 1 для j=0 до m-1 шаг 1 aij=i+j все для j все для i // вывод массива построчно для i=0 до n-1 шаг 1 для j=0 до m-1 шаг 1 вывод aij все для j все_для i освободить выделенную под указатель a динамическую память | #include "stdio.h" #include "stdlib.h" int main ( ) { int *a; int i, j, m, n; //ввод n printf ("n=" ); scanf ("%i", &n); //ввод m printf ("m=" ); scanf ("%i", &m); //выделение динамической памяти под //целочисленный массив из n строк и //m столбцов a=(int*)malloc(n*m*sizeof(int)); //формирование динамического массива //построчно for ( i=0; i<=n-1; i++ ) for ( j=0; j<=m-1; j++ ) { *(a+i*m+j)=i+j; } //вывод динамического массива //построчно for (i=0; i<=n-1; i++) { for ( j=0; j<=m-1; j++ ) printf ("%i ", *(a+i*m+j)); printf("\n"); } //освобождение выделенной // динамической памяти free(a); return 1; } |
3. Создать проект и реализовать данную задачу в среде Visual C++ 6.0.
Пример 3. Дан двухмерный динамический массив размера . Сформировать одномерный динамический массив, каждый элемент которого – произведение нечетных элементов соответствующего столбца двухмерного массива. Указать номер столбца с наименьшим произведением элементов.
Ход выполнения работы
1. Решение этой задачи было подробно рассмотрено в разделе «Двухмерные массивы».
2. Написать программу, соответствующую алгоритму:
Алгоритм | Программа |
объявление вещ: *а,p,*b, цел: i, j, pmin, n, m // ввод количества строк массива ввод n // ввод количества столбцов массива ввод m выделить динамическую память под указатель a выделить динамическую память под указатель b // ввод массива построчно для i=0 до 6-1 шаг 1 // в цикле изменяется номер i строки // массива для j=0 до 4-1 шаг 1 // в цикле изменяется номер // столбца массива j // затем элемент вводится ввод аij все_для j все_для i // вычисление произведений для j=0 до 4-1 шаг 1 // в цикле изменяется номер j столбца // массива //находим произведение j-го столбца p=1 для i=0 до 6-1 шаг 1 // в цикле изменяется номер строки // массива i // находим нечетный элемент если остаток от дел aij на 2 =1 //изменяем произведение p=p*aij все_если все_для j b[j]=p все_для i //находим минимальный элемент //массива b p=b0 //номер минимального элемента pmin=0 для i=1 до 4-1 шаг 1 если p<bi p=bi pmin=i все_если все_для i // вывод массива a построчно для i=0 до 6-1 шаг 1 // в цикле изменяется номер i строки // массива для j=0 до 4-1 шаг 1 // в цикле изменяется номер j // столбца массива // затем этот элемент выводится на // экран вывод аij все_для j все_для i // вывод массива b для i=0 до 4-1 шаг 1 вывод bi все_для i печать pmin | #include "stdio.h" #include "stdlib.h" #include "math.h" int main() { float *a, p, *b; int i, j, pmin, n, m; //ввод n printf ("n=" ); scanf ("%i", &n); //ввод m printf ("m=" ); scanf ("%i", &m); //выделение динамической памяти под //целочисленный массив из n строк и //m столбцов a=( float *)malloc(n*m*sizeof(float)); b=( float *)malloc(m*sizeof(float)); // ввод динамического массива a // построчно for(i=0; i<=n-1; i++) { for (j=0; j<=m-1; j++) { printf ("a[%i][%i]=",i,j); scanf ("%f", a+i*m+j); } } // вычисление произведений for(j=0; j<=m-1; j++) { p=1; for (i=0; i<=n-1; i++) { if(fmod(*(a+i*m+j),2)==1) p=p*(*(a+i*m+j)); } *(b+j)=p; } //находим минимальный элемент массива //b p=*b; //нулевой элемент массива b pmin=0; for (i=0; i<=m-1; i++) { if(p>*(b+i)) { p=*(b+i); pmin=i; } } // вывод массива a построчно for (i=0; i<=n-1; i++) { for (j=0; j<=m-1; j++) printf ("%.2f ", *(a+i*m+j)); printf ("\n"); } printf ("\n"); // вывод массива b for (i=0; i<=m-1; i++) { printf ("%.2f ", *(b+i)); } printf ("\n"); printf ("№min=%i\n", pmin); free(a); free(b); return 1; } |
3. Создать проект и реализовать данную задачу в среде Visual C++ 6.0.
Дата добавления: 2015-08-08; просмотров: 766;