5 WSKAŹNIKI I TABLICE
/* swap: zamień miejscami v[i] i v[j] */ void swap(char *v[], int i, int j)
{
char *temp; temp = v[i];
v[i] = vfl];
v(j] = temp;
Każdy element tablicy v (synonim lineptr) jest wskaźnikiem do znaków, toteż zmienna tymczasowa temp też musi być takim wskaźnikiem, aby poprawnie kopiować jeden na drugi.
Ćwiczenie 5.7. Zmień funkcję readlines tak, aby budowała wiersze w tablicy dostarczonej przez funkcję main, a nie w obszarach pamięci przydzielanych przez funkcję alloc. O ile szybszy jest program?
W języku C występują prostokątne tablice wielowymiarowe, w praktyce jednak są one rzadziej stosowane niż tablice wskaźników. Pokażemy tu kilka ich właściwości.
Rozważmy problem przekształcania daty, tzn. zamiany dnia miesiąca na dzień roku i odwrotnie. Na przykład 1 marca jest 60 dniem roku zwykłego i 61 dniem roku przestępnego. Zdefiniujemy dwie funkcje: day_of_year przekształcającą miesiąc i dzień na dzień roku oraz month_day przekształcającą dzień roku na miesiąc i dzień. Ta ostatnia funkcja ma obliczyć dwie wartości, niech więc argumenty miesiąc i dzień będą wskaźnikami. Wówczas wywołanie
month_day(1988, 60, &m, &d)
przypisze zmiennej m wartość 2, a zmiennej d wartość 29 (29 lutego).
Obie funkcje wymagają tej samej informacji - tablicy liczby dni w każdym miesiącu („wrzesień ma 30 dni”...). Ponieważ liczby dni w miesiącu różnią się dla lat zwykłych i przestępnych (ang. leap), jest więc prościej rozdzielić je na dwa wiersze dwuwymiarowej tablicy, niż śledzić, co się dzieje z lutym podczas obliczeń. Tablica i funkcja przekształcające wyglądają następująco:
g.7 TABLICE WIELOWYMIAROWE___
powered by
Mi siol
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}
I* day_of_year: podaj dzień roku na podstawie miesiąca i dnia */ int day_of_year(int year, int month, int day)
int i, leap;
leap = year%4 == 0 && year%100 != 0 11 year%400 == 0; for (i = 1; i < month; i++) day += daytab[leap] [i]; return day;
I* month_day: podaj miesiąc i dzień na podstawie dnia roku */ void month_day(int year, int yearday, int *pmonth, int *pday)
int i, leap;
leap = year%4 == 0 && year%100 != 0 11 year%400 == 0; for (i = 1; yearday > daytabjieap] [i]; i++) yearday -= daytab[leap] [ij;
♦prnonth = i;
*pday = yearday;
Przypominamy, że arytmetyczną wartością wyrażenia logicznego, takiego jak przypisywane zmiennej leap, jest albo zero (fałsz), albo 1 (prawda), można jej więc użyć jako indeks tablicy daytab.
Tablica daytab powinna być zewnętrzna dla funkcji day_of_year i month^day, aby obie mogły z niej korzystać. Elementy tablicy zadeklarowaliśmy jako char, ilustrując tym samym legalne zastosowanie obiektów typu char do przechowywania małych liczb całkowitych nie reprezentujących żadnych znaków.
Tablica daytab jest pierwszą tablicą dwuwymiarową, z jaką mamy do czynienia. W języku C tablica dwuwymiarowa jest w rzeczywistości tablicą jednowymiarową, w której każdy z elementów jest tablicą. Zatem indeksy pisze się
daytab[i] [j] /* [wiersz] [kolumna] */
a nie
daytab[i,j] /* ŹLE */
153