Лекция: Результат выполнения программы
Исходный массив чисел:
mas[6]={3.6 -1 4 3.4 -0.5 0 }
Отсортированный массив чисел:
mas[6]={-1 -0.5 0 3.4 3.6 4 }
!!Проанализируйте программу. Создав новый файл проекта с именем ukaz_1.ide, наберите в нем текст данной программы, откомпилируйте ее и произведите запуск программы на выполнение.
При работе с матрицами различной размерности возникает необходимость создания двумерныхдинамическихмассивов. В этом случае сначала с помощью операции new выделяется память под n указателей, где n – число строк матрицы. После этого каждому указателю присваивается с помощью new адрес выделенной области памяти с размером m, где m – число столбцов матрицы (рис. 7.3).
Рис. 7.3. Размещение динамического двумерного массива в памяти
Такой динамический массив по расположению элементов в памяти существенно отличается от статического двумерного массива, для которого память выделяется последовательно для всех строк. Для первого память выделяется последовательно только для каждой строки матрицы, а строки могут располагаться в разных местах памяти.
Пример. Формирование двумерного целочисленного массива размерностью n x m с вводом элементов матрицы с клавиатуры и последующим вычислением нормы матрицы по формуле
.
Программа для решения данной задачи приведена в листинге 7.2.
Листинг 7.2. ukaz_2.сpp
#include <iostream.h>
#include <stdlib.h> //Для функции exit
#include <iomanip.h> //Для функции setw
void main()
{
int n,m,**mas; //mas — указатель на указатель
//Ввод размерностей массива
cout<<«Введите размерность матрицы:\n»;
cout<<«число строк n=»,cin>>n;
cout<<«число столбцов m=»,cin>>m;
mas=new int*[n]; //Выделение памяти под n указателей
if(mas==NULL) //Проверка выделения памяти
{
cout<<«Свободной памяти нет»<<endl;
exit(1);
}
for(int i=0;i<n;i++)
{ mas[i]=new int[m]; //Выделение памяти для i строки
if(mas[i]==NULL) //Проверка выделения памяти
{
cout<<«Свободной памяти нет»<<endl;
exit(1);
}
}
//Ввод массива
cout<<«Введите элементы массива:\n»;
for(int i=0;i<n;i++)
for(int j=0;j<m;j++)
{
cout<<«mas[»<<i<<"]"<<"["<<j<<"]=";
cin>>mas[i][j];
}
//Вывод исходной целочисленной матрицы
cout<<"\nИсходный массив чисел:"
<<"\nmas["<<n<<"]"<<"["<<m<<"]=\n";
for(int i=0;i<n;i++)
for(int j=0;j<m;j++)
{ cout<<setw(6)<<mas[i][j];
if(j==m-1)cout<<endl;
}
cout<<endl;
//Вычисление нормы матрицы
int max=0;
for(int i=0;i<n;i++)
{ int s=0;
for(int j=0;j<m;j++)
s+=abs(mas[i][j]);
if (s>max) max=s;
}
cout<<«Норма матрицы=»<<max;
for(int i=0;i<n;i++) //Освобождение памяти, отведенную
delete mas[i]; // под матрицу
delete [] mas; //Освобождение памяти под указатели
}
Результат выполнения программы
Исходный массив чисел:
mas[3][4]=
5 8 4 2
4 9 6 4
1 5 6 8
Норма матрицы=23
!!Проанализируйте программу. Создав новый файл проекта с именем ukaz_2.ide, наберите в нем текст данной программы, откомпилируйте ее и произведите запуск программы на выполнение.
Указатели и динамическое распределение памяти – мощное средство С++. Однако возможности, которые получает программист при работе с указателями, накладывают на него большую ответственность, так как наибольшее количество ошибок вносится в программу именно при работе с указателями. К характерным ошибкам можно отнести следующие «промахи» неопытных программистов.
1. Использование неверного адреса в операции delete. В результате внутренняя структура памяти будет испорчена, что может привести к порче нужной информации.
2. Пропущено освобождение памяти, т.е. отсутствует операция delete. Такие ошибки называют «утечками памяти». В результате многократных утечек памяти ее в итоге может не хватить, и произойдет сбой программы.
3. Запись по неверному адресу. В результате, скорее всего, будут испорчены какие-либо данные, получен неверный результат, сбой программы и т.п. Ошибку определить в этом случае очень сложно, так как она обычно проявляется не сразу.