Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Metodichka_PZ.doc
Скачиваний:
0
Добавлен:
01.04.2025
Размер:
1.66 Mб
Скачать

Общие сведения

Все глобальные переменные и константы, объявленные в программе на языке C++, размещаются в одной непрерывной области оперативной памяти, которая называется сегментом данных [6]. Длина сегмента данных опреде­ляется архитектурой процессора 8086 и составляет 64 Кбайта, что может вы­звать определенные затруднения при обработке больших массивов данных. С другой стороны, объем памяти ПЭВМ достаточен для успешного решения задач с большой размерностью данных. Выходом из положения может служить использование так называемой динамической памяти.

Динамическая память - это оперативная память ПЭВМ, представляемая си-программе при её работе, за вычетом сегмента данных, стека, и собствен­но тела программы. Размер динамической памяти может варьировать в ши­роких пределах. Динамическая память - это фактически единственная воз­можность обработки массивов данных большой размерности. Существуют и другие задачи, которые трудно или невозможно решить без использова­ния динамической памяти. В частности, такие проблемы возникают при раз­работке систем автоматизированного проектирования: размерность матема­тических моделей может значительно отличаться в различных проектах, статическое распределение памяти в этом случае практически невозможно. Кроме того, динамическая память используется для временного запоминания данных при работе с графическими и звуковыми средствами ПЭВМ.

Д

82

инамическое размещение данных означает использование - динамиче­ской памяти непосредственно при работе программы. Статическое размеще­ние осуществляется компилятором в процессе компиляции программы. При динамическом размещении заранее не известны ни тип, ни количество размещаемых данных, к ним нельзя обращаться по именам как статическим пе­ременным.

Для управления динамической памятью в Си-программах используются уже знакомые нам указатели. Вся динамическая память рассматривается как подобная стеку структура, называемая "кучей".

Для выделения памяти под любую переменную используется операция new [3]:

указатель = new имя_инициализатор

Эта операция позволяет выделить и сделать доступным свободный уча­сток в основной памяти, размеры которого соответствуют типу данных, оп­ределяемому именем типа. B выделенный участок памяти заносится значе­ние, определяемое инициализатором, который не является обязательным элементом. В случае успешного выполнения операция new возвращает адрес начала выделенного участка, памяти. Если участок нужных размеров не мо­жет быть выделен (нет памяти), то операция new возвращает нулевое значе­ние указателя (NULL). Необязательный параметр инициализатор - это выра­жение в круглых скобках. Указатель должен ссылаться на тот же тип, что имя_типа в операции new. Например, можно написать такой фрагмент программы:

int *ptr; float *ptr1;

ptr=new int;

*ptr=10; ptr1=new float(13.15);

В первом случае операция new позволяет выделить 2 байта памяти и адрес начала выделенного участка присваивается указателю ptr. Сле­дующий оператор присваивания инициализирует этот участок памяти чис­лом 10. Во втором случае операция new позволяет выделить 4 байта-памяти, адрес начала выделенного участка присваивается указателю ptr1 и этот участок памяти инициализируется числом 13.15. В дальнейшем доступ к выделенному участку памяти осуществляется с помощью операции косвен­ной адресации (или разыменовывание). Продолжительность существования выделенного участка - от точки создания до конца программы или до явного освобождения. С помощью операции

delete указатель осуществляется явное освобождение памяти. Например:

delete ptr;

delete ptr1;

Если указатель, на который действует операция delete, не содержит ад­рес блока, зарезервированного ранее операцией new, то последствия бу­дут непредсказуемыми.

Д

83

ля выделения, динамической памяти под массив операция new используется следующим образом:

int *mas1; // Одномерный массив

mas1=new int[n];

float *mas2; // Двумерный массив

mas2=new float[n*n];

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

Рассмотрим пример выделения и освобождения памяти для массивов. Пусть дана матрица MAS2[N,N] и одномерный массив MAS1[N]. Требуется заменить элементы главной диагонали матрицы элементами одномерного массива. Матрицу формируем с помощью датчика случайных чисел, а одномерный массив введем с клавиатуры.

// Пример pr25

#include <stdio.h>

#include <stdlib.h>

#include <conio.h>

void main()

{

int n;

printf("\nВведите количество элементов в массиве");

scanf("%d",&n);

int *mas1, *ptr,i;

mas1=new int[n]; // Выделение памяти под одномерный массив

int *mas2=new int[n*n];//Выделение памяти под двумерный массив

randomize();

for(i=0; ptr=mas2; i<n*n; i++, ptr++)

*ptr=random(25); // Формирование двумерного массива

printf("\nВведите элементы одномерного массива");

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

scanf("%d", mas1[i]);

// Вывод элементов одномерного массива

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

printf("%d"\t, mas1[i]);

puts("\nВывод элементов двумерного массива");

for(i=0,ptr=mas2; i<n*n; i++,ptr++)

{ if(i%n==0) // Перевод курсора, если новая строка

printf("\n");

printf("%d\t",*ptr);

}

// Замена элементов главной диагонали матрицы элементами

// одномерного массива

84

for(i=0,ptr=mas2; i<n; i++; ptr=ptr+n+1)

*ptr=mas1[i]; puts("Обработанный массив");

for(i=0,ptr=mas2; i<n*n; i++,ptr++)

{ if(i%n==0)

printf("\n"); printf("%d\t",*ptr);

}

// Освобождение памяти

delete [ ] mas 1;

delete [ ] mas2;

getch();

}

В предыдущей программе двумерный массив в итоге был обработан как одномерный массив. Если все-таки необходимо воспользоваться индексами в двумерном массиве, то нужно вспомнить, что имя одномерного массиве яв­ляется указателем на первый элемент массиве. Таким образом, двумерный массив можно рассматривать как одномерный массив указателей. При этом усложняется выделение и освобождение динамической памяти. В следую­щей программе формируется с помощью датчика случайных чисел в дина­мической памяти двумерный массив, а из сумм элементов строк - одномер­ный массив. Главным преимуществом этой и предыдущей программы является возможность вводить с клавиатуры размеры массива.

// Пример рr26

#include<stdio.h>

#include<stdlib.h>

#include <conio.h>

void main()

{

int n,m;

printf("\nВведите количество строк и столбцов в матрице");

scanf("%d%d",&n,&m);

int *mas,j,i;

mas=new int[n]; // Выделение памятей для одномерного массива

int **mas2; // Указатель для массива указателей - матрица

mas2=new int *[n]; // Выделение памяти для массива указателей

randomize();

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

{

mas2[i]=new int[m]; // Выделение памяти под строку матрицы

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

mas2[i][j]=random(25);

}

p

85

uts("Вывод элементов двумерного массива"); for(i=0; i<n; i++)

{

printf("\n");

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

printf("%d\t",mas2[i][j]);

}

// Формирование одномерного массива

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

{

mas[i]=0;

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

mas[i]=mas[i]+mas2[i][j];

}

printf("\n");

puts("Вывод элементов одномерного массива");

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

printf("%d\t",mas[i]);

// Освобождение памяти

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

delete mas2[i];

delete [ ]mas2;

delete [ ] mas; getch();

}

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

1. Зачем нужны динамические массивы?

2. Как описываются динамические массивы?

3. Как организовать работу с указателями в двумерном массиве?

4. Как объяснить формулу pr25: ptr=ptr+n+1?

5. Составьте программу, которая, используя динамические массивы, в заданной квадратной целочисленной матрице определяет количество про­стых чисел.

Варианты заданий

Варианты заданий выбираются из заданий к лабораторной работе №5 по следующему правилу: если у вас i-й вариант, то выбираете задачу с номером 26 - i.

86

ЛАБОРАТОРНАЯ РАБОТА №7

ФУНКЦИИ

Цель работы: Написание и отладка программ с использованием, функ­ций.

Порядок выполнения работы:

В соответствии с поставленной задачей необходимо разработать графи­ческую схему алгоритма, составить программы.

К данной работе предъявляются следующие требования: левую часть уравнения нужно оформить как функцию C++, в главной функций обеспечить ввод исходных данных, реализацию метода решения уравнения и вывод результата на экран.

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]