結構體是自訂資料型別,可包含不同型別成員,支援整體指派(陣列不支援)。定義本身不佔記憶體,宣告變數時才配置空間。
struct test { int a; int b; };
int main() {
test pn1, pn2;
pn2.a = 10; pn2.b = 3;
pn1 = pn2; // 整體複製
test* ptr = &pn2;
ptr->a = 99; // 指標存取成員用 ->
}
| 方式 | 語法 | 效能 | 適用場景 |
|---|---|---|---|
| 值傳遞 | void f(test p) | 複製整個結構,堆疊開銷大 | 極小型結構 |
| 指標傳遞 | void f(test* p) | 僅傳遞位址,無複製 | 大型結構、需修改原物件 |
| 參考傳遞 | void f(test& p) | 同指標效能,語法如值傳遞 | 大型結構、需修改原物件(推薦) |
struct test { char name[10]; float score; };
void print_score(test& p) { cout << p.name << "|" << p.score << endl; }
int main() {
test a[2] = {{"marry",88.5},{"jarck",98.5}};
for (int i=0;i<2;i++) print_score(a[i]); // 參考傳遞
}
test get_score() {
test pn; cin >> pn.name >> pn.score;
return pn; // 產生暫時物件 temp,再複製給呼叫端
}
int main() {
test a[2];
for (int i=0;i<2;i++) a[i] = get_score(); // 兩次複製
}
void get_score(test& pn) { cin >> pn.name >> pn.score; } // 直接操作原物件
int main() {
test a[2];
for (int i=0;i<2;i++) get_score(a[i]); // 零複製
}
差異分析: 範例 1 在函式內建立區域物件、傳回時產生暫時物件、指派時再複製;範例 2 直接對呼叫端物件操作,無額外記憶體配置與複製。
test a; // 全域物件
test& get_score(test& pn) { cin >> pn.name >> pn.score; return pn; }
int main() {
test& sp = get_score(a); // 直接綁定全域物件 a
cout << sp.name << "|" << sp.score;
}
int*& ref = ptr; 為指標的別名,可修改指標指向:
int a=0, b=10;
int *p1=&a, *p2=&b;
int*& rp = p1;
rp = p2; // p1 現在指向 b
const T& 唯讀,T& 可修改)。std::move (C++11) 或輸出參數模式。const 修飾唯讀參考,編譯器可進一步優化。