русс | укр

Мови програмуванняВідео уроки php mysqlПаскальСіАсемблерJavaMatlabPhpHtmlJavaScriptCSSC#DelphiТурбо Пролог

Компьютерные сетиСистемное программное обеспечениеИнформационные технологииПрограммирование


Linux Unix Алгоритмічні мови Архітектура мікроконтролерів Введення в розробку розподілених інформаційних систем Дискретна математика Інформаційне обслуговування користувачів Інформація та моделювання в управлінні виробництвом Комп'ютерна графіка Лекції


Багатовимірні масиви


Дата додавання: 2014-11-28; переглядів: 767.


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

Уявіть собі задачу по перетворенню дати з дня місяця в день року і навпаки. Наприклад, 1-го березня — це 60-ий день звичайного року і 61-ий день високосного. Давайте визначимо дві функції для здійснення перетворення: day_of_year перекладає місяць і день у день року, іmonth_day, яка переводить день року в місяць і день. Так як остання функція обчислює два значення, аргументи місяця і дня будуть покажчиками:

month_day(1988, 60, &m, &d)

присвоїть m значення 2, а d значення 29 (29-го лютого).

Обидві ці функції потребують тієї самої інформації — таблиці з кількістю днів у кожному місяці («рівно 30 днів у вересні ...»). Так як кількість днів відрізняється в високосному і невисокожному році, буде легше розділити їх на два ряди у двохвимірному масиві, після чого звертати увагу на лютий під час обчислень. Масив і функції для здійснення перетворень слідують:

static char daytab[2][13] = {

{0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31},

{0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}

};

 

/* day_of_year: отримати день року маючи місяць і день */

int day_of_year(int year, int month, int day)

{

int i, leap;

leap = year%4 == 0 && year%100 != 0 || year%400 == 0;

for (i = 1; i < month; i++)

day += daytab[leap][i];

return day;

}

 

/* month_day: отримати місяць і день з дня року */

void month_day(int year, int yearday, int *pmonth,

int *pday)

 

{

int i, leap;

 

leap = year%4 == 0 && year%100 != 0 || year%400 == 0;

for (i = 1; yearday > daytab[leap][i]; i++)

yearday -= daytab[leap][i];

*pmonth = i;

*pday = yearday;

}

Якщо пригадуєте, арифметичним значенням логічного виразу, як у випадку leap (англ. високосний), може бути або нуль (хибно), або один (істина), тож це значення можна також використати як індекс масиву daytab.

Масив daytab повинен бути зовнішнім для обох, day_of_year і month_day, щоб обидва могли користуватись ним. Ми оголосили масив як char для ілюстрації того як використовуватиchar для збереження малих незнакових цілих.

daytab — це перший двовимірний масив з яким ми досі стикалися. У C, двовимірний масив, це насправді одновимірний, кожен елемент якого також являється масивом. Тому індекси записуються як

daytab[i][j] /* [рядок][стовпчик] */

замість

daytab[i,j] /* НЕПРАВИЛЬНО */

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

Такий масив ініціалізується за допомогою, включеного у фігурні дужки, списку ініціалізаторів; кожний рядок двовимірного масиву ініціалізується відповідним другорядним списком. Ми почали масив daytab зі стовпчика, який містить 0, тож цифри місяців можна відраховувати природнішим 1 до 12, замість 0 до 11. Оскільки неможливо використати пропуск у цій ситуації, це зрозуміліше ніж пізніша зміна індексів.

При передачі двовимірного масиву як аргумент функції, оголошення параметра функції повинно включати кількість стовпчиків; кількість рядків не є важливим так як те, що передається, як ми це раніше засвоїли, це покажчик на масив рядків, кожен з яких містить масив з 13-ти елементів типу int. У цьому конкретному випадку, це покажчик на об'єкти, що являють собою масиви з 13-и int. Таким чином, якщо масив daytab передати функції f, оголошенням f буде:

f(int daytab[2][13]) { ... }

Також це могло би бути

f(int daytab[][13]) { ... }

так як кількість рядків не є важливою, або це могло б також бути

f(int (*daytab)[13]) { ... }

що вказує на те, що параметр — це покажчик на масив з 13-и цілих. Дужки потрібні, оскільки квадратні дужки [] мають більший пріоритет за *. Без дужок оголошення

int *daytab[13]

буде масивом з 13 покажчиків на цілі int. Як узагальнення, тільки перший вимір (індекс) масиву є вільним, решту потрібно вказувати. Розділ 5.12 включає подальше обговорення складних оголошень.

Вправа 5-8. Перевірки на помилки в day_of_year і month_day бракує. Виправіть цей недолік.


<== попередня лекція | наступна лекція ==>
Масив покажчиків; покажчики на покажчики | Ініціалізація масиву покажчиків


Онлайн система числення Калькулятор онлайн звичайний Науковий калькулятор онлайн