【C++ 筆記】運算子多載(Operator Overloading)範例

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

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

2x2 矩陣

以下範例多載了這些運算子:

運算子型態說明
[]成員存取矩陣元素,如 A[0][1]
-(一元)成員取負矩陣
+, -, *成員矩陣加減乘
+=, -=, *=成員複合指派
==, !=成員相等比較
*(純量)friendscalar * matrixmatrix * scalar
<<, >>friend標準輸出入串流
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
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
#include <iostream>
#include <stdexcept>

class Matrix2x2 {
private:
double data[2][2];

public:
// 建構子 Constructor
Matrix2x2() {
data[0][0] = data[0][1] = data[1][0] = data[1][1] = 0.0;
}

Matrix2x2(double a, double b, double c, double d) {
data[0][0] = a; data[0][1] = b;
data[1][0] = c; data[1][1] = d;
}

// C++ 11 : "= default" Syntax
Matrix2x2(const Matrix2x2&) = default; // Copy Constructor
Matrix2x2& operator=(const Matrix2x2&) = default; // Copy Assignment Operator
~Matrix2x2() = default; // 解構子 Destructor

double* operator[](int row) { // 回傳可修改的指標
if (row < 0 || row > 1)
throw std::out_of_range("Row index out of range");
return data[row];
}

const double* operator[](int row) const { // 回傳唯讀的指標
if (row < 0 || row > 1)
throw std::out_of_range("Row index out of range");
return data[row];
}

// 一元負號
Matrix2x2 operator-() const {
return Matrix2x2(-data[0][0], -data[0][1],
-data[1][0], -data[1][1]);
}

// 二元算術運算子 + -
Matrix2x2 operator+(const Matrix2x2& rhs) const {
return Matrix2x2(
data[0][0] + rhs.data[0][0], data[0][1] + rhs.data[0][1],
data[1][0] + rhs.data[1][0], data[1][1] + rhs.data[1][1]
);
}

Matrix2x2 operator-(const Matrix2x2& rhs) const {
return Matrix2x2(
data[0][0] - rhs.data[0][0], data[0][1] - rhs.data[0][1],
data[1][0] - rhs.data[1][0], data[1][1] - rhs.data[1][1]
);
}

// 矩陣乘法
Matrix2x2 operator*(const Matrix2x2& rhs) const {
return Matrix2x2(
data[0][0]*rhs.data[0][0] + data[0][1]*rhs.data[1][0],
data[0][0]*rhs.data[0][1] + data[0][1]*rhs.data[1][1],
data[1][0]*rhs.data[0][0] + data[1][1]*rhs.data[1][0],
data[1][0]*rhs.data[0][1] + data[1][1]*rhs.data[1][1]
);
}

// 複合指派運算子
// 直接複用已多載的 + - * 實作,避免重複邏輯
Matrix2x2& operator+=(const Matrix2x2& rhs) { *this = *this + rhs; return *this; }
Matrix2x2& operator-=(const Matrix2x2& rhs) { *this = *this - rhs; return *this; }
Matrix2x2& operator*=(const Matrix2x2& rhs) { *this = *this * rhs; return *this; }

// 比較運算子 ==
bool operator==(const Matrix2x2& rhs) const {
for (int i = 0; i < 2; ++i)
for (int j = 0; j < 2; ++j)
if (data[i][j] != rhs.data[i][j]) return false;
return true;
}

// != 直接複用 == 的結果
bool operator!=(const Matrix2x2& rhs) const { return !(*this == rhs); }

// 行列式
double det() const {
return data[0][0] * data[1][1] - data[0][1] * data[1][0];
}

// friend : 讓非成員函式存取 private data
friend Matrix2x2 operator*(double scalar, const Matrix2x2& m);
friend Matrix2x2 operator*(const Matrix2x2& m, double scalar);
friend std::ostream& operator<<(std::ostream& os, const Matrix2x2& m);
friend std::istream& operator>>(std::istream& is, Matrix2x2& m);
};

// 純量乘法
// 支援 3.0 * A (純量在左) 與 A * 3.0 (純量在右) 兩種寫法
Matrix2x2 operator*(double s, const Matrix2x2& m) {
return Matrix2x2(s*m.data[0][0], s*m.data[0][1],
s*m.data[1][0], s*m.data[1][1]);
}

Matrix2x2 operator*(const Matrix2x2& m, double s) {
return s * m; // 直接委託給上面那個
}

// 輸出串流 <<
std::ostream& operator<<(std::ostream& os, const Matrix2x2& m) {
os << "| " << m.data[0][0] << "\t" << m.data[0][1] << " |\n";
os << "| " << m.data[1][0] << "\t" << m.data[1][1] << " |";
return os;
}

// 輸入串流 >>
std::istream& operator>>(std::istream& is, Matrix2x2& m) {
is >> m.data[0][0] >> m.data[0][1]
>> m.data[1][0] >> m.data[1][1];
return is;
}

int main() {
Matrix2x2 A(1, 2, 3, 4);
Matrix2x2 B(5, 6, 7, 8);

std::cout << "A =\n" << A << "\n\n";
std::cout << "B =\n" << B << "\n\n";

std::cout << "A + B =\n" << (A + B) << "\n\n";
std::cout << "A - B =\n" << (A - B) << "\n\n";
std::cout << "A * B =\n" << (A * B) << "\n\n";
std::cout << "-A =\n" << (-A) << "\n\n";

std::cout << "3.0 * A =\n" << (3.0 * A) << "\n\n";
std::cout << "A * 2.0 =\n" << (A * 2.0) << "\n\n";

std::cout << "A == B : " << std::boolalpha << (A == B) << "\n";
std::cout << "A != B : " << (A != B) << "\n\n";

std::cout << "A[0][1] = " << A[0][1] << "\n\n"; // 存取第 0 列第 1 行

A += B;
std::cout << "After A += B:\n" << A << "\n\n";

std::cout << "det(B) = " << B.det() << "\n"; // 5*8 - 6*7 = -2

return 0;
}

程式碼解釋:

首先是 = default 這個語法,這個語法是 C++ 11 引入的新特性,稱為明確預設函式定義(Explicitly-defaulted function definition)。

當定義了任何建構子時,編譯器就不會再自動生成預設建構子(無參數建構子),但如果我們還需要預設建構子,可用 = default 來強制編譯器生成,不必手動撰寫空的函數體 {}

接著第 24-34 行的程式碼:

1
2
3
4
5
6
7
8
9
10
11
double* operator[](int row) { // 回傳可修改的指標
if (row < 0 || row > 1)
throw std::out_of_range("Row index out of range");
return data[row];
}

const double* operator[](int row) const { // 回傳唯讀的指標
if (row < 0 || row > 1)
throw std::out_of_range("Row index out of range");
return data[row];
}

這邊寫的 const 只是專門給 const 用的,方便存取輸出,就這樣。

最後的 *this 指標:

1
2
3
Matrix2x2& operator+=(const Matrix2x2& rhs) { *this = *this + rhs; return *this; }
Matrix2x2& operator-=(const Matrix2x2& rhs) { *this = *this - rhs; return *this; }
Matrix2x2& operator*=(const Matrix2x2& rhs) { *this = *this * rhs; return *this; }

this 是 C++ 每個非靜態成員函式都隱藏擁有的一個指標,指向呼叫這個函式的那個物件自己

例如 A += BA 就會是呼叫 operator+= 的那個人,即 this,而 rhs 就是 B

return *this 回傳的是參考(reference)而非複製,讓多載 += 等運算子效率更高,也支援 (A += B) += C 的連鎖(chain)寫法 。

然後這邊也複用了在先前已經事先多載好的運算子 +, -, *,直接用即可。

多項式運算

以下範例多載了這些運算子:

運算子說明
[]讀寫第 i 項係數
()代入 x 值計算 P(x),使物件像函式一樣呼叫
+, -, *多項式加減乘
+=, -=複合指派
前綴 ++ / --所有係數 +1 / -1
後綴 ++ / --同上,但回傳舊值
<<美化輸出,如 2x^2 + x - 3
==, !=相等比較
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
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
#include <iostream>
#include <vector>
#include <cmath> // std::pow
#include <stdexcept>
#include <algorithm> // std::max
#include <initializer_list>

class Polynomial {
private:
std::vector<double> coeffs; // coeffs[i] = x^i 的係數

// 去除尾端多餘的 0 (避免 "0x^3 + 2x" 這種情況)
void trim() {
while (coeffs.size() > 1 && coeffs.back() == 0.0)
coeffs.pop_back();
}

public:
// 建構子
// 預設常數 0
Polynomial() : coeffs(1, 0.0) {}

// 單一常數,例如 Polynomial(5) 代表 P(x) = 5
explicit Polynomial(double c) : coeffs(1, c) {}

// C++11 initializer_list,例如 Polynomial({-3, 1, 2}) 代表 2x^2 + x - 3
Polynomial(std::initializer_list<double> list) : coeffs(list) {
if (coeffs.empty()) coeffs.push_back(0.0);
trim();
}

Polynomial(const Polynomial&) = default;
Polynomial& operator=(const Polynomial&) = default;
~Polynomial() = default;

int degree() const { return static_cast<int>(coeffs.size()) - 1; }

double& operator[](int i) {
if (i < 0) throw std::out_of_range("Index must be >= 0");
if (i >= static_cast<int>(coeffs.size()))
coeffs.resize(i + 1, 0.0); // 自動擴展補 0
return coeffs[i];
}

double operator[](int i) const {
if (i < 0 || i >= static_cast<int>(coeffs.size())) return 0.0;
return coeffs[i];
}

// operator()
// 讓 Polynomial 物件像函式一樣呼叫:P(3.0) 計算 P(x=3)
// 另外這邊用了秦九韶算法,讓傳統方法 O(n^2) -> O(n)
double operator()(double x) const {
double result = 0.0;
for (int i = degree(); i >= 0; --i)
result = result * x + coeffs[i];
return result;
}

// 一元負號
Polynomial operator-() const {
Polynomial neg(*this);
for (auto& c : neg.coeffs) c = -c;
return neg;
}

// 二元算術運算子
Polynomial operator+(const Polynomial& rhs) const {
int len = std::max(coeffs.size(), rhs.coeffs.size());
Polynomial result;
result.coeffs.resize(len, 0.0);
for (int i = 0; i < len; ++i)
result.coeffs[i] = (*this)[i] + rhs[i];
result.trim();
return result;
}

Polynomial operator-(const Polynomial& rhs) const {
return *this + (-rhs); // 複用已有的 + 與 一元-
}

// 多項式乘法:(a0+a1x+...)(b0+b1x+...) 的 x^k 項 = sum(ai*bj, i+j=k)
Polynomial operator*(const Polynomial& rhs) const {
int n = degree() + rhs.degree() + 1;
Polynomial result;
result.coeffs.resize(n, 0.0);
for (int i = 0; i <= degree(); ++i)
for (int j = 0; j <= rhs.degree(); ++j)
result.coeffs[i + j] += coeffs[i] * rhs.coeffs[j];
result.trim();
return result;
}

// 複合指派
Polynomial& operator+=(const Polynomial& rhs) { *this = *this + rhs; return *this; }
Polynomial& operator-=(const Polynomial& rhs) { *this = *this - rhs; return *this; }
Polynomial& operator*=(const Polynomial& rhs) { *this = *this * rhs; return *this; }

// 前綴 ++ / --
// 語意: 所有係數 +1(先改再回傳自己)
Polynomial& operator++() {
for (auto& c : coeffs) ++c;
return *this;
}
Polynomial& operator--() {
for (auto& c : coeffs) --c;
trim();
return *this;
}

// 後綴 ++ / -- (int 參數是假的,只是用來區分前後綴)
// 語意: 先記錄舊值,再改,回傳舊值 (注意回傳的是值,不是參考)
Polynomial operator++(int) {
Polynomial old(*this);
++(*this); // 呼叫前綴版本
return old;
}
Polynomial operator--(int) {
Polynomial old(*this);
--(*this);
return old;
}

// 比較運算子
bool operator==(const Polynomial& rhs) const {
return coeffs == rhs.coeffs;
}
bool operator!=(const Polynomial& rhs) const { return !(*this == rhs); }

friend std::ostream& operator<<(std::ostream& os, const Polynomial& p);
};

// 美化輸出: 從最高次往下印
std::ostream& operator<<(std::ostream& os, const Polynomial& p) {
bool first = true;
for (int i = p.degree(); i >= 0; --i) {
double c = p.coeffs[i];
if (c == 0.0) continue;

if (!first) os << (c > 0 ? " + " : " - ");
else if (c < 0) os << "-";

double abs_c = std::abs(c);
if (abs_c != 1.0 || i == 0) os << abs_c;

if (i == 1) os << "x";
else if (i > 1) os << "x^" << i;

first = false;
}
if (first) os << "0"; // 零多項式
return os;
}

int main() {
// P = 2x^2 + x - 3, Q = x^3 - x + 5
Polynomial P = {-3, 1, 2};
Polynomial Q = {5, -1, 0, 1};

std::cout << "P = " << P << "\n";
std::cout << "Q = " << Q << "\n\n";

std::cout << "P + Q = " << (P + Q) << "\n";
std::cout << "P - Q = " << (P - Q) << "\n";
std::cout << "P * Q = " << (P * Q) << "\n";
std::cout << "-P = " << (-P) << "\n\n";

// operator(): 代入數值
std::cout << "P(2) = " << P(2.0) << "\n"; // 2(4)+2-3 = 7
std::cout << "Q(-1) = " << Q(-1.0) << "\n\n"; // -1+1+5 = 5

// operator[]: 修改單一係數
P[0] = 10; // 把常數項從 -3 改成 10
std::cout << "After P[0]=10, P = " << P << "\n\n";

// 前綴 ++
Polynomial A = {1, 2, 3}; // 3x^2 + 2x + 1
std::cout << "A = " << A << "\n";
std::cout << "++A = " << ++A << "\n"; // 先改後印
std::cout << "A now = " << A << "\n\n";

// 後綴 ++
Polynomial B = {0, 1}; // x
std::cout << "B = " << B << "\n";
std::cout << "B++ = " << B++ << "\n"; // 先印舊值再改
std::cout << "B now = " << B << "\n\n";

// 複合指派
Polynomial C = {1, 1}; // x + 1
C *= C; // (x+1)^2 = x^2 + 2x + 1
std::cout << "(x+1)^2 = " << C << "\n\n";

std::cout << "P == Q : " << std::boolalpha << (P == Q) << "\n";
std::cout << "P != Q : " << (P != Q) << "\n";

return 0;
}

程式碼解釋:

explicit 關鍵字是用來禁止編譯器自動做隱式型別轉換(Implicit Conversion)的關鍵字,通常加在建構子前面。

假設我們沒寫,像是 Polynomial(double c) : coeffs(1, c) {},則:

1
2
3
4
5
void print(Polynomial p) { ... }

print(5.0);

Polynomial p = 5.0; // 初始化也會觸發隱式轉換

在呼叫 print(5.0) 時,本來應該要傳 Polynomial,但傳了 double,編譯器會自動呼叫建構子把 5.0 包成 Polynomial(5.0),這種行為可能不是我們想要的,因此可透過 explicit 強制關閉這種機制。

另外 std::initializer_list 是 C++ 11 引入的型態,代表一組同型態元素的大括號初始化清單,讓我們可以在 main() 裡面用 {1, 2, 3} 這種語法初始化物件。

當編譯器看到 {-3, 1, 2} 時,會自動把它打包成一個 initializer_list<double>,然後傳給對應的建構子:

1
2
3
4
Polynomial P = {-3, 1, 2};
// 等價於:
// initializer_list<double> tmp = {-3.0, 1.0, 2.0};
// Polynomial P(tmp);

範例程式碼中的用法:

1
2
3
4
Polynomial(std::initializer_list<double> list) : coeffs(list) {
if (coeffs.empty()) coeffs.push_back(0.0);
trim();
}

有理分數

以下範例多載了這些運算子:

運算子說明
+, -, *, /分數四則運算
+=, -=, *=, /=複合指派
一元 +, -正負號
==, !=, <, >, <=, >=六大比較
operator double()隱式轉換成 double(型別轉換運算子)
++ / --(前後綴)分子 ±1(分母不變)
<<, >>串流輸入輸出
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
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
#include <iostream>
#include <numeric>
#include <stdexcept>
#include <cmath> // std::abs

static long long gcd(long long a, long long b) {
a = std::abs(a);
b = std::abs(b);
while (b) {
a %= b;
std::swap(a, b);
}
return a;
}

class Fraction {
private:
long long num; // 分子 (numerator)
long long den; // 分母 (denominator)

// 化簡
void simplify() {
if (den == 0) throw std::invalid_argument("Denominator cannot be zero");
if (den < 0) { num = -num; den = -den; }
long long g = gcd(std::abs(num), den);
num /= g; den /= g;
}

public:
// 建構子
Fraction(long long n = 0, long long d = 1) : num(n), den(d) {
simplify();
}

Fraction(const Fraction&) = default;
Fraction& operator=(const Fraction&) = default;
~Fraction() = default;

long long numerator() const { return num; }
long long denominator() const { return den; }

// 型別轉換運算子: Fraction → double
// 讓 Fraction 可以在需要 double 的地方自動轉換
// 加 explicit 避免在不預期的場合偷偷轉換
explicit operator double() const {
return static_cast<double>(num) / static_cast<double>(den);
}

// 一元運算子
Fraction operator+() const { return *this; }
Fraction operator-() const { return Fraction(-num, den); }

// 四則運算 (通分後計算)
// a/b + c/d = (a*d + c*b) / (b*d)
Fraction operator+(const Fraction& rhs) const {
return Fraction(num * rhs.den + rhs.num * den,
den * rhs.den);
}

Fraction operator-(const Fraction& rhs) const {
return *this + (-rhs); // 複用 + 與 一元-
}

// a/b * c/d = (a*c) / (b*d)
Fraction operator*(const Fraction& rhs) const {
return Fraction(num * rhs.num, den * rhs.den);
}

// a/b ÷ c/d = (a*d) / (b*c)
Fraction operator/(const Fraction& rhs) const {
if (rhs.num == 0) throw std::domain_error("Division by zero fraction");
return Fraction(num * rhs.den, den * rhs.num);
}

// 複合指派
Fraction& operator+=(const Fraction& rhs) { *this = *this + rhs; return *this; }
Fraction& operator-=(const Fraction& rhs) { *this = *this - rhs; return *this; }
Fraction& operator*=(const Fraction& rhs) { *this = *this * rhs; return *this; }
Fraction& operator/=(const Fraction& rhs) { *this = *this / rhs; return *this; }

// 前綴 ++ / -- (分子 ± 1,分母不變)
Fraction& operator++() { num += den; simplify(); return *this; }
Fraction& operator--() { num -= den; simplify(); return *this; }

// 後綴 ++ / -- (先存舊值,再改)
Fraction operator++(int) { Fraction old(*this); ++(*this); return old; }
Fraction operator--(int) { Fraction old(*this); --(*this); return old; }

// 六大比較運算子
// 比較 a/b 與 c/d,通分後比分子即可:a*d vs c*b
bool operator==(const Fraction& rhs) const { return num == rhs.num && den == rhs.den; }
bool operator!=(const Fraction& rhs) const { return !(*this == rhs); }
bool operator< (const Fraction& rhs) const { return num * rhs.den < rhs.num * den; }
bool operator> (const Fraction& rhs) const { return rhs < *this; }
bool operator<=(const Fraction& rhs) const { return !(rhs < *this); }
bool operator>=(const Fraction& rhs) const { return !(*this < rhs); }

friend std::ostream& operator<<(std::ostream& os, const Fraction& f);
friend std::istream& operator>>(std::istream& is, Fraction& f);
};

std::ostream& operator<<(std::ostream& os, const Fraction& f) {
if (f.den == 1) os << f.num;
else os << f.num << "/" << f.den;
return os;
}

// 輸入格式為 "num/den" 或純整數
std::istream& operator>>(std::istream& is, Fraction& f) {
long long n, d = 1;
char slash;
is >> n;
if (is.peek() == '/') {
is >> slash >> d;
}
f = Fraction(n, d);
return is;
}

int main() {
Fraction a(1, 2); // 1/2
Fraction b(1, 3); // 1/3
Fraction c(-3, 6); // 自動化簡 -> -1/2

std::cout << "a = " << a << "\n";
std::cout << "b = " << b << "\n";
std::cout << "c = " << c << " (由 -3/6 自動化簡)\n\n";

std::cout << "a + b = " << (a + b) << "\n"; // 1/2 + 1/3 = 5/6
std::cout << "a - b = " << (a - b) << "\n"; // 1/2 - 1/3 = 1/6
std::cout << "a * b = " << (a * b) << "\n"; // 1/2 * 1/3 = 1/6
std::cout << "a / b = " << (a / b) << "\n\n"; // 1/2 ÷ 1/3 = 3/2

double d_a = static_cast<double>(a); // explicit 要求必須明確轉換
std::cout << "a as double = " << d_a << "\n\n";

// 六大比較
std::cout << std::boolalpha;
std::cout << "a == c : " << (a == c) << "\n"; // 1/2 == -1/2 → false
std::cout << "a > b : " << (a > b) << "\n"; // 1/2 > 1/3 → true
std::cout << "b < a : " << (b < a) << "\n"; // 1/3 < 1/2 → true
std::cout << "a >= a : " << (a >= a) << "\n\n";

// 前綴 ++:1/2 + 1 = 3/2
Fraction x(1, 2);
std::cout << "x = " << x << "\n";
std::cout << "++x = " << ++x << "\n"; // 先改後印
std::cout << "x now = " << x << "\n\n";

// 後綴 --:先印再改
Fraction y(5, 3);
std::cout << "y = " << y << "\n";
std::cout << "y-- = " << y-- << "\n"; // 先印舊值再改
std::cout << "y now = " << y << "\n\n";

// 複合指派
Fraction s(1, 4);
s += Fraction(1, 4); // 1/4 + 1/4 = 1/2
s *= Fraction(2, 1); // 1/2 * 2 = 1
std::cout << "After += 1/4 then *= 2: s = " << s << "\n\n";

// 串流輸入
Fraction input;
std::cout << "請輸入一個分數(格式:num/den 或整數):";
std::cin >> input;
std::cout << "你輸入的是:" << input
<< " = " << static_cast<double>(input) << "\n";

return 0;
}