6 STRUKTURY_
struct rect {
struct point pt1; struct point pt2;
Struktura rect zawiera dwie struktury point. Jeśli zadeklarujemy screen (ekran) jaki
struct rect screen;
to konstrukcja screen.pt1.x
odnosi się do współrzędnej x punktu pt1, który jest składową zmiennej screen.
Dozwolonymi operacjami dla struktury są: przypisanie jej innej struktury w całośc; skopiowanie jej w całości na inną strukturę, pobranie jej adresu za pomocą operator-& oraz odwołania do jej składowych. Przez kopiowanie i przypisanie rozumie się także przesyłanie argumentów funkcjom i zwracanie przez funkcje wartości. Struktur nie można natomiast porównywać. Strukturę można zainicjować listą stałych wartości początkowych jej składowych; automatyczną strukturę można też zainicjować za pomocą przypisania.
Spróbujemy zbadać właściwości struktur, pisząc kilka funkcji manipulujących punktami i prostokątami. Istnieją co najmniej trzy sposoby podejścia do zagadnienia: prze kazywanie składników oddzielnie, przekazywanie całej struktury lub przekazywani; wskaźnika do tej struktury. Każdy z nich ma swoje wady i zalety.
Pierwsza funkcja, makepoint, z podanych dwóch wartości całkowitych buduje i zwraca strukturę typu point:
/* makepoint: utwórz punkt ze współrzędnych x i y */ struct point makepoint(int x, int y)
struct point temp;
temp.x = x; temp.y = y; return temp;
} 8
Zwróć uwagę na to, że nie ma konfliktu między nazwami argumentów i składowych struktury; ponowne użycie tych samych nazw faktycznie jeszcze bardziej uwypukla wzajemny związek między nimi.
funkcję makepoint można teraz stosować do dynamicznego inicjowania dowolnej struktury lub do budowania strukturowych argumentów funkcji:
struct rect screen;
struct point middle;
struct point makepoint(int, int);
screen.pt1 = makepoint(0, 0);
screen.pt2 = makep/oint(XMAX, YMAX);
middle = makepoint((screen.pt1.x + screen.pt2.x)/2,
(screen.pt1 ,y + screen.pt2.y)/2);
Teraz zbudujemy kilka funkcji realizujących arytmetykę na punktach. Na przykład
I* addpoint: dodaj dwa punkty */
struct point addpoint(struct point pi, struct point p2)
p1.x += p2.x;
P1 .y 4- p2.y; return pi;
Tutaj oba argumenty i zwracana wartość są strukturami. Zamiast tworzyć zmienną tymczasową, zwiększyliśmy składowe w strukturze p1 po to, by podkreślić, że struktury są tak samo przekazywane funkcji przez wartość, jak wszystkie inne argumenty.
Innym przykładem jest funkcja ptinrect, w której sprawdza się, czy punkt leży wewnątrz prostokąta. Przyjęliśmy tu konwencję, że prostokąt zawiera swoje krawędzie lewą i dolną, ale nie zawiera krawędzi górnej i prawej:
/* ptinrect: zwróć 1 jeśli p należy do r, 0 jeśli nie należy */ int ptinrect(struct point p, struct rect r)
return p.x >= r.pt1.x && p.x < r.pt2.x && p.y >= r.ptt.y && p.y < r.pt2.y;
177
Język ANSI C
12