結構體的自引用(self reference),就是在結構體內部,包含指向自身類型結構體的指針。
結構體的相互引用(mutual reference),就是說在多個結構體中,都包含指向其他結構體的指針。
1. 自引用 結構體
1.1 不使用typedef時
錯誤的方式:
struct tag_1{ struct tag_1 A; /* 結構體 */ int value; };
這種聲明是錯誤的,因為這種聲明實際上是一個無限循環,成員b是一個結構體,b的內部還會有成員是結構體,依次下去,無線循環。在分配內存的時候,由于無限嵌套,也無法確定這個結構體的長度,所以這種方式是非法的。
正確的方式: (使用指針):
struct tag_1{ struct tag_1 *A; /* 指針 */ int value; };
由于指針的長度是確定的(在32位機器上指針長度為4),所以編譯器能夠確定該結構體的長度。
1.2 使用typedef 時
錯誤的方式:
typedef struct { int value; NODE *link; /* 雖然也使用指針,但這里的問題是:NODE尚未被定義 */ } NODE;
這里的目的是使用typedef為結構體創建一個別名NODEP。但是這里是錯誤的,因為類型名的作用域是從語句的結尾開始,而在結構體內部是不能使用的,因為還沒定義。
正確的方式:有三種,差別不大,使用哪種都可以。
/* 方法一 */ typedef struct tag_1{ int value; struct tag_1 *link; } NODE; /* 方法二 */ struct tag_2; typedef struct tag_2 NODE; struct tag_2{ int value; NODE *link; }; /* 方法三 */ struct tag_3{ int value; struct tag *link; }; typedef struct tag_3 NODE;
2. 相互引用 結構體
錯誤的方式:
typedef struct tag_a{ int value; B *bp; /* 類型B還沒有被定義 */ } A; typedef struct tag_b{ int value; A *ap; } B;
錯誤的原因和上面一樣,這里類型B在定義之 前 就被使用。
正確的方式:(使用“不完全聲明”)
/* 方法一 */ struct tag_a{ struct tag_b *bp; /* 這里struct tag_b 還沒有定義,但編譯器可以接受 */ int value; }; struct tag_b{ struct tag_a *ap; int value; }; typedef struct tag_a A; typedef struct tag_b B; /* 方法二 */ struct tag_a; /* 使用結構體的不完整聲明(incomplete declaration) */ struct tag_b; typedef struct tag_a A; typedef struct tag_b B; struct tag_a{ struct tag_b *bp; /* 這里struct tag_b 還沒有定義,但編譯器可以接受 */ int value; }; struct tag_b{ struct tag_a *ap; int value; };
3.實例:
應用結構體指針變量,打印結構體成員變量的信息。
#include <stdio.h>struct Point{double x; /*x坐標*/double y; /*y坐標*/double z; /*z坐標*/};int main(){struct Point oPoint1={100,100,0};struct Point oPoint2;struct Point *pPoint; /*定義結構體指針變量*/pPoint=& oPoint2; /*結構體指針變量賦值*/(*pPoint).x= oPoint1.x;(*pPoint).y= oPoint1.y;(*pPoint).z= oPoint1.z;printf("oPoint2={%7.2f,%7.2f,%7.2f}",oPoint2.x, oPoint2.y, oPoint2.z);return(0);}
程序運行結果如下:
oPoint2={ 100.00,100.00,0.00}
其中表達式&oPoint2的作用是獲得結構體變量oPoint2的地址。表達式pPoint=&oPoint2的作用是將oPoint2的地址存儲在結構體指針變量pPoint中,因此pPoint存儲了oPoint2的地址。*pPoint代表指針變量pPoint中的內容,因此*pPoint 和oPoint2等價。
通過結構體指針變量獲得其結構體變量的成員變量的一般形式如下:
(*結構體指針變量). 成員變量
其中“結構體指針變量”為結構體指針變量,“成員變量”為結構體成員變量名稱,“.”為取結構體成員變量的運算符。
另外C語言中引入了新的運算符“->”,通過結構體指針變量直接獲得結構體變量的成員變量,一般形式如下:
結構體指針變量-> 成員變量
其中“結構體指針變量”為結構體指針變量,“成員變量”為結構體成員變量名稱,“- >”為運算符。
因此,例中的部分代碼
……(*pPoint).x= oPoint1.x;(*pPoint).y= oPoint1.y;(*pPoint).z= oPoint1.z;……
等價于
……pPoint->x= oPoint1.x;pPoint->y= oPoint1.y;pPoint->z= oPoint1.z;……
新聞熱點
疑難解答
圖片精選