Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Informatika_metoda_1k1s_правка 20130917.doc
Скачиваний:
1
Добавлен:
01.05.2025
Размер:
684 Кб
Скачать
☆

Теоретичні відомості

Масив – один з най­більш простих і відомих структур даних. Під масивом в мові Сі розу­міють набір даних одного і того ж типу, зібраних під одним ім'ям. Кожний елемент масиву визначається ім'ям масиву і порядковим номе­ром елемента, який називається індексом. Індекс в мові Сі завжди ціле число.

Частіше за все використовуються одновимірні масиви:

тип <ім'я масиву> [розмір] ;

Розмір масиву в мові Сі може задаватися константою або констан­тним виразом. Не можна задати масив змінного розміру. Для цього існує окремий механізм, званий динамічним виділенням пам'яті.

У мові Сі індекс завжди починається з нуля. Коли ми говоримо про перший елемент масиву, то маємо на увазі елемент з індексом 0. Якщо ми оголосили масив

int a[100] ;

це означає, що масив містить 100 елементів від а[0] до а[99]. Для одновимірного масиву легко підрахувати, скільки байт в пам'яті бу­де займати цей масив:

кільк. байтів = <розмір базового типу> * <кільк. елементів>.

У мові Сі під масив завжди виділяється безперервне місце в опе­ративній пам'яті.

У мові Сі не перевіряється вихід індексу за межі масиву. Якщо масив а[100] описаний як цілочисельний масив, що має 100 елемен­тів, а ви в програмі вкажете а[200], то повідомлення про помилку не буде видане, а як значення елемента а[200] буде видано деяке число, що займає відповідні 2 байти. Можна визначити масив будь-якого визначеного раніше типу, наприклад:

unsigned arr[40], long double al[1000], char ch[80].

Перед тим як використати масив, необхідно присвоїти значення його елементам. У Сі масиви не ініціалізуються і не обнулюються автоматично. Елементам масиву можна задати початкові значення трьома способами: ініціалізацією, присвоєнням або введенням. При описі масиву може бути виконана ініціалізація елементів масиву.

Є два методи ініціалізації:

  1. ініціалізація за замовчуванням. Якщо не проводиться ініціалізація елементів масиву, то всі елементи статичних та зовнішніх масивів ініціалізуються компілятором нулями, а елементи автоматичних і регістрових масивів визначені на неочищену пам’ять;

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

Існують дві форми явної ініціалізації:

  1. явне зазначення числа елементів масиву та список початкових значень, можливо, з меншим числом елементів.

<тип даних> <ім’я масиву> [розмірність N]...[розмірність 1] = {<список значень>};

Наприклад, ініціалізація зовнішнього масиву з 10 елементів:

int array [10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};

Якщо оголошений масив b з 10 елементів int b [10] = {1, 2, 3, 4}, то перші чотири елементи масиву ініціалізувати числами 1, 2, 3 і 4. Значення інших шести елементів або дорівнює 0, якщо масив зовнішній чи статистичний, або не визначено, якщо масив автоматичний чи регістровий. При використанні автоматичних масивів програміст повинен присвоїти нульове початкове значення принаймні першому елементові для того, щоб автоматично були обнулені елементи, що залишилися.

Завдання в списку початкових значень більшого числа значень, ніж є елементів у масиві, є синтаксичною помилкою;

2) без явного зазначення елементів масиву, тільки зі списком початкових значень. Компілятор визначає число елементів масиву за списком ініціалізації.

<тип даних> <ім’я масиву> [ ][розмірність N–1]...[розмірність 1] = {<список значень >};

Наприклад, int array [ ] = {1, 2, 3, 4};

У результаті створюється масив з чотирьох елементів, і ці елементи отримують початкові значення зі списку ініціалізації.

Масиву символів можна задавати початкові значення, використовуючи рядкову константу. Наприклад, оголошення

char c[ ] = {"ABCD"};

присвоює елементам масиву с початкові значення як окремі символи рядка “ABCD”. Розмір масиву с визначається на основі довжини рядка плюс нульовий символ закінчення рядка, таким чином масив містить п’ять елементів. Символьний масив можна задати окремими символьними константами. Попереднє оголошення еквівалентне наступному:

char c [ ] = {'A', 'B', 'C', 'D', '\0'};

Використовуючи операцію присвоєння, можна в програмі присвоїти значення кожному елементу масиву або, використовуючи оператор циклу і функції введення, можна вводити значення елементів з клавіатури. Ці способи ініціалізації масиву будуть показані нижче.

Доступ до елементів масиву може виконуватися за допомогою операції індексації або за допомогою механізму вказівників. При використанні операції індексації для посилання на необхідний елемент вказується його номер у масиві, вміщений у [ ].

У мові Сі дозволяється лише поелементне звертання до масиву, при якому поточне значення може бути задане константою, змінною чи виразом. Наприклад,

int a[9]; a[0] = 0; a[1] = 0; a[2] = 0; a[3] = 0; a[4] = 0; a[5] = 0; a[6] = 0; a[7] = 0; a[8] = 0;

У даному прикладі обнуляються елементи масиву a.

Інший спосіб доступу до елементів масиву — використання механізму вказівників. Ім’я масиву, що використовується без наступних [ ], являє собою адресу початку масиву. Оскільки ім’я масиву — це вказівник-константа на перший байт першого елемента масиву, то, використовуючи операцію отримання значення за адресою (*), можна виконати доступ до будь-якого елемента масиву. Тобто будуть еквівалентними запис до посилання на i-й елемент масиву array array[i] і *(array+i).

Нехай є опис масиву int a[5], який містить 5 елементів: a[0], a[1], a[2], a[3], a[4]. Адреса і-го елемента масиву дорівнює сумі адреси початкового елемента масиву і зсування цього елемента на і одиниць від початку масиву. Якщо pa — це вказівник на ціле int *pa; , то після виконання оператора pa = &a[0]; pa містить адресу елемента a[0]. Вираз pa+1 вказує на наступний елемент, pa+i вказує на i-й елемент масиву, тобто є адресою a[i], тоді *(pa+i) є вмістом i-го елемента. Оскільки ім’я масиву ототожнюється з адресою його першого елемента, то оператор pa = &a[0]; еквівалентний оператору pa = a; , тому будуть еквівалентними запис до посилання на i-й елемент масиву a[i] і *(а+i). Будь-який масив і індексний вираз можна представити за допомогою вказівника. В той же час між ім’ям масиву й відповідним вказівником є істотна відмінність. Треба пам’ятати, що вказівник — це змінна, а ім’я масиву — константа. Тому pa = a; і pa++; допустимі операції. Оператори вигляду а = pa; а++; використати не можна, оскільки значення константи постійне і не може бути змінене.

Якщо до вказівника додається ціле, компілятор автоматично масштабує ціле, множачи його на число байтів, відповідне типу, зазначеному в оголошенні вказівника. Розміщення масиву а в пам’я­ті подано на рис. 5.1, якщо він розташовується з адреси 1000.

1000

1002

1004

1006

1008

*ра

*(pa+1)

*(pa+2)

*(pa+3)

*(pa+4)

a[0]

a[1]

a[2]

a[3]

a[4]

*а

*(а+1)

*(а+2)

*(а+3)

*(а+4)

Рисунок 5.1. Розміщення масиву в пам’яті

Тоді вираз ра + 3 або а + 3 дає значення адреси 1000 + 3*si­zeof(int) = 1000 + 3*2 = 1006. Взявши значення за цією адресою, можна набути значення четвертого елемента масиву, тобто *(ра+3) або *(а+3). Обидва способи еквівалентні.

Приклад

Як приклад виконання операцій над масивами розробимо алгоритм для підрахунку кількості ненульових значень масиву А[10]. Блок-схема такої програми буде мати наступний вигляд:

Ні

Код програми:

#include <stdio.h>

int main()

{

int N = 10;

int p = 0;

int A[N] = {5, -3, 0, 3, 9, -2, 0, 2, 1, 4};

for (int i = 0; i < N; i++)

if (A[i] == 0) p++;

printf("%d", p);

return 0;

}

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]