Язык программирования Си (Ритчи, Керниган) - страница 90

должен иметь тот же тип, что и v - тогда можно будет осуществлять пересылки между temp и элементами v.

Упражнение 5.7. Напишите новую версию readlines, которая запоминала бы строки в массиве, определенном в main, а не запрашивала память посредством программы alloc. Насколько быстрее эта программа?

5.7 Многомерные массивы

В Си имеется возможность задавать прямоугольные многомерные массивы, правда, на практике по сравнению с массивами указателей они используются значительно реже. В этом параграфе мы продемонстрируем некоторые их свойства.

Рассмотрим задачу перевода даты "день-месяц" в "день года" и обратно. Например, 1 марта - это 60-й день невисокосного или 61-й день високосного года. Определим две функции для этих преобразований: функция day_of_year будет преобразовывать месяц и день в день года, a month_day - день года в месяц и день. Поскольку последняя функция вычисляет два значения, аргументы месяц и день будут указателями. Так вызов

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

присваивает переменной m значение 2, а d - 29 (29 февраля).

Нашим функциям нужна одна и та же информация, а именно таблица, содержащая числа дней каждого месяца. Так как для високосного и невисокосного годов эти таблицы будут различаться, проще иметь две отдельные строки в двумерном массиве, чем во время вычислений отслеживать особый случай с февралем. Массив и функции, выполняющие преобразования, имеют следующий вид:

>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 для малых целых без знака.