【C++ 筆記】結構(Struct) - part 15
===
目錄(Table of Contents):
[TOC]
---
很感謝你點進來這篇文章。
你好,我並不是什麼 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 的格式如下:
```cpp
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 等)放在一起,形成一個集合。例如:可以用來描述一個學生的資料,包括學號、姓名和年齡等。
```cpp=
struct Student {
int id; // 學號
char name[50]; // 姓名
int age; // 年齡
};
```
記得要使用結構體時,要事前做以下的宣告(示範):
```cpp
Student student1;
```
前面是結構體名稱,後面則為自己定義的變數名稱,此為成員變數。
以下是有關於結構體的優點:
* **簡單資料封裝**:適合封裝多種型態的簡單資料,通常用於資料的儲存。
* **輕量級**:比起 class,結構體語法較簡潔,適合小型資料物件。
* **物件導向支援**:支援建構函數、成員函數和存取權限控制,可以實現物件導向的設計。
* **靜態配置**:結構體在記憶體中佔用的空間是所有成員大小的總和,這使得它在處理相關資料時非常方便。
所以 struct 可被稱為 lite 版 class。
來源:https://www.runoob.com/cplusplus/cpp-struct.html
你可能聽不太懂以上是蝦咪東東,因為 Struct 跟物件導向技術有很大的相關聯,總之,之後學 class 時就知道了。
存取結構成員(Access structure members)
---
用點運算子(`.`)以結構體變數名稱作為前綴,後綴為結構體內的成員名字。
如:`student1.id`
以下是一個範例:
```cpp=
#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;
}
```
輸出結果:
```
ID: 12345
Name: John Doe
Age: 20
```
結構作為函數參數(Structure as function parameter)
---
傳遞參數的方式如一般傳參方法類似,以下是個範例:
```cpp=
#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;
}
```
輸出結果:
```
書標題 : C++ 教學
書作者 : Runoob
書類目 : 程式語言
書 ID : 12345
書標題 : CSS 教學
書作者 : Runoob
書類目 : 前端技術
書 ID : 12346
```
來源:https://www.runoob.com/cplusplus/cpp-struct.html
結構指標(structure pointer)
---
我們可以定義一個指向結構的指標,方法就如同一般的指標指向方式一樣,如下:
```cpp
struct Books *struct_pointer;
```
如果我們有一個指向結構的指標,則用箭頭 ( `->` ) 運算子而不是點 ( `.` ) 運算子來存取成員,如下:
```cpp
struct_pointer->title;
```
以下是個範例:
```cpp=
#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 2
```
Source:https://www.geeksforgeeks.org/structures-in-cpp/
typedef keyword
---
`typedef` 是 C++ 中的關鍵字,用於為已有的資料型態建立別名。可使程式碼更具可讀性跟可維護性,尤其在處理複雜型態時。
`typedef` 的基本語法如下:
```cpp
typedef existing_type new_type_name;
```
此語句會將 `existing_type` 的別名定義為 `new_type_name`,使得在後續的程式碼中可用 `new_type_name` 來代替 `existing_type`。
另外,此關鍵字具有以下三種用途:
1. 簡化複雜型態:在處理指標、結構或函數指標等複雜型態時,使用 `typedef` 可簡化宣告。
2. 增強可讀性:用有意義的名稱來替代原始型態,可提高代碼的可讀性。
3. 封裝實作細節:當需要更改資料型態的實現時,只需更改 `typedef` 的定義,而不必修改所有使用該型態的地方。
以下為實作 `typedef` 中常見的幾種類型:
* 基本型態的別名:
```cpp=
typedef int size; // size 是 int 的別名
size length = 10; // 以 size 作為變數之資料型態
```
* 結構體的別名:
```cpp=
typedef struct {
char name[50];
int age;
} Person;
Person p1; // 現在可用 Person 作為結構之型態
// 原本只能寫成 struct Person p1; 現在用 typedef 可簡化
```
* 指標和函數指標:
```cpp=
typedef void (*FuncPtr)(int); // 定義一個函數指標型態
void myFunction(int a) { /* ... */ }
FuncPtr f = myFunction; // 用 FuncPtr 作為函數指標型態
```
需要值得注意的是,`typedef` 的作用域遵循普通變數的作用域規則。在不同的作用域中,可能會有相同名稱的 `typedef` 定義,可能會導致名稱遮蔽。建議在用 `typedef` 時選擇具有描述性的名稱以避免混淆。
參考資料
---
[C/C++ typedef 用法與範例 | ShengYu Talk](https://shengyu7697.github.io/cpp-typedef/)
[typedef in C++ - GeeksforGeeks](https://www.geeksforgeeks.org/typedef-in-cpp/)
[別名和 typedef (C++) | Microsoft Learn](https://learn.microsoft.com/zh-tw/cpp/cpp/aliases-and-typedefs-cpp?view=msvc-170)
[Structures in C++ - GeeksforGeeks](https://www.geeksforgeeks.org/structures-in-cpp/)
[C++ Structures (struct)](https://www.w3schools.com/cpp/cpp_structs.asp)
[[C++] 結構與類別(struct & class) - HackMD](https://hackmd.io/@howkii-studio/SkX4rSWyP)
[struct (C++) | Microsoft Learn](https://learn.microsoft.com/zh-tw/cpp/cpp/struct-cpp?view=msvc-170)
[C++ 结构体(struct) | 菜鸟教程](https://www.runoob.com/cplusplus/cpp-struct.html)