1. 程式人生 > 其它 >C語言結構體詳解

C語言結構體詳解

C語言中為什麼會有結構體

主要是基本資料型別沒有辦法展現我們需要的實體。比如我們要表現一個實體————人,那麼我們需要姓名name,年齡age,性別sex,家庭關係如父母parent等等。

C語言如何定義結構體

在C語言中,可以使用結構體(Struct)來存放一組不同型別的資料。結構體的定義形式為:

struct 結構體名{
    結構體所包含的變數或陣列
};

結構體是一種集合,它裡面包含了多個變數或陣列,它們的型別可以相同,也可以不同,每個這樣的變數或陣列都稱為結構體的成員(Member)。請看下面的一個例子:

struct Person {
  char* name;  // 姓名
  int age;     // 年齡
  int sex;     // 姓名
  Person* parent;  // 父母
};

注意點1:以分號結尾

注意大括號後面的分號;不能少,這是一條完整的語句。
如果不加這個分號,會出現編譯錯誤: error C2628: “Person”後面接“int”是非法的(是否忘記了“;”?)

注意點2:結構體成員型別為自身

當結構體內的成員變數的型別是自身時,需要用指標。
比如Person中引用Person型別的變數parent,此時需要用指標來儲存引用。否則會出現編譯錯誤:error C2460: “Person::parent”: 使用正在定義的“Person”

C語言結構體的大小

我們先在32位編譯模式下編譯以下程式:

#include <stdio.h>
#include <stdlib.h>

struct A {
	char c1;
	char c2;
	int i;
};

struct B {
	char c1;
	int i;
	char c2;
};

int main()
{
	printf("Size of A: %d bytes.\n", sizeof(A));
	printf("Size of B: %d bytes.\n", sizeof(B));

	A a = {'a', 'b', 1024};
	printf("&a.c1:0x%08X\n&a.c2:0x%08X\n&a.i:0x%08X\n", &a.c1, &a.c2, &a.i);

	B b = {'A', 65536, 'B'};
	printf("&b.c1:0x%08X\n&b.i:0x%08X\n&b.c2:0x%08X\n", &b.c1, &b.i, &b.c2);

	system("pause");
	return 0;
}
  • &是取地址符,可以獲取變數的記憶體地址
  • %08X表示以16進製表示,字母大寫,最小寬度為8,如果不足8位,以0補足。

一次實驗的輸出結果如下:

  • 結構體A與結構體B的大小不等。結構體A的大小為8位元組,結構體B的大小為12位元組。
  • 上圖中一個單元格表示一個位元組單元;
  • 每個位元組單元都對應一個記憶體地址;
  • 記憶體地址由下向上依次增加;

成員的獲取與賦值

1. 定義變數

Person person1;
struct Person person2;

這兩種方式均可,前面可以寫struct,也可以不寫

2. 給結構體成員賦值

Person person1;
person1.age = 10;

3. 訪問結構體成員

printf("%d", person1.age);

4. 整體賦值

之前用到的這兩條語句就是整體賦值的例子:

A a = {'a', 'b', 1024};
B b = {'A', 65536, 'B'};
  • 不過整體賦值僅限於定義結構體變數的時候,在使用過程中只能對成員逐一賦值,這和陣列的賦值非常類似。

5. 定義結構體和定義變數結合

struct Student {
    char *name;  //姓名
    int num;  //學號
    int age;  //年齡
    char group;  //所在小組
    float score;  //成績
} stu1, stu2 = { "Tom", 12, 18, 'A', 136.5 };

上面這段程式碼相當於把定義結構體和定義變數的程式碼組合起來了:

// 定義結構體Student
struct Student {
    char *name;  //姓名
    int num;  //學號
    int age;  //年齡
    char group;  //所在小組
    float score;  //成績
};

並且,變數stu1沒有賦值,而變數stu2進行了整體賦值:

// 定義變數
Student stu1;
Student stu2 = { "Tom", 12, 18, 'A', 136.5 };

typedef struct

  • typedef struct Student {...} Stu;struct Student {...} stu;不同,前者 Stu 表示的是型別(相當於Student的別名),後者 stu 表示的是變數;
  • typedef struct Student {...} Stu; 相當於定義結構體語句 struct Student {...}; 與定義型別語句 typedef Student Stu; 的組合;
  • struct Student {...} stu; 相當於定義結構體語句 struct Student {...}; 與定義變數語句 Student stu 的組合;

我們再來看一個 typedef struct 的複雜例子:

typedef struct Student {
    char *name;  //姓名
    int num;  //學號
    int age;  //年齡
    char group;  //所在小組
    float score;  //成績
} Stu, *PStu;

然後,我們可以用 PStu 來表示指標型別:

PStu stu1 = (PStu)malloc(sizeof(PStu));
stu1->age = 11;

上面這段程式碼就等同於

Stu* stu1 = (Stu*)malloc(sizeof(Stu));
stu1->age = 11;

Learn More

《C語言結構體詳解,C語言struct用法詳解》閱讀