當前位置:才華齋>計算機>C語言>

C語言中結構體的自引用和相互引用詳細講解

C語言 閱讀(2.19W)

本文主要介紹了C語言中結構體的自引用和相互引用,詳細解析了結構體中指標的指向情況,有需要的小夥伴可以參考一下,希望對大家有所幫助!想了解更多相關資訊請持續關注我們應屆畢業生考試網!

C語言中結構體的自引用和相互引用詳細講解

結構體的自引用(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;

……