При определении статического массива: <тип> <имя_массива> [количество_элементов] , имя_массива становится указателем на область памяти, выделяемой для размещения элементов массива. Количество элементов должно быть константой. Таким образом, размеры памяти, выделяемой под массив, заданы в определении массива. Но иногда нужно, чтобы размеры памяти были не фиксированными, а выделялись в ходе выполнения программы при решении конкретной задачи.
Формирование массивов с переменными размерами можно организовать с помощью указателей и средств для динамического выделения памяти. Эти средства описаны в файле <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 * осуществляется автоматически,
так что в качестве фактического параметра можно подставить указатель любого
типа без явного приведения типов.
Пример формирования одномерного динамического массива
#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].
Каждый элемент массива может быть, в свою очередь, массивом. Именно так конструируются динамические многомерные массивы. Рассмотрим алгоритм создания и обработки двумерного массива.
Пример обработки двумерного динамического массива
Составить программу, создающую динамическую матрицу размером 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(); }
1. Отличия динамического массива от статического.
2. Как создать одномерный динамический массив?
3. Как создать динамическую матрицу?
4. Как освобождается память, занятая под динамические
структуры?