Программирование на языках высокого уровня. Язык программирования Си 

 

назад | оглавление | вперёд

 

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

12.1. Основные понятия

При определении статического массива: <тип> <имя_массива> [количество_элементов] , имя_массива становится указателем на область памяти, выделяемой для размещения элементов массива. Количество элементов должно быть константой. Таким образом, размеры памяти, выделяемой под массив, заданы в определении массива. Но иногда нужно, чтобы размеры памяти были не фиксированными, а выделялись в ходе выполнения программы при решении конкретной задачи.

Формирование массивов с переменными размерами можно организовать с помощью указателей и средств для динамического выделения памяти. Эти средства описаны в файле <alloc.h>. Функции malloc() и calloc() динамически выделяют память в соответствии со значениями их параметров и возвращают адрес начала выделенного участка памяти. Тип возвращаемого значения указателя void *. Его можно преобразовать к указателю любого типа с помощью явного приведения типа. Функция free(void *) освобождает память, выделенную с помощью malloc() или calloc().

int *p;

p=(int *)malloc(size); //Указателю на целое p присваивается адрес начала выделенной области памяти размером size байт.

p=(int *)calloc(n, size); //Указателю на целое p присваивается адрес начала выделенной области памяти размером n*size байт.

free(p); //Освобождает выделенную по адресу p память. Преобразование указателя любого типа к типу void * осуществляется автоматически, так что в качестве фактического параметра можно подставить указатель любого типа без явного приведения типов.

12.2. Одномерные динамические массивы

Пример формирования одномерного динамического массива

#include <stdio.h>

#include <conio.h>

#include <alloc.h>

main()

{float *p,d;

 int i,n;

 printf("\n input n:");

 scanf("%d",&n);

 p=(float *)malloc(n*sizeof(float));

 for (i=0;i<n;i++)

 {printf("x[%d]=",i);

   scanf("%f",&d);

   p[i]=d;

 }

 for (i=0;i<n;i++)

 {if (i%4==0) printf("\n");

    printf("\t x[%d]=%6.2f",i,p[i]);

 }

 free(p);

 getch();

}

Доступ к участкам выделенной памяти выполняется с помощью операции индексирования: p[i].


12.3. Двумерные динамические массивы

Каждый элемент массива может быть, в свою очередь, массивом. Именно так конструируются динамические многомерные массивы. Рассмотрим алгоритм создания и обработки двумерного массива.

  1. Определяем указатель на массив указателей , задающий адреса начала строк матрицы: тип **uk.
  2. Вводим размеры матрицы n,m.
  3. Создаём динамический массив указателей на указатели начала строк : uk=(тип **)malloc(n*sizeof(тип *));
  4. В цикле выделяем память под n массивов – строк по m элементов в каждом: for (i=0;i<n;i++) uk[i]=(тип *)malloc(m*sizeof(тип));
  5. Обработка массива (работа с индексированными элементами uk[i][j]).
  6. В цикле освобождаем память, занятую под n массивов – строк : for (i=0;i<n;i++) free(uk[i]);
  7. Освобождаем память, занятую под массив указателей : free(uk).

Пример обработки двумерного динамического массива

Составить программу, создающую динамическую матрицу размером n*n, заполнить матрицу случайными числами. Вычислить сумму каждой строки и поместить суммы строк в одномерный динамический массив.

 

#include <stdio.h>

#include <conio.h>

#include <stdlib.h>

#include <alloc.h>

void main()

{int n,j,i;

float ** matr; float * mass; // Объявляем matr - указатель на массив указателей //mass – указатель на одномерный массив

clrscr();

printf("Введите размер квадратной матрицы n: "); scanf("%d",&n);

mass=(float *)malloc(n*sizeof(float )); // Выделяем память под массив mass

if (mass==NULL)

{puts("не создан динамический массив!");

  return;}

matr=(float **)malloc(sizeof(float *)*n); // Выделяем память под массив указателей

if (matr==NULL)

{puts("не создан динамический массив!");

  return;}

randomize();

for (i=0;i<n;i++)

{matr[i]=(float *)malloc(sizeof(float)*n); // Выделяем память под i-ю строку

  if (matr[i]==NULL)

  {puts("не создан динамический массив!");

    return;}

  for (j=0;j<n;j++) matr[i][j]=random(100);

}

for (i=0;i<n;i++)

{mass[i]=0;

  for (j=0;j<n;j++)

    mass[i]+=matr[i][j];

}

for (i=0;i<n;i++)

{for (j=0;j<n;j++)

  printf("\t%6.2f",matr[i][j]);

  printf("\n");

}

for (i=0;i<n;i++)

  printf("\n сумма %d строки %8.2f",i,mass[i]);

for (i=0;i<n;i++)

  free(matr[i]); //Освобождаем память i – й строки

free(matr); // Освобождаем память массива указателей

free(mass); // Освобождаем память массива сумм

getch();

}

 

12.4. Контрольные вопросы

12.4.1. Отличия динамического массива от статического.

12.4.2. Как создать одномерный динамический массив?

12.4.3. Как создать динамическую матрицу?

12.4.4. Как освобождается память, занятая под динамические структуры?



назад | оглавление | вперёд