結構體
假設要存儲有關籃球運動員的信息,則可能需要存儲他(她)的姓名、工資、身高、體重、平均得分、命中率、助攻次數等。希望有一種數據格式可以將所有這些信息存儲在一個單元中。數組不能完成這項任務,因爲雖然數組可以存儲多個元素,但所有元素的類型必須相同。也就是說,一個數組可以存儲20個int,另一個數組可以存儲10個float,但同l一l個數組不能在一些元素中存儲int,在另一些元素中存儲float。
C++中的結構的可以滿足要求(存儲籃球運動員的信息)。結構是一種比數組更靈活的數據格式,因爲同一個結構可以存儲多種類型的數據,這使得能夠將有關籃球運動員的信息放在一個結構中,從而將數據的表示合併到一起。如果要跟蹤整個球隊,則可以使用結構數組。結構也是C++ OOP堡壘(類)的基石學習有關結構的知識將使我們離C++的核心OOP更近。
結構是用戶定義的類型,而結構聲明定義了這種類型的數據屬性。定義了類型後,便可以創建這種類型的變量。因此創建結構包括兩步。首先,定義結構描述——它描述並標記了能夠存儲在結構中的各種數據類型。然後按描述創建結構變量(結構數據對象)。結構定義的示例如下:
struct inflatable //structure declaration
{
char name[20];
float volume;
double price;
}
關鍵字struct表明,這些代碼定義的十一結構的佈局。標識符inflatables是這種數據格式的名稱,因此新類型的名稱爲inflatable,這樣便可以像創建char,int類型的變量創建inflatable類型的變量了。接下來的大括號包含了的是結構存儲的數據類型的列表,其中每個列表項都是一條聲明語句。這個例子使用了一個適合用於存儲字符串的char數組、一個float和一個 double。列表中的每一項都被稱爲結構成員,因此 inflatable結構有3個成員(參見圖4.6)。總之,結構定義指出了新類型(這裏是 inflatable)的特徵。
定義結構後,便可以創建這種類型的變量了:
inflatable hat; //hat是inflatable類型的結構
inflatable woopie_cushion; //inflatable類型
如果你熟悉C語言的結構,則可能已經注意到,C++允許聲明結構變量時省略關鍵字struct
struct inflatable goose; //C語言中不能省略struct關鍵字
inflatable vincent; //C++中可省略struct關鍵字
在C++中,結構標記的用法與基本類型名相同。這種變化強調的是,結構聲明定義了一種新類型。在C++中,省略 struct不會出錯。由於hat的類型爲 inflatable,因此可以使用成員運算符(.)來訪問各個成員。例如, hat.volume指是結構的 volume成員, hat. price指的是 price成員。同樣, vincent.price是 vincent結構的 price成員。總之,通過成員名能夠訪問結構的成員,就像通過索引能夠訪問數組的元素一樣。由於price成員被聲明爲 double類型,因此 hat. price和 vincent.price相當於是 double類型的變量,可以像使用常規 double變量那樣來使用它們。總之,hat是一個結構,而 hat.price是一個doub變量順便說一句,訪問類成員函數(如 cin.getline())的方式是從訪問結構成員變量(如 vincent.price)的方式衍生而來的。
-
結構程序案例structur.cpp
#include <iostream> struct inflatable { char name[20]; float volume; double price; } int main() { using namespace std; inflatable guest = { "Glorious Gloria", 1.88, 29.99 }; //guest被初始化爲inflatable類型的結構,結構體成員被初始化爲相應的值。 inflatabel pal = { "Audacious Arthur", 3.12, 32.99 }; cout << "Expand your guest list with "<< guest.name; cout<< " and "<< pal.name << "!\n"; cout<< "You can have both for $"; cout<< guest.price + pal.price << "!\n"; return 0; } //程序輸出 Expand your guest list with Glorious Gloria and Audacious Arthur! You can have both for $62.98!
結構聲明的位置很重要。對於 structur. cpp而言,有兩種選擇。可以將聲明放在main()函數中,緊跟在開始括號的後面。另一種選擇是將聲明放到main())的前面,這裏採用的便是這種方式,位於函數外面的聲明被稱爲外部聲明。對於這個程序來說,兩種選擇之間沒有實際區別。但是對於那些包含兩個或更多函數的程序來說,差別很大。外部聲明可以被其後面的任何函數使用,而內部聲明只能被該聲明所屬的函數使用。通常應使用外部聲明,這樣所有函數都可以使用這種類型的結構(參見圖4.7)。
接下來,請注意初始化方式:
inflatable guest =
{
"Glorious Gloria", //name初始值
1.88, //volume初始值
29.99 //price初始值
}
和數組一樣,使用由逗號(,)分隔值列表,並將這些值用花括號括起來。
可將每個結構成員看作是相應類型的變量。因此, pal price是一個 double變量,而 pal.name是一個char數組。當程序使用cout顯示 pal.name時,將把該成員顯示爲字符串。另外,由於 pal.name是一個字符數組,因此可以用下標來訪問其中的各個字符。例如, pal .name[0]是字符A.不過pal[0]沒有意義,因爲pal是一個結構,而不是數組。
C++11結構初始化
與數組一樣,C++11也支持將列表初始化用於結構,且等號(=)是可選的。
inflatable duck {"Daphne",0.12,9.98}; //可以省略“=”
其次,如果大括號內未包含任何東西,各個成員都將被設置爲零。例如,下面的聲明導致 mayor.volar和 mayor.price被設置爲零,且 mayor.name的每個字節都被設置爲零:
inflatable mayor {};
1.1使用 string類作爲成員
struct inflatable
{
std:: string name;
float volume;
double price;
}
一定要讓結構定義能夠訪問名稱空間std.爲此,可以將編譯指令 using移到結構定義之前:也可以像前面那樣,將name的類型聲明爲std::string
1.2結構其他屬性
C++使用戶定義的類型與內置類型儘可能相似。例如,可以將結構作爲參數傳遞給函數,也可以讓函數返回一個結構。另外,還可以使用賦值運算符(=)將結構賦給另一個同類型的結構,這樣結構中每個成員都將被設置爲另一個結構中相應成員的值,即使成員是數組。這種賦值被稱爲成員賦值(memberwise assignment)。
-
結構賦值案例 assgn_st.cpp
#include <iostream> struct inflatable { char name[20]; float volume; double price; } int main() { using namespace std; inflatable bouquet = { "sunflowers", 0.20, 12.49 }; inflatable choice; cout << "bouquet: " << bouquet.name << " for $"; cout << bouquet.price << endl; choice = bouquet; cout << "choice: " << choice.name << " for $"; cout << choice.price << endl; return 0; } //程序輸出 bouquet: sunflowers for $12.49 choice: sunflowrs for $12.49
可以同時完成定義結構和創建結構變量的工作。爲此,只需將變量名放在結束括號的後面即可
struct perks
{
int key_number;
char car[12];
} mr_smith, ms_jones; //兩個perks變量
甚至可以以這種方式初始化創建的變量:
struct perks
{
int key_number;
char car[12];
} mr_glitz =
{
7,
"Packard"
};
然而,將結構定義和變量聲明分開,可以使程序更易於閱讀和理解。還可以聲明沒有名稱的結構類型,方法是省略名稱,同時定義一種結構類型和一個這種類型的變量:
struct
{
int x;
int y;
} position;
這樣將創建一個名爲position的結構變量。可以使用成員運算符來訪問它的成員(position.x),但這種類型沒有名稱,因此以後無法創建這種類型的變量,因此不建議這樣使用。
1.3結構數組
inflatable結構包含一個數組(name)。也可以創建元素爲結構的數組,方法和創建基本類型數組完全相同。例如,要創建一個包含100個 inflatable結構的數組,可以這樣做:
inflatable gifts[100]; //包含100個infatable結構的數組
這樣, gifts將是一個 inflatable數組,其中的每個元素(如 gifts[0]或gifts[99])都是 inflatable對象,可以與成員運算符一起使用:
cin >> gifts[0].volume;
cout << gifts[99].price << endl;
記住, gifts本身是一個數組,而不是結構,因此像 gifts.price這樣的表述是無效的。
要初始化結構數組,可以結合使用初始化數組的規則(用逗號分隔每個元素的值,並將這些值用花括號括起)和初始化結構的規則(用逗號分隔每個成員的值,並將這些值用花括號括起)。由於數組中的每個元素都是結構,因此可以使用結構初始化的方式來提供它的值。因此,最終結果爲一個被括在花括號中、用逗號分隔的值列表,其中每個值本身又是一個被括在花括號中、用逗號分隔的值列表:
inflatable guests[2]
{
{"Bambi",0.5,21.99}, //guset數組中第一個結構
{"Godzilla",2000,565.99} //guest數組中第二個結構
};
1.4結構體指針
結構體指針是指向結構體的指針,如int* ps
表示指向int型的指針,結構體指針的定義和訪問結構體成員方式如下:
struct Phone
{
int data;
int price;
};
struct iphone *ps;
ps->data = 2019;
ps->price = 8888;
注意指針的訪問方式和其他結構體的訪問是不同的。
結構體爲參數
1.傳結構體
//
#include <iostream>
using namespace std;
struct{
const char *name;
const char *sex;
int age;
} student;
void changeMessage(student t)
{
t.age += 1;
cout << "The age is : " << t.age << endl;
}
int main()
{
student stu = {"xiaobei", "man", 99};
changeMessage(stu);
cout << "The age is : " << stu.age);
return 0;
}
打印結果爲:
The age is : 100
The age is : 99
2.傳結構體指針
//
#include <iostream>
using namespace std;
struct {
const char *name;
const char *sex;
int age;
} student;
void changeMessage(student *t)
{
t->age += 1;
cout << "The age is : " << t->age << endl;
}
int main()
{
student stu = {"xiaobei", "man", 99};
changeMessage(&stu);
cout << "The age is : " << stu.age << endl;
return 0;
}
打印結果爲:
The age is : 100
The age is : 100