【C++ 筆記】結構(Struct) - part 15

很感謝你點進來這篇文章。

你好,我並不是什麼 C++、程式語言的專家,所以本文若有些錯誤麻煩請各位鞭大力一點,我極需各位的指正及指導!!本系列文章的性質主要以詼諧的口吻,一派輕鬆的態度自學程式語言,如果你喜歡,麻煩留言說聲文章讚讚吧!

簡介(Introduction)

Structure(又稱 Struct),英翻中則為結構(體),是一種用來整合不同資料型態的自訂資料型態,讓我們能夠更方便地管理和使用相關的變數。

W3School 這樣定義:

Structures (also called structs) are a way to group several related variables into one place. Each variable in the structure is known as a member of the structure.

結構是一種方法,將多個相關聯的變數分組到一個位置的方法。每個變數在結構裡面則被稱為結構中的成員(member)。

而在 C++ 中 struct 的格式如下:

1
2
3
4
5
6
7
struct type_name {
member_type1 member_name1;
member_type2 member_name2;
member_type3 member_name3;
.
.
} object_names;

type_name 為結構體型態的名稱。

member_type1:為內部結構的成員 1 之資料型態。

member_name1:為內部結構的成員 1 之變數名稱。

總之,結構體可讓我們把多個不同型態的變數(如 int、char、float 等)放在一起,形成一個集合。例如:可以用來描述一個學生的資料,包括學號、姓名和年齡等。

1
2
3
4
5
struct Student {
int id; // 學號
char name[50]; // 姓名
int age; // 年齡
};

記得要使用結構體時,要事前做以下的宣告(示範):

1
Student student1;

前面是結構體名稱,後面則為自己定義的變數名稱,此為成員變數。

以下是有關於結構體的優點:

  • 簡單資料封裝:適合封裝多種型態的簡單資料,通常用於資料的儲存。
  • 輕量級:比起 class,結構體語法較簡潔,適合小型資料物件。
  • 物件導向支援:支援建構函數、成員函數和存取權限控制,可以實現物件導向的設計。
  • 靜態配置:結構體在記憶體中佔用的空間是所有成員大小的總和,這使得它在處理相關資料時非常方便。

所以 struct 可被稱為 lite 版 class。

來源:https://www.runoob.com/cplusplus/cpp-struct.html

你可能聽不太懂以上是蝦咪東東,因為 Struct 跟物件導向技術有很大的相關聯,總之,之後學 class 時就知道了。

存取結構成員(Access structure members)

用點運算子(.)以結構體變數名稱作為前綴,後綴為結構體內的成員名字。

如:student1.id

以下是一個範例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#include <iostream>
#include <cstring>

using namespace std;

struct Student {
int id;
char name[50];
int age;
};

int main() {
Student student1; // 宣告 Student 結構體變數
student1.id = 12345;
strcpy(student1.name, "John Doe");
student1.age = 20;

// 輸出學生資料
cout << "ID: " << student1.id << endl;
cout << "Name: " << student1.name << endl;
cout << "Age: " << student1.age << endl;

return 0;
}

輸出結果:

1
2
3
ID: 12345
Name: John Doe
Age: 20

結構作為函數參數(Structure as function parameter)

傳遞參數的方式如一般傳參方法類似,以下是個範例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
#include <iostream>
#include <cstring>

using namespace std;
void printBook( struct Books book );

// 宣告一個結構體型態 Book
struct Books
{
char title[50];
char author[50];
char subject[100];
int book_id;
};

int main( )
{
Books Book1; // 定義結構體型態 Books 的變數 Book1
Books Book2; // 定義結構體型態 Books 的變數 Book2

// Book1 詳述
strcpy( Book1.title, "C++ 教學");
strcpy( Book1.author, "Runoob");
strcpy( Book1.subject, "程式語言");
Book1.book_id = 12345;

// Book2 詳述
strcpy( Book2.title, "CSS 教學");
strcpy( Book2.author, "Runoob");
strcpy( Book2.subject, "前端技術");
Book2.book_id = 12346;

// 輸出 Book1 訊息
printBook( Book1 );

// 輸出 Book2 訊息
printBook( Book2 );

return 0;
}
void printBook( struct Books book )
{
cout << "書標題 : " << book.title <<endl;
cout << "書作者 : " << book.author <<endl;
cout << "書類目 : " << book.subject <<endl;
cout << "書 ID : " << book.book_id <<endl;
}

輸出結果:

1
2
3
4
5
6
7
8
書標題 : C++ 教學
書作者 : Runoob
書類目 : 程式語言
書 ID : 12345
書標題 : CSS 教學
書作者 : Runoob
書類目 : 前端技術
書 ID : 12346

來源:https://www.runoob.com/cplusplus/cpp-struct.html

結構指標(structure pointer)

我們可以定義一個指向結構的指標,方法就如同一般的指標指向方式一樣,如下:

1
struct Books *struct_pointer;

如果我們有一個指向結構的指標,則用箭頭 ( -> ) 運算子而不是點 ( . ) 運算子來存取成員,如下:

1
struct_pointer->title;

以下是個範例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include <iostream>
using namespace std;

struct Point {
int x, y;
};

int main()
{
struct Point p1 = { 1, 2 };

// p2 指標指向結構 p1
struct Point* p2 = &p1;

// 存取結構成員
// 結構指標
cout << p2->x << " " << p2->y;
return 0;
}

輸出結果:

1
1 2

Source:https://www.geeksforgeeks.org/structures-in-cpp/

typedef keyword

typedef 是 C++ 中的關鍵字,用於為已有的資料型態建立別名。可使程式碼更具可讀性跟可維護性,尤其在處理複雜型態時。

typedef 的基本語法如下:

1
typedef existing_type new_type_name;

此語句會將 existing_type 的別名定義為 new_type_name,使得在後續的程式碼中可用 new_type_name 來代替 existing_type

另外,此關鍵字具有以下三種用途:

  1. 簡化複雜型態:在處理指標、結構或函數指標等複雜型態時,使用 typedef 可簡化宣告。
  2. 增強可讀性:用有意義的名稱來替代原始型態,可提高代碼的可讀性。
  3. 封裝實作細節:當需要更改資料型態的實現時,只需更改 typedef 的定義,而不必修改所有使用該型態的地方。

以下為實作 typedef 中常見的幾種類型:

  • 基本型態的別名:
1
2
typedef int size; // size 是 int 的別名
size length = 10; // 以 size 作為變數之資料型態
  • 結構體的別名:
1
2
3
4
5
6
7
typedef struct {
char name[50];
int age;
} Person;

Person p1; // 現在可用 Person 作為結構之型態
// 原本只能寫成 struct Person p1; 現在用 typedef 可簡化
  • 指標和函數指標:
1
2
3
4
typedef void (*FuncPtr)(int); // 定義一個函數指標型態
void myFunction(int a) { /* ... */ }

FuncPtr f = myFunction; // 用 FuncPtr 作為函數指標型態

需要值得注意的是,typedef 的作用域遵循普通變數的作用域規則。在不同的作用域中,可能會有相同名稱的 typedef 定義,可能會導致名稱遮蔽。建議在用 typedef 時選擇具有描述性的名稱以避免混淆。

參考資料

C/C++ typedef 用法與範例 | ShengYu Talk

typedef in C++ - GeeksforGeeks

別名和 typedef (C++) | Microsoft Learn

Structures in C++ - GeeksforGeeks

C++ Structures (struct)

[C++] 結構與類別(struct & class) - HackMD

struct (C++) | Microsoft Learn

C++ 结构体(struct) | 菜鸟教程