Практическая часть
Пример 1. Создать одномерный динамический массив из n элементов и удалить из него те элементы, значения которых совпадут с первым элементом массива. Первый элемент массива оставить без изменения.
Программный код решения примера:
#include <stdio.h>
#include <conio.h>
#include <stdlib.h>
int main(void)
{
float *p, *p1=NULL, d;
int i, n, j, col=0;
printf("\n input n:");// запрашиваем количество элементов в массиве
scanf("%d",&n);
p=(float *)malloc(n*sizeof(float));// выделяем память по массив
//проверяем была ли выделена область памяти нужного размера
if (!p)
{
printf("Out of memory. Press any key: ");
_getch();
return 1;
}
// заполняем элементы массива
for (i=0;i<n;i++)
{printf("x[%d]=",i);
scanf("%f",p+i);
}
// выводим на экран исходный массив
for (i=0; i<n; i++)
printf("p[%d]=%6.2f ",i+1,*(p+i));
// удаляем те элементы массива, значения которых совпали с первым
for (i=n-1;i>=0;i--)
if (*p!=*(p+i)||i=0)
{
col++;
p1=(float*) realloc (p1, col * sizeof(float));
for(j=col-1;j>0;j--)
*(p1+j)=*(p1+j-1);
*p1=*(p+i);
if (i) p=(float*) realloc (p, (n-col) * sizeof(float));
else free(p);
}
// выводим на экран массив после удаления элементов
p=p1;
for (i=0; i<col; i++)
printf("p[%d]=%6.2f",i+1,*(p+i));
// освобождаем память
free(p);
getch();
return 0;
}
Пример 2.Составить программу, создающую динамическую матрицу размером n*n, заполнить матрицу случайными числами. Вычислить сумму каждой строки и поместить суммы строк в одномерный динамический массив.
#include <stdio.h>
#include <conio.h>
#include <stdlib.h>
#include <alloc.h>
int main(void)
{
int n,j,i;
float ** matr; float * mass; /*Объявляем matr - указатель на массив
указателей и mass – указатель на одномерный массив*/
clrscr();// очищаем экран
printf("Введите размер квадратной матрицы n: ");
scanf("%d",&n);
// Выделяем память под одномерный массив
mass=(float *)malloc(n*sizeof(float ));
if (mass==NULL)
{
puts("не создан динамический массив!");
return 1;
}
matr=(float **)malloc(sizeof(float *)*n); //Выделяем память под массив указателей
if (matr==NULL)
{
puts("не создан динамический массив!");
return 1;
}
randomize();
for (i=0;i<n;i++)
{
// Выделяем память под i-ю строку двумерного массива.
matr[i]=(float *)malloc(sizeof(float)*n);
if (matr[i]==NULL)
{
puts("не создан динамический массив!");
return 1;
}
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();
return 0;
}
Доступ к i-му элементу одномерного массива arr осуществляется с указанием одного индексного выражения в форме arr[i] или *(arr+i).
Для доступа к элементу двумерного массива mas, находящемся в i-ой строке и в j-м столбце, могут быть использованы следующие выражения:
- mas[i][j]:
- *(*(arr+i)+j)
- (*(arr+i))[j]
Используя замечания по поводу доступа к элементам массивов, перепишем программу для примера 2, через указатели:
#include <stdio.h>
#include <conio.h>
#include <stdlib.h>
#include <alloc.h>
int main(void)
{
int n,j,i;
float ** matr; float * mass; /*Объявляем matr - указатель на массив
указателей и mass – указатель на одномерный массив*/
clrscr();// очищаем экран
printf("Введите размер квадратной матрицы n: ");
scanf("%d",&n);
// Выделяем память под одномерный массив
mass=(float *)malloc(n*sizeof(float ));
if (mass==NULL)
{
puts("не создан динамический массив!");
return 1;
}
matr=(float **)malloc(sizeof(float *)*n); //Выделяем память под массив указателей
if (matr==NULL)
{
puts("не создан динамический массив!");
return 1;
}
randomize();
for (i=0;i<n;i++)
{
// Выделяем память под i-ю строку двумерного массива.
*(matr+i)=(float *)malloc(sizeof(float)*n);
if (*(matr+i)==NULL)
{
puts("не создан динамический массив!");
return 1;
}
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();
return 0;
}
Пример 3.Вводится последовательность целых чисел заканчивающаяся 0. Вывести ее на экран.
#include <stdio.h>
#include <stdlib>
int main(void)
{
int input;
int counter = 0; // счетчик введенных чисел
int * values = NULL; // переменная для создания динамического массива
int * many_numbers;
do {
printf("Введите целое значение (0 - выход): ");
scanf("%d",&input);
counter++;
// при добавлении нового числа, увеличиваем массив на 1
many_numbers = (int*) realloc (values, counter * sizeof(int));
if (many_numbers != NULL)
{
values = many_numbers;
// добавить к массиву только что введённое число
values[counter - 1] = input;
}
else
{
free (values); // удалить массив
printf("Ошибка перевыделения памяти!";)
return 1; // завершить работу программы
}
} while (input != 0); // пока не введён 0
printf("Введенные числа: ");
for (int ix = 0; ix < counter; ix++) std::cout << values[ix] << " ";
free (values); // удалить массив
return 0;
}
Пример 4.Написать фрагмент программы, удаляющий в матрице, рассмотренной в примере 2 третью строку (считаем, что n>2), выводит новую матрицу на экран, а затем освобождает память от данных .
// удаляем третью строку
for (i=2;i<n-1;i++)
matr[i]=matr[i+1];
free(matr[n-1]);
matr=(float**) realloc(matr, sizeof(float *)*(n-1));
// выводим матрицу на экран
for (i=0;i<n-1;i++)
{
for (j=0;j<n;j++)
printf("\t%6.2f",matr[i][j]);
printf("\n");
}
for (i=0;i<n-1;i++)
free(matr[i]); //Освобождаем память i – й строки
free(matr); // Освобождаем память массива указателей
Контрольные вопросы
- Что такое динамическая память?
- Какие средства языка С используются для хранения данных с динамическим выделением памяти компьютера?
- Какие основные библиотечные функции языка С используются для динамического распределения памяти?
- Какое различие в действии функций malloc() и calloc()?
- Как осуществляется перераспределение динамической памяти?
- Для каких типов данных возможно динамическое распределение памяти?