1. 程式人生 > >C語言結構體陣列遇上typedef

C語言結構體陣列遇上typedef

昨天韓同學在做資料結構題的時候,問了我一個關於typedef 與結構體陣列的問題:

1 typedef struct vexnode
2 {
3   int vertex;
4   arcnode* firstarc;
5 }adjlist[Vnum];

這裡我們先回顧一下struct是怎麼使用的。

1.有名構造型別-結構體

1 struct student //<-------結構名
2 {
3   char name[30]; //<-------結構成員
4   char sex;
5   int age;
6   float high;
7 }stu;      //<--------定義資料型別同時定義stu
結構體變數(不要忘記;號,在C語言中,凡是構造型別都要加分號,比如union
8 struct student stu2; //<-------這時候我們還可以用struct student結構體型別定義另一個 stu2結構體成員變數(此處的struct不可省,在C++中才可以省略)

2.別名構造型別-結構體

上面我們使用有名構造型別-結構體可以滿足要求了,為何還要有個別名構造型別呢?

因為你看上面的第8行程式碼,我們定義一個新的結構體型別變數時,每次都要寫上長長的字首struct student 不太方便簡潔,而且在大型專案中,變數往往都佔用了很長的位置,更顯累贅,於是typedef 登場了。

我們先看個例子:

1 typedef struct student
2 {
3   char name[30];
4   char sex;
5   int age;
6   float high;
7 }STUDENT;
8 STUDENT stu, stu2;

對比上面兩例的程式碼,我們發現是不是隻有兩點差異:

1.struct 前添加了typedef

2.結構體的右下角右括號}後的結構體變數stu替換成了STUDENT

於是,我們就可以用student結構體型別的別名STUDENT去定義結構體變數啦!就有了第8 行程式碼,與我們的基本資料型別例如 int a ,是不是一致啦!

別忙,我們先理清下思路到底是怎麼給結構體型別取別名的?我想通過我上面的分析可以歸納出以下兩個步驟:

1.先按照有名構造型別-結構體 的方式定義結構體型別,同時定義一個結構體變數;

2.在定義好的結構體型別struct 前新增typedef,然後把定義的結構體變數替換成你取定的別名。

 

回到最初的問題,韓同學問我的typedef {...}adjlist[Vnum]; 這裡我們就可以這樣理解啦!

struct {....}adjlist[Vnum] 了一個結構體型別並且同時聲明瞭一個adjlist[Vnum] 結構體變數,這個變數有點特殊,它是個陣列,合起來就是結構體陣列,既然名叫結構體陣列,那麼這個陣列中的每個元素的型別不就是 我們定義的結構體型別嗎?

再按照我們上面取別名的步驟,先typedef,然後把結構體變數換成你要取得別名,這裡比較特殊的是,我們取得結構體別名就是結構體陣列,謹記,那麼adjlist 代表的就不僅僅代表一個結構體型別了,它被賦予了外加的一個特性:陣列;也就是說如果我們這樣寫

1 adjlist a;

那麼上面的程式碼中 a 就是一個結構體陣列了,a中的每個元素都是我們定義的結構體型別。看到這你就差不多會用了,但是不是感覺還是有點未懂?

哎,其實我給你看下面的程式碼:

1 typedef struct vexnode
2 {
3   int vertex;
4   arcnode* firstarc;
5 }[Vnum] adjlist;

你看,我把[Vnum]放在了前面 與前面的struct 一個整體 你是不是就明白了,其實原理也是這樣的,只是C編譯器不認識這種語法,我們把它放在後面了而已,但這種其實才符合人的思維。

小結:

  1、我們定義的新型別,它的地位等同於int 型別。還只是個模子,如果沒有生成
  2、變數的話,是不會佔用空間的。
  3、結構定義放置在程式的開始部分,位於標頭檔案宣告之後。
  4、注意{}不表示覆合語句,其後有分號。
  5、結構體型別名稱是struct+結構體名,注意struct 關鍵字不能省略。

  6、結構體陣列的typedef 中我們可以把[] 前置 來幫助我們理解,但實際應用還是正常使用。