0%

0-11 struct

被遞迴摧殘後的大家還好嗎?放心,最難的一章過了,之後的會輕鬆許多。

這是在 11/11 更新的第 11 小節!

struct 是什麼?

這篇寫得太好,偷懶一下XD。這篇由於使用的是 C 語言,因此寫法略有不同,但概念是一樣的。

總之,struct 的出現,讓我們可以自己定義一個新的變數型態,而這個型態能夠把很多不同的變數包在一起,甚至可以定義自己的函式與運算子。

基礎語法

語法是這樣的:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include<bits/stdc++.h>
using namespace std;

struct my_struct{
int x;
double y;
string s;
} c;//要有分號

int main(){
my_struct a;
a.x = 45;
a.y = 55.232;
a.s = "This is a string";

my_struct b{1,1.23,"Another way of declaration."}; // 另一種宣告方法

cout<<a.x<<" "<<a.y<<" "<<a.s<<'\n';
cout<<b.x<<" "<<b.y<<" "<<b.s<<'\n';
c.x = 10;
cout<<c.x<<'\n';
}

輸出:

1
2
45 55.232 This is a string
1 1.23 Another way of declaration.

宣告部分,可以像一般宣告變數那樣,直接 my_struct a。也可以在後方加上大括號{}以傳入值。特別的是,可以直接在 struct 的最後宣告。

使用上,以 . 來取得元素,a.x 代表的就是 a 的 x 項,可參考上方 code。

自定義比較

要如何比較兩個 struct 的大小呢?我們需要告訴程式”怎麼樣是比較小的”。語法稍微有點複雜,也不常用到。

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
#include<bits/stdc++.h>
using namespace std;

struct my_struct{
int x;
double y;
string s;
bool operator <(my_struct b){
return x < b.x; // 定義小於為 x 較另一個人的 x 小
}
};//要有分號

int main(){
my_struct a;
a.x = 45;
a.y = 55.232;
a.s = "This is a string";

my_struct b{221,1.23,"Another way of declaration."}; // 另一種宣告方法

if(a < b){
cout << "A is smaller than B\n";
}
else{
cout << "A is not smaller than B\n";
}
}

輸出:

1
A is smaller than B

自定義加減

當然,我也可以重定義加減。

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
#include<bits/stdc++.h>
using namespace std;

struct my_struct{
int x;
double y;
string s;
bool operator <(my_struct b){
return x < b.x; // 定義小於為 x 較另一個人的 x 小
}
my_struct operator +(my_struct b){
return {x+b.x, y+b.y, s+b.s};
}
};//要有分號

int main(){
my_struct a;
a.x = 45;
a.y = 55.232;
a.s = "This is a string";

my_struct b{221,1.23,"Another way of declaration."}; // 另一種宣告方法

a = a + b; // 不可寫 a += b 因為你只定義 + 沒有定義 +=
cout<<a.x<<" "<<a.y<<" "<<a.s<<'\n';
}

輸出:

1
2
3
266
56.462
This is a string, Another way of declaration.

建構子

告訴程式在指定其中幾個值的情況下,struct 中的每個變數是多少,語法有點像函式:my_struct(……){}。

提醒一下,若未自己寫建構子,系統會預設每一個值都是該型態放在全域變數的預設值,例如 int 是 0,string 是 “” 等等。

但若自己寫了任何一個,則不會預設,也就是說,如果你寫了一個需要傳入預設值的建構子,之後在沒有值的情況下單獨宣告:my_struct a,這時,a 裡面所有變數的值將會是未知數,而這是很恐怖的。因此,如果要寫建構子,記得一定要多寫在不傳入任何參數下的預設。

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
#include<bits/stdc++.h>
using namespace std;

struct my_struct{
int x;
double y;
string s;
my_struct(){ // 多寫的預設建構子
x = 45;
y = 1.23;
s = "sdaf";
}
my_struct(int a,double b,string c){
x = a;
y = b;
c = "safasf";
}
};//要有分號

int main(){
my_struct a;
my_struct b(45,45.45455,"sdfsd");
cout<<a.x<<" \n"<<a.y<<" \n"<<a.s<<'\n';
cout<<b.x<<" \n"<<b.y<<" \n"<<b.s<<'\n';
}

輸出:

1
2
45 1.23 sdaf
12 1.2536 sdfsd

struct 的使用時機

其實大概可以感覺的出來,struct不會太常用到。但有時,總是會遇到一些時候,我們需要同時儲存超過一個變數,例如:要儲存三維空間中的點(x,y,z),我們可以這樣寫:

1
2
3
struct Point{
int x, y, z;
};

這樣的話,我就成功將三個整數包在一起,代表空間中的一個點了!

練習

老樣子,因為很多使用struct的時機是在排序時,因此併入下一章節。