本文主要介紹了C語言中結(jié)構(gòu)體的自引用和相互引用,詳細解析了結(jié)構(gòu)體中指針的指向情況,有需要的小伙伴可以參考一下,希望對大家有所幫助!想了解更多相關(guān)信息請持續(xù)關(guān)注我們應(yīng)屆畢業(yè)生考試網(wǎng)!

  結(jié)構(gòu)體的自引用(self reference),就是在結(jié)構(gòu)體內(nèi)部,包含指向自身類型結(jié)構(gòu)體的指針。

  結(jié)構(gòu)體的相互引用(mutual reference),就是說在多個結(jié)構(gòu)體中,都包含指向其他結(jié)構(gòu)體的指針。

  1. 自引用 結(jié)構(gòu)體

  1.1 不使用typedef時

  錯誤的方式:

  struct tag_1{

  struct tag_1 A; /* 結(jié)構(gòu)體 */

  int value;

  };

  這種聲明是錯誤的,因為這種聲明實際上是一個無限循環(huán),成員b是一個結(jié)構(gòu)體,b的內(nèi)部還會有成員是結(jié)構(gòu)體,依次下去,無線循環(huán)。在分配內(nèi)存的時候,由于無限嵌套,也無法確定這個結(jié)構(gòu)體的長度,所以這種方式是非法的。

  正確的方式: (使用指針):

  struct tag_1{

  struct tag_1 *A; /* 指針 */

  int value;

  };

  由于指針的長度是確定的(在32位機器上指針長度為4),所以編譯器能夠確定該結(jié)構(gòu)體的長度。

  1.2 使用typedef 時

  錯誤的方式:

  typedef struct {

  int value;

  NODE *link; /* 雖然也使用指針,但這里的問題是:NODE尚未被定義 */

  } NODE;

  這里的目的是使用typedef為結(jié)構(gòu)體創(chuàng)建一個別名NODEP。但是這里是錯誤的,因為類型名的作用域是從語句的結(jié)尾開始,而在結(jié)構(gòu)體內(nèi)部是不能使用的,因為還沒定義。

  正確的方式:有三種,差別不大,使用哪種都可以。

  /* 方法一 */

  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. 相互引用 結(jié)構(gòu)體

  錯誤的方式:

  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; /* 使用結(jié)構(gòu)體的不完整聲明(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.實例:

  應(yīng)用結(jié)構(gòu)體指針變量,打印結(jié)構(gòu)體成員變量的信息。

  #include

  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; /*定義結(jié)構(gòu)體指針變量*/

  pPoint=& oPoint2;   /*結(jié)構(gòu)體指針變量賦值*/

  (*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);

  }

  程序運行結(jié)果如下:

  oPoint2={ 100.00,100.00,0.00}

  其中表達式&oPoint2的作用是獲得結(jié)構(gòu)體變量oPoint2的地址。表達式pPoint=&oPoint2的作用是將oPoint2的地址存儲在結(jié)構(gòu)體指針變量pPoint中,因此pPoint存儲了oPoint2的地址。*pPoint代表指針變量pPoint中的內(nèi)容,因此*pPoint 和oPoint2等價。

  通過結(jié)構(gòu)體指針變量獲得其結(jié)構(gòu)體變量的成員變量的一般形式如下:

  (*結(jié)構(gòu)體指針變量). 成員變量

  其中“結(jié)構(gòu)體指針變量”為結(jié)構(gòu)體指針變量,“成員變量”為結(jié)構(gòu)體成員變量名稱,“.”為取結(jié)構(gòu)體成員變量的運算符。

  另外C語言中引入了新的運算符“->”,通過結(jié)構(gòu)體指針變量直接獲得結(jié)構(gòu)體變量的成員變量,一般形式如下:

  結(jié)構(gòu)體指針變量-> 成員變量

  其中“結(jié)構(gòu)體指針變量”為結(jié)構(gòu)體指針變量,“成員變量”為結(jié)構(gòu)體成員變量名稱,“- >”為運算符。

  因此,例中的部分代碼

  ……

  (*pPoint).x= oPoint1.x;

  (*pPoint).y= oPoint1.y;

  (*pPoint).z= oPoint1.z;

  ……

  等價于

  ……

  pPoint->x= oPoint1.x;

  pPoint->y= oPoint1.y;

  pPoint->z= oPoint1.z;

  ……

1.《互的結(jié)構(gòu) C語言中結(jié)構(gòu)體的自引用和相互引用詳細講解》援引自互聯(lián)網(wǎng),旨在傳遞更多網(wǎng)絡(luò)信息知識,僅代表作者本人觀點,與本網(wǎng)站無關(guān),侵刪請聯(lián)系頁腳下方聯(lián)系方式。

2.《互的結(jié)構(gòu) C語言中結(jié)構(gòu)體的自引用和相互引用詳細講解》僅供讀者參考,本網(wǎng)站未對該內(nèi)容進行證實,對其原創(chuàng)性、真實性、完整性、及時性不作任何保證。

3.文章轉(zhuǎn)載時請保留本站內(nèi)容來源地址,http://f99ss.com/jiaoyu/76734.html