文章目錄
- 1 結構體的基本概念
- 2 結構體定義和使用
- 2.1 定義結構體
- 2.2 創建結構體變數
- 3 結構體陣列
- 4 結構體指標
- 5 結構體嵌套結構體
- 6 結構體作為函式引數
- 7 結構體中const的使用場景
- 8 結構體案例練習
1 結構體的基本概念
結構體是用戶自定義的資料型別(內置資料型別的集合),可存盤不同的資料型別,
2 結構體定義和使用
2.1 定義結構體
語法:struct 結構體名 { 結構體成員串列 };
例:struct Person { string name, int age};
2.2 創建結構體變數
創建結構體變數的3種方式:
(1)struct 結構體名 結構體變數名;
先創建結構體變數,再對結構體成員進行賦值(使用.訪問結構體變數的屬性,即結構體成員),
例:
struct Person p;
p.name = "Tom";
p.age = 16;
(2)struct 結構體名 結構體變數名 = { 成員1初始值 , 成員2初始值...};
創建結構體變數時進行初始化,
例:
struct Person p = {"Tom", 16};
(3)定義結構體時即創建變數,
struct Person {
string name,
int age
} person;
注1:C++中,定義結構體時,struct關鍵字不可省略;創建結構體變數時,struct關鍵字可省略,
注2:結構體變數使用運算子.訪問結構體成員/屬性,即結構體變數x.成員a,
示例:
//結構體定義
/* 定義結構體時,struct關鍵字不可省略 */
struct Person {
string name;
int age;
} p1; //結構體變數創建方式1
int main() {
/* 創建結構體變數時,struct關鍵字可省略 */
//結構體變數創建方式2
struct Person p2;
p2.name = "Tom";
p2.age = 16;
//結構體變數創建方式3
struct Person p3 = {"Jerry", 18};
cout << p2.name << "\t" << p2.age << endl;
cout << p3.name << "\t" << p3.age << endl;
return 0;
}
3 結構體陣列
作用:將自定義的結構體變數存盤至陣列中,即結構體變數的陣列,方便進行維護,
語法:struct 結構體名 陣列名[元素個數] = { {...} , {...} , ... , {...} }
注1:對比基本資料型別的變數和陣列:
基本資料型別變數:int var;
基本資料型別陣列:int var[5];
結構體變數:struct Person person;
結構體陣列:struct Person persons[5];
注2:定義結構體陣列時,struct關鍵字可省略,
示例:
#include <iostream>
using namespace std;
#include <string>
/* 結構體定義 */
struct Person {
string name;
int age;
};
int main() {
/* 創建結構體陣列 */
//1.定義時結構體陣列時初始化(可省略struct關鍵字)
Person persons[3] = { {"Tom", 12}, {"Jerry" , 13} };
//2.修改結構體陣列元素
persons[2].name = "Lucy";
persons[2].age = 16;
/* 遍歷結構體陣列 */
for (int i = 0; i < sizeof(persons) / sizeof(persons[0]); i++) {
cout << "姓名:" << persons[i].name << ",年齡:" << persons[i].age << endl;
}
return 0;
}
4 結構體指標
作用:利用結構體指標訪問或操作結構體成員,
注1:對比基本資料型別的指標:
基本資料型別指標:int *p = &var;
結構體指標:struct Person *p = &person;//結構體指標型別需與結構體型別相匹配
注2:結構體指標使用運算子
->訪問結構體成員/屬性,即結構體指標p -> 成員a,
注3:定義結構體指標時,struct關鍵字可省略,
示例:
#include <iostream>
using namespace std;
#include <string>
/* 結構體定義 */
struct Person {
string name;
int age;
};
int main() {
//1.創建結構體變數
Person person = {"Tom", 12};
//2.創建指向結構體變數的結構體指標(struct關鍵字可省略)
Person *p = &person;
//使用結構體變數訪問成員
cout << "姓名:" << person.name << ",年齡:" << person.age<< endl;
//使用結構體指標訪問成員
cout << "姓名:" << p->name << ",年齡:" << p->age << endl;
return 0;
}
5 結構體嵌套結構體
作用: 結構體中可定義其它結構體作為成員,用于解決實際問題,
注:作為結構體成員(被包含)的結構體需預先定義,否則編譯器報錯:結構體A使用未定義的struct “B”,
示例:每門課程對應一個老師,課程的結構體成員記錄老師結構體,
#include <iostream>
using namespace std;
#include <string>
/* teacher型別結構體需先于course型別結構體前被定義,否則編譯器報錯:"course::t"使用未定義的struct "teacher" */
struct teacher {
string name;
int age;
};
struct course {
string courseName;
struct teacher t;
};
int main() {
course c;
c.courseName = "C++";
c.t.name = "老王";
c.t.age = 16;
cout << "課程名:" << c.courseName << ",授課老師:" << c.t.name << ",年齡:" << c.t.age << endl;
return 0;
}
6 結構體作為函式引數
作用:將結構體作為函式的引數進行傳遞,
傳遞方式有2種:
(1)值傳遞:函式引數使用結構體變數接收值(結構體變數),
(2)地址傳遞:函式引數使用結構體指標接收地址(結構體變數的地址),
注1:若不希望修改實參,則使用值傳遞(函式形參使用
結構體型別接收結構體變數的實參),形參的改變不影響實參,
注2:若希望修改實參,則使用地址傳遞(函式形參使用結構體指標接收結構體變數地址的實參),形參的改變會影響實參,
示例:
#include <iostream>
#include <string>
using namespace std;
struct Person {
string name;
int age;
};
/* 值傳遞:形參的改變不影響實參 */
void func_value(struct Person person) {
person.name = "Jerry";
person.age = 15;
cout << "結構體變數作為函式引數傳遞:" << person.name << "\t" << person.age << endl;
}
/* 地址傳遞:形參的改變影響實參 */
void func_address(struct Person *p) {
p->name = "Lucy";
p->age = 20;
cout << "結構體指標作為函式引數傳遞:" << p->name << "\t" << p->age << endl;
}
int main(){
struct Person person = { "Tom", 10 };
/* 結構體變數作為函式引數傳遞 */
func_value(person); //Jerry 15
cout << "main函式中的結果:" << person.name << "\t" << person.age << endl; //Tom 10
/* 結構體指標作為函式引數傳遞 */
func_address(&person); //Lucy 20
cout << "main函式中的結果:" << person.name << "\t" << person.age << endl; //Lucy 20
return 0;
}
7 結構體中const的使用場景
作用:使用const可避免資料被修改的誤操作(不可寫),
場景:值傳遞程序有更大的記憶體開銷,會拷貝新的副本(結構體成員越多,記憶體占用越大),地址傳遞程序(形參改為指標)可減少記憶體空間占用,不會拷貝新的副本且指標型別僅占用4位元組;為避免資料被修改等誤操作,可使用const關鍵字將函式形參的指標限定為常量指標,無法進行解參考賦值操作(限定為只讀不可寫狀態),
注1:對函式引數的結構體指標使用const關鍵字修飾后,無法通過結構體指標使用運算子
->修改結構體成員的值(可讀不可寫),否則編譯器報錯:運算式必須是可修改的左值,
注2:const關鍵字的作用:限定為只讀狀態,防止修改操作(不可寫),
示例:
struct Person {
string name;
int age;
};
/* 傳遞地址值:形參的改變影響實參 */
void func_address(const struct Person* p) {
//使用const關鍵字修飾結構體指標后,不能通過結構體指標修改結構體成員的值
//p->age = 20;
cout << "結構體指標作為函式引數傳遞:" << p->name << "\t" << p->age << endl;
}
int main() {
struct Person person = { "Tom", 10 };
/* 結構體指標作為函式引數傳遞 */
func_address(&person); //Tom 10
cout << "main函式中的結果:" << person.name << "\t" << person.age << endl; //Tom 10
return 0;
}
8 結構體案例練習
練習:設計學生結構體,包含姓名與成績,創建結構體陣列存盤若干名學生;使用冒泡排序實作結構體陣列中學生成績的降序排序,
#include <iostream>
#include <string>
using namespace std;
struct Student {
string name;
int score;
};
/* 冒泡排序 */
void bubbleSort(struct Student students[], int length) {
for (int i = 0; i < length - 1; i++) {
for (int j = 0; j < length - i - 1; j++) {
if(students[j].score < students[j + 1].score){ //降序排序
struct Student temp = students[j];
students[j] = students[j + 1];
students[j + 1] = temp;
}
}
}
}
int main() {
//創建學生結構體陣列
struct Student stus[3] = {
{"張三" , 89},
{"李四" , 68},
{"王五" , 95}
};
int len = sizeof(stus) / sizeof(stus[0]);
//冒泡排序:實作成績降序排序
bubbleSort(stus, len);
for (int i = 0; i < len; i++) {
cout << "姓名:" << stus[i].name << ",成績:" << stus[i].score << endl;
}
return 0;
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/246617.html
標籤:其他
