книги / Язык Си
..pdf10.6.2. Операторы new, delete
Операторы new, delete введены в языке Си++. Они более удобны для работы с динамической памятью.
Создание нового объекта с помощью оператора new имеет вид
тип *имя = new тип;
float *а = new float;
Создание одномерного массива с помощью оператора new имеет вид
тип *имя = new тип [размер];
int п = 5;
float *arrayl = new float [n] ;
Пример создания двумерного массива 5><3 с помощью опера тора new имеет вид
int i,n = 5;
float **array2;
array2 = new float * [n] ;
for(i=0;i<n;i++)
array2[i]= new float [3] ;
Созданный в памяти объект хранится, пока не будет уничто жен операцией delete или пока не завершится выполнение про граммы.
Удаление динамически выделенной памяти происходит в ОБРАТНОМ порядке, т.е. если объект был создан первым, то его надо удалять последним. Таким образом, все выделенные выше объекты удаляем в обратном порядке:
for(i=0;i<n;i++) delete[] array2[i] ;
delete[] array2;
delete[] arrayl;
delete a;
Пример. Динамическое выделение памяти под трехмерный массив.
#include<stdio.h>
#include<conio.h>
#include<stdlib.h>
#include<time.h> main()
{int ***a;
int i,j,k; int nl,n2,n3;
//пределы генерации случайных чисел int min=0 f max=l00;
puts("Введите nl, n2,n3 :"); scant("%d%d%d",&nl,&n2,&n3);
//выделение памяти под координату х а = new int **[nl];
//выделение памяти под координату у for(i=0;i<nl;i++)
a[i] = new int *[n2];
//выделение памяти под координату z for(i=0;i<nl;i++)
for(j=0;j<n2;j++)
a [i][j] = new int [n3];
//заполнение массива случайными значениями srand(time(NULL));
for(i=0;i<nl;i++) for(j=0;j<n2;j++)
for(k=0;k<n3;k++)
a[i][j][k] = min + rand()%(max-min+1);
//вывод массива на консоль for(i=0;i<nl;i++) {printf("\ni=%d\n",i);
for(j=0;j<n2;j++)
{for(k=0;k<n3;k++)
printf("%4d",a[i] [j] [k]);
printf("\nM);
}
}
//очистка памяти по координате z for(i=0;i<nl;i++) for(j=0;j<n2;j++)
delete []a [i] [j];
//очистка памяти по координате у for(i=0;i<nl;i++)
delete []a[i];
//очистка памяти по координате х delete []а;
getch(); return 0;
}
Задача 1. Написать функцию для определения минимального и максимального элементов одномерного динамического массива.
Поскольку результатом работы функции должны быть два значения (min, max), оператор return здесь не может быть приме нен (им можно вернуть только одно значение). В подобных случа ях искомые параметры передают в функцию по ссылке, чтобы при выходе из функции не потерять их измененные значения. Также необходимо передавать в функцию динамический массив *а и число элементов в нем п.
#include<conio.h>
#include<stdio.h>
#include<stdlib.h>
//функция поиска минимального и максимального //элементов
void my_f(int *а,int n,int &min,int &max) {int i;
//определяем минимальный элемент в массиве min=a[0];
for(i=l;i<n;i++)
if(a[i]<min)
min=a[i];
//определяем максимальный элемент в массиве шах=а[0];
for(i=l;i<n;i++) if (a [i]>max) шах=а[i];
main()
{int *a, min, max; int i,n;
puts("Введите число элементов"); scanf("%d",&n);
//выделяем динамическую память
a = (int*)malloc(sizeof(int)*n) ;
//заполняем одномерный массив значениями for(i=0;i<n;i++)
{printf("a[%d]=",i);
scanf("%dM,&a[i]);
}
my_f (a, n,min,max) ; //вызываем функцию
//печатаем результат
printf ("min=%d\nmax=%d",min,max) ;
free(а); //освобождаем динамическую память getch();
return 0;
}
Задача 2. Написать функцию, формирующую из средних арифметических значений положительных элементов каждого столбца матрицы одномерный массив.
Для этого в функцию будем передавать сам двумерный мас сив я, число строк п и число столбцов т этого массива, а также одномерный массив Ъ, который будет заполнен необходимыми значениями внутри функции. Помним, что при выходе из функции измененные в массиве значения остаются измененными.
#include<conio.h>
#include<stdio.h>
#include<stdlib.h>
void my_f(int **a,int n,int m,float *b) {int i,j,к;
float s;
for(j=0;j<m;j++)
{//вычисляем сумму положительных //элементов столбца j
s=0;
к=0;
for(i=0;i<n;i++) if(a[i] [j]>0)
{s+=a[i][j]; //накапливаем сумму
//положительных элементов k++; //подсчитываем число
//положительных элементов
}
//вычисляем среднее значение if(k==0)
b [j ]=0; else
b [j]=s/k;
}
}
main()
{int **a,i,j,n,m; float *b;
int min=-10,max=10;
puts("Введите число строк"); scanf("%d",&n);
puts("Введите число столбцов"); scanf("%d",&m);
//выделяем динамическую память под массивы а = (int**)malloc(n*sizeof(int)); for(i=0;i<n;i++)
a[i] = (int*)malloc(m*sizeof(int));
//заполнение массива случайными значениями
sгand(time(NULL));
for(i=0;i<n;i++)
for(j=0;j<m;j++)
a [i][j] = min + rand ()% (max-min+1);
//вывод двумерного массива на консоль for(i=0;i<n;i++)
{for(j=0;j<m;j++)
printf("%3d",a[i][j]); printf ("\n,f);
}
my_f (a,n,m, b) ; //вызываем функцию
//печатаем массив из средних значений
printf(и\пи);
for(j=0;j<m;j++)
printf("%10.3f",b[j]);
//освобождаем динамическую память free(b);
for(i=0;i<n;i++)
free(a[i]);
free(a);
getch(); return 0;
}
Обратите внимание, что динамическая память удаляется в по рядке, обратном выделению: сначала удаляем массив 6, потом массив а.
1.Написать программу, вычисляющую пять определенных интегралов методом парабол (см. лекцию 9, задачу 3). В решении использовать указатель на функции. Интегралы придумать самому.
2.Написать программу для формирования целочисленной квадратной матрицы размерностью п вида
1 |
1 |
1 |
1 |
1 |
1 |
0 |
1 |
1 |
1 |
1 |
0 |
0 |
0 |
1 |
1 |
0 |
0 |
0 |
1 |
1 |
1 |
1 |
0 |
1 |
1 |
1 |
1 |
1 |
1 |
Матрица А создается динамически. Число п вводится с консоли.
3. Написать функцию, которая в квадратной динамическо матрице размерностью п определяет наибольший элемент среди элементов диагоналей, параллельных побочной диагонали.
ЛЕКЦИЯ 11. СТРУКТУРЫ, ОБЪЕДИНЕНИЯ, БИТОВЫЕ ПОЛЯ
Из базовых типов можно формировать производные тапш: указатели, массивы, функции, а также еще пять типов данных:
-структуры (structure);
-объединения (union);
-поля битов (bitfields);
-перечислимый тип (enumeration);
-с помощью оператора typedef создать новое имя (псевдо ним) для уже существующего типа.
11.1. Структуры
Структура объединяет несколько переменных базовых ти пов. Переменные, которые объединены структурой, называются элементами или полями структуры. Структура определяется с помощью служебного слова struct. Форма определения структур ного типа имеет вид
struct имя структурного типа { определения элементов
};
Объявление структуры является оператором, и поэтому в конце объявления должна стоять точка с запятой:
struct student
{char паше[20]; //ФИО студента
int kurs; |
//курс |
char group[5]; //название группы
};
Теперь объявлен новый тип student, но пока переменные дан ного типа не созданы. Переменные структурного типа объявляют ся следующим образом:
struct |
тип имя переменной; |
I/в Си |
тип |
имя переменной; |
//вСи++ |
Для созданного типа student объявим две переменные
struct |
student studl,stud2; |
//Си |
student |
studl,stud2; |
//Си++ |
В дальнейших примерах будем использовать более короткую форму объявления структурных переменных, характерную для Си++.
При объявлении структурных переменных studl и studl типа student компилятор автоматически выделит под них место в памя ти компьютера. Под каждую из переменных структурного типа выделяется память, равная сумме размеров полей структуры, плюс участок, используемый для выравнивания памяти (обычно кратен 4 или 8).
Пример. Сколько памяти выделится под структурную пере менную:
#include<conio.h> |
|
|
|
#include<stdio.h> |
|
|
|
struct |
student |
//20 |
байт |
{char |
name[20]; |
||
int kurs; |
//4 |
байта |
|
char |
group[5]; |
//5 |
байт |
};
int main() {student studl; int s_all,s;
//размер памяти, выделяемой под поля структуры
s = |
sizeof(studl.name); |
s+= |
sizeof(studl.kurs); |
s+= |
sizeof(studl.group); |