6.1
點是最基本的對象,假定用 x 與 y 座標表示它,且 x、y 的座標值都爲整數。
採用結構存放這兩個座標:
struct point {
int x;
int y;
};
結構可以嵌套。我們可以用對角線上的兩個點來定義矩形:
struct rect {
struct point pt1;
struct point pt2;
};
struct rect screen;
可以用語句 screen.pt1.x 引用 screen 的成員 pt1 的 x 座標。
6.2
/* makepoint: make a point from x and y components */
struct point makepoint(int x, int y)
{
struct point temp;
temp.x = x;
temp.y = y;
return temp;
}
struct rect screen;
struct point middle;
struct point makepoint(int, int);
screen.pt1 = makepoint(0, 0);
screen.pt2 = makepoint(XMAX, YMAX);
middle = makepoint((screen.pt1.x + screen.pt2.x)/2, (screen.pt1.y + screen.pt2.y)/2);
/* addpoints: add two points */
struct addpoint(struct point p1, struct point p2)
{
p1.x += p2.x;
p1.y += p2.y;
return p1;
}
/* ptinrect: return 1 if p in r, 0 if not */
int prinrect(struct point p, struct rect r)
{
return p.x >= r.pt1.x && p.x < r.pt2.x && p.y >= r.pt1.y && p.y < r.pt2.y;
}
#define min(a, b) ((a) < (b) ? (a) : (b))
#define max(a, b) ((a) > (b) ? (a) : (b))
/* canonrect: canonicalize coordinate of rectangle */
struct rect canonrect(struct rect r)
{
struct rect temp;
temp.pt1.x = min(r.pt1.x, r.pt2.x);
temp.pt1.y = min(r.pt1.y, r.pt2.y);
temp.pt2.x = max(r.pt1.x, r.pt2.x);
remp.pt3.y = max(r.pt1.y, r.pt2.y);
return temp;
}
如果傳遞給函數的結構很大,使用指針方式的效率通常比複製整個結構的效率要高。結構指針類似於普通變量指針。
struct point *pp;
將pp定義爲一個指向struct point 類型對象的指針。如果 pp 指向一個 point 結構,那麼 *pp 即爲該結構,而 (*pp).x 和 (*pp).y 則是結構成員。可以按照下例中的方式使用 pp:
struct point origin, *pp;
pp = &origin;
printf("origin is (%d, %d)\n", (*pp).x, (*pp).y);
其中,(*pp).x 中的圓括號是必須的,因爲結構成員運算符 “.” 的優先級比 “*” 的優先級高。
結構指針的使用頻度非常高,爲了使用方便,C 語言提供了另一種簡寫方式。假定 p 是一個指向結構的指針,可以用
p->結構成員
這種形式引用相應的結構成員。
6.4
#include <stdio.h>
#include <ctype.h>
#include <string.h>
#define MAXWORD 100
int getword(char *, int);
struct key *binsearch(char *, struct key *, int);
/* count C keywords; pointer version */
int main()
{
char word[MAXWORD];
struct key *p;
while (getword(word, MAXWORD) != EOF)
if (isalpha(word[0]))
if ((p=binsearch(word, keytab, NKEYS)) != NULL)
p->count++;
for (p = keytab; p < keytab + NKEYS; p++)
if (p->count > 0)
printf("%4d %s\n", p->count, p->word);
return 0;
}
/* binsearch: find word in tab[0] ... tab[n-1] */
struct key *binsearch(char *word, struct key *tab, int n)
{
int cond;
struct key *low = &tab[0];
struct key *high = &tab[n];
struct key *mid;
while (low < high)
{
mid = low + (high-low)/2;
if ((cond = strcmp(word, mid->word)) < 0)
high = mid;
else if (cond > 0)
low = mid + 1;
else
return mid;
}
return NULL;
}
我們無法簡單的通過下列表達式計算中間元素的位置:
mid = (low + high) / 2; /* wrong */
這是因爲,兩個指針之間的加法運算是非法的。但是,指針的減法運算卻是合法的。high-low的值就是數組元素的個數,
因此,可以用下列表達式:
mid = low + (high-low) / 2;