ВУЗ: Не указан

Категория: Не указан

Дисциплина: Не указана

Добавлен: 23.12.2021

Просмотров: 121

Скачиваний: 2

ВНИМАНИЕ! Если данный файл нарушает Ваши авторские права, то обязательно сообщите нам.

ДИНАМІЧНІ АРИФМЕТИЧНІ МАСИВИ


Динамічний масив може бути будь-якій розмірності. За допомогою покажчиків можна формувати одновимірні і багатовимірні масиви з розміром, не заданим до виконання програми, і з даними будь-якого типу. При цьому розмір масиву визначається в процесі виконання програми, наприклад шляхом введення кількості його елементів з файлу з початковими даними або з клавіатури в режимі діалогу. Використовуючи тільки покажчик, можна обробляти значення одновимірних і багатовимірних масивів. Динамічні масиви арифметичних даних розглянемо на прикладах роботи з одновимірними і двовимірними масивами. Наприклад:

int *mi; // – покажчик на дані типу int

float *mf; // – покажчик на дані типу float

char *st; // – покажчик на дані типу char

Ці покажчики можна використовувати як для роботи з скалярними значеннями відповідного типу, так і з масивами наперед не певного розміру.

Приклад програми заповнення одновимірного динамічного масиву значеннями типу int представлений в лістингу 1. У ньому k – кількість елементів масиву визначається в режимі діалогу введенням з клавіатури. Після введення значення до за допомогою функції malloc виділяється ОП для масиву з до значень типу int. Потім i-елементи масиву заповнюються значеннями: 100* i. До i-елементу масиву можна використовувати звернення у вигляді *(а + i) або а[i].

Лістинг 1. Використання покажчика для роботи з одновимірним масивом

#include <stdio.h>

#include <alloc.h>

#include <conio.h>

void main()

{ int i, k, *a; /* k – кількість елементів масиву,

а – покажчик на масив */

clrscr(); // – очистити екран

printf("Введіть кількість елементів масива:\n");

scanf (" %d", &k); // – введення значення k

а = (int *) malloc( k * sizeof(int)); // – запит ОП

// Заповнення масиву:

for ( i = 0; i < k; i++ ) { * (а + i) = 100 * i;

// або: а[i]= 100 * i;

printf( "а[%d] = %4d\n", i, а[i]); }

free (a); // – звільнення ОП

printf ("\nДля завершення програми натисніть будь-яку клавишу\n");

getch(); // – натиснути будь-яку клавішу

}

Приклад програми для роботи з динамічним масивом даних типу int приведений в лістингу 2. У програмі спочатку вводиться k – кількість елементів одновимірного масиву, а потім самі значення елементів вводяться і виводяться.

Лістинг 2. Робота з одновимірним динамічним масивом: введення даних і виведення його значень.

#include <stdio.h>

#include <alloc.h>

#include <conio.h>

void main()

{ int i, k, *a; /* kкількість елементів масиву, aпокажчик на масив */

clrscr(); // - очистити екран

printf("Введіть кількість елементів масива:\n");

scanf (" %d", &k); // - введення значення k

a=(int *) malloc(k*sizeof(int)); // - запрос ОП

// Заполнение массива:

for ( i = 0; i <k; i++ ) { * (a + i) = 100 * i;

// или: a[i] = 100 * i;

printf( "a[%d] = %4d\n", i, a[i] ); }

free (a); // - звільнення ОП

printf ("\nДля завершення програми натисніть будь-яку клавішу\n");


getch(); // - натиснути будь-яку клавішу

}

Початкові дані: 5 1 2 3 4 5

Результати виконання програми:

а[0] = 1 а[1] = 2 а[2] = 3 а[3] = 4 а[4] = 5

Аналогічно можна організувати роботу з масивами іншого типу, наприклад float, double або масиву структур.

У лістингу 3 приведений приклад програми для оголошення і роботи з одновимірним динамічним масивом даних типу int.

Лістинг 3. Робота з одновимірним динамічним масивом. Кількість і значення його елементів вводяться з клавіатури.

#include <stdio.h>

#include <conio.h>

#include <alloc.h>

void main ()

{ int i, k, *p; clrscr(); // - очистити екран

printf ("\nВведіть кількість елементів масиву : ");

scanf ( "%d", &k); // - введення k - кількості елементів масиву

printf("Кількість елементів масиву = %d\n", k);

p = (int*) malloc(k * sizeof(int)); // - запит на ОП k-елементам

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

{ printf ("Введіть %d-e значення : ", i) ;

// Введення значення чергового елементу:

scanf ( "%d",(p+i)); }

// или: (р + i), или: &p[i] }

printf ("Введеня значення: \n");

//p = p - k; // - встановлення покажчика р на початок масиву

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

printf ( "%d ", *(p+i)); // або: *(p + i), або: p[i] printf("\n");

free(p); //- звільнення ОП

printf ("\nДля завершення програми натисніть будь-яку клавішу\n");

getch(); // - натиснути будь-яку клавішу

}

/* У випадках "або" покажчик р не змінювати: тобто прибрати оператор установки його на початок масиву і не змінювати його при звільненні ОП */

Результати виконання програми:

Введіть кількість елементів масиву : 3

Кількість елементів масиву = 3

Введіть 0-е значення 1

Введіть 1-е значення 2

Введіть 2-е значення 3

Введені значення:

1 2 3

У програмі лістингу 3 використовуються змінні: i – для перебору номерів елементів масиву; k – кількість елементів масиву; р – покажчик на дані типу int. У режимі діалогу з клавіатури вводиться значення k – кількості елементів масиву. Потім виділяється ОП для до значень типу int. Потім в режимі діалогу з клавіатури вводяться значення елементів масиву. Після введення всього масиву його значення виводяться на екран.

У лістингу 4 приведений приклад програми для оголошення, введення і виведення значень елементів динамічного двовимірного масиву значень типу int. Процес роботи з масивом аналогічний викладеному для масиву в лістингу 3.

Лістинг 4. Робота з двовимірним динамічним масивом. Кількість його рядків, стовпців і значення елементів вводяться з клавіатури.

#include <stdio.h>

#include <alloc.h>

#include <conio.h>

void main()

{ int *p, i, j, ik, jk; clrscr(); // - очистити екран

printf ("\nВведіть кількість рядків матриці : ");

scanf ("%d", &ik);

printf ("Кількість рядків матриці = %d", ik);

printf("\nВведіть кількість значень в рядку : ");

scanf("%d", &jk);

printf ("Кількість значень в рядку = %d", jk);

p = (int*) malloc(( ik * jk ) * sizeof (int));

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

{ printf("\n Вводиться %d-й рядок\n", i + 1);

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

{ printf ("Введіть %d-e значення : ", j + 1);

scanf ( "%d", (p+jk*i+j) ); // або: p+i*jk+j або: &p[i*jk+j]

}

}

printf ("\nВведена матриця таких значень: \n");


// p позначає значення покажчика на 0-елемент 0-рядка матриці:

// p = p - ik * jk; // - це прибрати для "або"

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

{ for ( j = 0; j < jk; j++)

printf ( "%d ",*(p+j+i*jk)); // або: *(p+i*jk+j) або: p[i*jk+j]);

printf("\n");

}

free( p); // - звільнення ОП, починаючи з 0-елементу

// для "або": free (p);

printf("\nДля завершення програми натисніть будь-яку клавішу\n");

getch(); // - натиснути будь-яку клавішу

}

Результати виконання програми:

Введіть кількість рядків матриці : 2

Кількість рядків матриці = 2

Введіть кількість значень в рядку : 3

Кількість значень в рядку = 3

Вводиться 1-а - рядок

Введіть 1-е значення : 1

Введіть 2-е значення : 2

Введіть 3-е значення : 3

Вводиться 2-а - рядок

Введіть 1-е значення : 4

Введіть 2-е значення : 5

Введіть 3-е значення : 6

Введена матриця таких значень:

1 2 3

4 5 6

У програмі листинга 4 використовуються змінні:

- i, j для перебору номерів рядків і стовпців елементів масиву;

- ik, jk – кількість рядків і стовпців в рядку масиву;

- р – покажчик на дані типу int.

У режимі діалогу з клавіатури вводяться значення ik і jk – кількості рядків і стовпців масиву. Виділяється ОП для (ik *jk) значень типу int . Потім в режимі діалогу з клавіатури вводяться значення елементів масиву. Після введення всього масиву його значення виводяться на екран.


Вільні арифметичні масиви

Роботу з вільним масивом арифметичних даних і з динамічним виділенням ОП масиву розглянемо на прикладах.

У прикладі лістингу 5 кількість і значення елементів масиву вводяться з клавіатури в режимі діалогу. Для формування вільного масиву використовується р – статичний масив з 10 покажчиків на дані типу int. У нульовий стовпець кожного рядка вільного масиву вводиться кількість її елементів, а потім – значення елементів цього рядка.

Лістинг 5. Робота із статичним масивом покажчиків для формування вільного масиву цілих значень.

#include <stdio.h>

#include <alloc.h>

#include <conio.h>

void main()

{ int *p[10], *p1, i, j, ik, jk; clrscr(); // - очистити екран

printf ("\nВведiть кiлькiсть рядкiв матрицi;\n"

"воно повинне бути не бiльшe 10: ");

scanf ( "%d", &ik);

printf ("Кiлькiсть рядкiв матрицi = %d", ik);

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

{ printf("\nВкажiть кiлькiсть значень в %d-u рядку : ", i+1);

scanf ("%d", &jk);

printf ("Кiлькiсть значень в %d-й рядку = %d", i+1, jk);

p[i]= p1 = (int*) malloc(( jk + 1) * sizeof (int));

*p1++ = jk; // Або: *p[i] = jk; або: *(p+i) = jk;

printf("\n Вводиться %d- й рядок \n", i + 1);

for (j = 1; j <= jk; j++)

{ printf ("Введiть %d-e значення : ", j );

scanf ( "%d", p1++ ); // Або: (p[i]+j), (*(p+i)+j)

} // - кiнець циклу по 'j' }

} // - кiнець циклу по 'i'

printf ("\nВведена матриця таких значень: \n");

for ( i = 0; i < ik; i++) { p1 = p[i];

jk = *p1; // або: jk = *p[i]; або: jk = *(p+i);

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

printf ( "%d ", *p1++);

// Або: printf ( "%d ", *(p[i]+j) );

// Або: printf ( "%d ", *(*(p+i)+j) );

printf("\n"); }

// Звiльнення ОП даних:

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

free(p[i]); //- звiльнення ОП i-рядки

printf ("\nДля завершення програми натиснiть будь-яку клавiшу\n");

getch(); // - натиснути будь-яку клавішу


}

Результати виконання програми:

Введіть кількість рядків матриці;

воно повинне бути не більш 10: 2

Кількість рядків матриці = 2

Вкажіть кількість значень в 1-й рядку : 2

Кількість значень в 1-й рядку = 2

Вводиться 1-й рядок

Введіть 2-е значення : 3

Введіть 3-е значення : 4

Вкажіть кількість значень в 2-й рядку : 3

Кількість значень в 2-й рядку = 3

Вводиться 2-й рядок

Введіть 1-е значення : 5

Введіть 2-е значення : 6

Введіть 3-е значення : 7

Введена матриця таких значень:

2 3 4

3 5 6 7

У програмі лістингу 5 використовуються такі змінні:

- p – ім'я статичного масиву з 10 покажчиків на дані типу int;

- p[i] – елемент масиву р, зберігає значення покажчика на початок ОП для значень i-рядки даних;

- p1 – скалярний покажчик на дані типу int;

- i – змінна для перебору номерів рядків масиву;

- ik – кількість рядків динамічного масиву;

- j – змінна для перебору номерів стовпців масиву;

- jk – кількість елементів масиву в рядку.

Для створення вільного масиву в режимі діалогу з клавіатури вводиться значення ik – кількості рядків вільного масиву. Воно повинне бути не більш 10 – кількості елементів р масиву покажчиків. Потім воно виводиться на екран. Для формування ik рядків організовується перебір номерів рядків по i від 0 до ik -1.

Для кожного рядка:

1) вводиться значення jk – кількість значень в рядку;

2) виділяється ОП для розміщення (jk + 1) - значень в i-рядку вільного масиву:

а) одне – для значення jk і

б) jk – для розміщення значень елементів i-рядка;

в) адреса розміщення елементів i-рядка поміщається в i-елемент масиву р і в змінну p1:

p[i]=p1 = (int*) malloc(( jk + 1) * sizeof (int));

3) у нульовий стовпець i – го рядка поміщається значення jk:

*p1++ = jk;

4) перебираються значення j номерів стовпців елементів i-рядка від 1 до jk;

5) для кожного j з клавіатури вводиться чергове значення і поміщається в ОП:

scanf(“%d”, p1++);

при цьому за допомогою р1++ спочатку за адресою – значенню покажчика р1 вводиться значення чергового елементу масиву, а потім значення покажчика збільшується на 1.

Після закінчення створення вільного масиву виконується виведення його значень на екран. Для цього перебираються значення і-номерів рядків масиву від 0 до (іk-l). Формується значення покажчика на початок і-рядка (на її нульовий елемент): р1=р[i]; формується кількість елементів і-рядка: jk= *p1, потім перебираються номери стовпців і-рядка масиву по j від 1 до jk. Кожне значення виводиться на екран з допомогою: printf (“%d “, *p1++); при цьому за допомогою виразу *p1++ спочатку виводиться значення *p1, а потім значення покажчика збільшується на 1. Таким чином за допомогою змінної pl виконується перебір адрес значень елементів масиву арифметичних даних при їх створенні і виведенні.

Після закінчення роботи програми ОП, виділена за допомогою функції malloc, звільняється за допомогою функції free. Для цього перебираються номери рядків по і від 0 до ik-1, і для кожного значення i звільняється ОП для даних рядка оператором free(p[i]);.



Аналогічні результати можна одержати, якщо використовувати динамічне виділення ОП не тільки елементам вільного масиву, але і масиву покажчиків, тобто з виділенням ОП масиву покажчиків, і вільному арифметичному масиву, приведений в лістингу 6. У програмі лістингу 6 в режимі діалогу вводиться значення ik – кількість рядків вільного масиву. Потім для р– динамічного масиву покажчиків виділяється ОП для ik його елементів за допомогою функції malloc. Звернення до елементів масиву покажчиків виконується звичайним способом, у вигляді p[i]. У іншому робота програми лістингу 6 аналогічна роботі програми лістингу 5. Для звернення до елементів масиву можна використовувати покажчик р1 або елемент масиву покажчиків p[i].

Лістинг 6. Робота з динамічним масивом покажчиків для вільного масиву цілих значень

#include <conio.h>

#include <stdio.h>

#include <alloc.h>

void main()

{ int **p, // p - iм'я покажчика на динамiчний масив покажчикiв

*p1, i, j, ik, jk; clrscr(); // очистити екран

printf ("\nВвeдiть кiлькiсть рядкiв матрицi: \n");

scanf ( "%d", &ik);

printf ("Кiлькiсть рядкiв матрицi = %d", ik);

// Запит ОП динамiчному масиву покажчикiв:

p=(int**) malloc (ik * sizeof(int*));

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

{ printf("\nВкажiть кiлькiсть значень в %d рядку : ", i+1 );

scanf ("%d", &jk);

printf("Кiлькiсть значень в %d рядку = %d ", i+1, jk );

//Запит ОП i-рядку вiльного масиву:

p[i]= p1 = (int*) malloc ((jk+1) * sizeof (int));

*p1++ =jk; //или *p[i] =jk; або: *(p+i)= jk;

printf("\n Вводиться %d-й рядок \n", i+1);

for (j=1; j<=jk; j++)

{printf ("\n Введiть %d-е значення : ", j);

scanf ("%d", p1++); // Або: (p[i]+j), (*(p+i)+j)

} // - кiнець циклу по 'j'

} // - кiнець циклу по 'i'

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

{p1 = p[i]; jk = *p1;

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

printf ("%d ", *p1++);

//або printf ("%d ", *(p[i]+j) );

//або printf ("%d ", *(*(p+i)+j) );

printf ("%d ", *p1);

printf ("\n"); }

// Звiльнення ОП i-рядкa вiльного масиву:

free (p); // Звiльнення ОП покажчика для масиву покажчик?в

printf ("\nДля завершення роботи натиснiть будь-яку клавiшу\n");

getch (); // - натиснути будь-яку клавiшу

}

8