Главная | Обратная связь | Поможем написать вашу работу!
МегаЛекции

Лекция 13. Динамические массивы. 1. Способы объявления и обращения к элементам массивов. ü освоить методику написания алгоритмов с использованием динамических массивов, перевода таких алгоритмов на язык программирования С++ и разработки соответствующ




Лекция 13

Динамические массивы

Цели:

ü получить представление о способах объявления и обращения к элементам массивов;

ü освоить методику написания алгоритмов с использованием динамических массивов, перевода таких алгоритмов на язык программирования С++ и разработки соответствующего проекта в среде Visual C++ 6. 0.

 

1. Способы объявления и обращения к элементам массивов

1. 1. Способы объявления и обращения

к элементам одномерных массивов

 

Объявление одномерного массива с явным указанием количества элементов массива:

< тип_элементов_массива> < имя_массива> [< количество_элементов> ];

Обращение к элементам одномерного массива в общем случае можно представить индексированием:

< имя_массива> [< выражение> ];

где < имя_массива> – указатель–константа, адрес нулевого элемента массива; < выражение>  определяет индекс элемента массива.

Элементы одномерного массива располагаются в ОП последовательно друг за другом: нулевой, первый и т. д. При объявления массива 

int а[10];

компилятор выделяет массиву ОП для размещения его элементов в размере sizeof(< тип_элементов_массива> )*< размер_массива> байт, т. е. 4 ∙ 10 = 40 байт. Запись & a[i] равносильна записи (а + i). В программе & a[i] или (а + i) определяет  адрес i-го элемента массива. На машинном уровне (в соответствии с определением операций над указателями) адрес i-го элемента массива & a[i] формируется в виде  а + i*sizeof(int).

В связи с вышеизложенным, будут справедливы соотношения:

& а  а + 0  & а[0] – адрес нулевого элемента массива а;

а + 2  & а[2] – адрес второго элемента массива а;

а + i  & a[i] – адрес i-го элемента массива а;

 

 *(а + 0)  *(& а[0])  а[0] – значение нулевого

элемента массива а;

*(а+2)  а[2] – значение второго элемента массива;

*(а + i)  a[i] – значение i-го элемента массива;

 

*а + 2  а[0] + 2 – сумма значений а[0] и 2.

Если р – указатель на тип данных, совпадающий с типом элементов массива а и адрес, который содержит указатель р, совпадает с адресом массива а, то а и р взаимозаменяемы. При этом

р  & а[0]  а + 0;

р + 2  & а[2]  а + 2;

*(р + 2)  *(& а[2])  а[2];

*(p + i)  *(& a[i])  a[i].

1. 2. Способы объявления и обращения

к элементам двухмерных массивов

 

Рассмотрим объявление и связь указателей и элементов двухмерных массивов. Двухмерный массив в языке С++ рассматривается как совокупность одномерных масси­вов (его строк), а строка – совокупность элементов одно­мерного массива.

Объявление двухмерного массива с явным указанием количества элементов массива:

< тип_элементов_массива> < имя_массива> [< кол–во_строк> ][< кол–во_столбцов> ];

Для обращения к элементам двухмерного массива используется два индекса (индексных выражений):

< имя_массива> [< выражение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 - 2024 megalektsii.ru Все авторские права принадлежат авторам лекционных материалов. Обратная связь с нами...