Вільні арифметичні масиви
Роботу з вільним масивом арифметичних даних і з динамічним виділенням ОП масиву розглянемо на прикладах.
У прикладі лістингу 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>