Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

книги / Язык Си

..pdf
Скачиваний:
6
Добавлен:
20.11.2023
Размер:
7.64 Mб
Скачать

10.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);