结构体引用_C/C++结构体完全攻略
結(jié)構(gòu)體是一個由程序員定義的數(shù)據(jù)類型,可以容納許多不同的數(shù)據(jù)值。在過去,面向?qū)ο缶幊痰膽?yīng)用尚未普及之前,程序員通常使用這些從邏輯上連接在一起的數(shù)據(jù)組合到一個單元中。一旦結(jié)構(gòu)體類型被聲明并且其數(shù)據(jù)成員被標識,即可創(chuàng)建該類型的多個變量,就像可以為同一個類創(chuàng)建多個對象一樣。
雖然今天結(jié)構(gòu)體較少使用,但知道它們是什么,以及如何使用它們?nèi)匀缓苤匾?#xff0c;這并不僅僅是因為可以在較老的程序中遇到它們,還因為在某些情況下,類的實例無法使用,這時必須使用結(jié)構(gòu)體。
聲明結(jié)構(gòu)體的方式和聲明類的方式大致相同,其區(qū)別如下:
1、使用關(guān)鍵字 struct 而不是關(guān)鍵字 class。
2、盡管結(jié)構(gòu)體可以包含成員函數(shù),但它們很少這樣做。所以,通常情況下結(jié)構(gòu)體聲明只會聲明成員變量。
3、結(jié)構(gòu)體聲明通常不包括 public 或 private 的訪問修飾符。
4、類成員默認情況是私有的,而結(jié)構(gòu)體的成員則默認為 public。程序員通常希望它們保持公開,只需使用默認值即可。
以下是一個結(jié)構(gòu)體聲明的示例,該結(jié)構(gòu)體將 5 個變量綁定在一起,保存了員工的工資單數(shù)據(jù)。這個特殊結(jié)構(gòu)體的名稱是 PayRoll。請注意,它以大寫字母開頭,這和類名使用大寫字母開頭的約定一樣。另外還要注意,與類聲明一樣,在結(jié)構(gòu)體聲明的大括號后面必須有一個分號。
正如在類的對象被創(chuàng)建之前,類聲明不會被實例化一樣,結(jié)構(gòu)體聲明不會創(chuàng)建任何結(jié)構(gòu)體的實例。本示例中的結(jié)構(gòu)體聲明只是告訴編譯器PayRoll結(jié)構(gòu)體看起來的樣子。它本質(zhì)上是創(chuàng)建一個名為 PayRoll 的新數(shù)據(jù)類型。
定義 PayRoll 結(jié)構(gòu)體的變量和定義其他任何變量的方式并無二致,首先列出數(shù)據(jù)類型,然后是變量名稱。以下定義語句創(chuàng)建了 PayRoll 結(jié)構(gòu)體的 3 個變量:
PayRoll deptHead, foreman, associate;它們每一個都是 PayRoll 結(jié)構(gòu)體的實例,可以被分配和擁有自己的內(nèi)存,以保存其成員數(shù)據(jù)。請注意,盡管 3 個結(jié)構(gòu)體變量具有不同的名稱,但每個變量都包含具有相同名稱的成員,如圖 1 所示。
圖 1 每個結(jié)構(gòu)體變量都包含具有相同名稱的成員
初始化結(jié)構(gòu)體
當(dāng)定義結(jié)構(gòu)體變量時,可以通過兩種方式初始化它:使用初始化列表或構(gòu)造函數(shù)。
初始化列表
初始化結(jié)構(gòu)體變量成員的最簡單的方法是使用初始化列表。初始化列表是用于初始化一組內(nèi)存位置的值列表。列表中的項目用逗號分隔并用大括號括起來。
例如,假設(shè)已經(jīng)聲明了以下 Date 結(jié)構(gòu)體:
定義和初始化 Date 變量的方式是:先指定變量名,后接賦值運算符和初始化列表,如下所示:
Date birthday = {23, 8, 1983};該聲明定義 birthday 是一個 Date 結(jié)構(gòu)體的變量,大括號內(nèi)的值按順序分配給其成員。所以 birthday 的數(shù)據(jù)成員已初始化,如圖 2 所示。
圖 2 已經(jīng)初始化的 birthday 的數(shù)據(jù)成員
也可以僅初始化結(jié)構(gòu)體變量的部分成員。例如,如果僅知道要存儲的生日是8月23日, 但不知道年份,則可以按以下方式定義和初始化變量:
Date birthday = {23,8};這里只有 day 和 month 成員被初始化,year 成員未初始化。但是,如果某個結(jié)構(gòu)成員未被初始化,則所有跟在它后面的成員都需要保留為未初始化。使用初始化列表時,C++ 不提供跳過成員的方法。以下語句試圖跳過 month 成員的初始化。這是不合法的。
Date birthday = {23,1983}; //非法還有一點很重要,不能在結(jié)構(gòu)體聲明中初始化結(jié)構(gòu)體成員,因為結(jié)構(gòu)體聲明只是創(chuàng)建一個新的數(shù)據(jù)類型,還不存在這種類型的變量。例如,以下聲明是非法的:
//非法結(jié)構(gòu)體聲明 struct Date {int day = 23,month = 8,year = 1983; };因為結(jié)構(gòu)體聲明只聲明一個結(jié)構(gòu)體“看起來是什么樣子的”,所以不會在內(nèi)存中創(chuàng)建成員變量。只有通過定義該結(jié)構(gòu)體類型的變量來實例化結(jié)構(gòu)體,才有地方存儲初始值。
構(gòu)造函數(shù)初始化結(jié)構(gòu)體
雖然初始化列表易于使用,但它有兩個缺點:
如果有某個成員未被初始化,那么在這種情況下,跟隨在該成員后面的成員都不能初始化。
如果結(jié)構(gòu)體包括任何諸如字符串之類的對象,那么在許多編譯器上它都將無法運行。
在這些情況下,可以使用構(gòu)造函數(shù)來初始化結(jié)構(gòu)體成員變量,這和初始化類成員變量是相同的。與類構(gòu)造函數(shù)一樣,結(jié)構(gòu)體的構(gòu)造函數(shù)必須是與結(jié)構(gòu)體名稱相同的公共成員函數(shù),并且沒有返回類型。因為默認情況下,所有結(jié)構(gòu)體成員都是公開的,所以不需要使用關(guān)鍵字 public。
以下是一個名為 Employee 的結(jié)構(gòu)體的聲明語句,它包含一個具有兩參數(shù)的構(gòu)造函數(shù),以便在創(chuàng)建一個 Employee 變量而不向其傳遞任何參數(shù)時,提供默認值:
訪問結(jié)構(gòu)體成員
結(jié)構(gòu)體成員的訪問方式與類的公共成員一樣,都是使用點運算符。但是,類的數(shù)據(jù)成員通常是私有的,必須通過函數(shù)訪問。因為結(jié)構(gòu)數(shù)據(jù)成員是公共的,所以它們可以被直接訪問,并且可以像常規(guī)變量一樣使用。以下語句即可為前面創(chuàng)建的每個 PayRoll 變量的 empNumber 成員賦值:
//非法結(jié)構(gòu)體聲明 struct Date {int day = 23,month = 8,year = 1983; };以下語句將顯示 deptHead 變量所有成員的內(nèi)容:
//非法結(jié)構(gòu)體聲明 struct Date {int day = 23,month = 8,year = 1983; };下面的程序是使用 PayRoll 結(jié)構(gòu)體的完整程序。請注意,在 cin 語句、cout 語句和數(shù)學(xué)運 算中,單個結(jié)構(gòu)體成員的用法和常規(guī)變量基本上是一樣的。
//非法結(jié)構(gòu)體聲明 struct Date {int day = 23,month = 8,year = 1983; };程序輸出結(jié)果:
Enter the employee1s number:2214 Enter the employee's name: Jack Smith Hours worked this week: 40 Employee's hourly pay rate: 12.50Here is the employee1s payroll data: Name: Jack Smith Employee number: 2214 Hours worked: 40 Hourly pay rate: 12.5 Gross pay: $500.00程序中,變量 employee 被定義在第 17 行,它是 Payroll 結(jié)構(gòu)體的一個實例。此后就可以通過變量名稱和點運算符來訪問其中的 5 個數(shù)據(jù)成員。例如,在第 22 行中,以下語句將讀取變量的 empNumber 成員中的值:
cin >> employee.empNumber; //正確如果試圖通過結(jié)構(gòu)體類型的名稱來訪問該成員,那么結(jié)果將是錯誤的:
cin >> Payroll.empNumber; //錯誤結(jié)構(gòu)體嵌套
正如一個類的對象可以嵌套在另一個類中一樣,一個結(jié)構(gòu)體的實例也可以嵌套在另一個結(jié)構(gòu)體中。例如,來看以下聲明:
//非法結(jié)構(gòu)體聲明 struct Date {int day = 23,month = 8,year = 1983; };Costs 結(jié)構(gòu)體有兩個 double 類型成員,wholesale 和 retail。Item 結(jié)構(gòu)體有 3 個成員,前 2 個是 partNum 和 description,它們都是 string 對象。第 3 個是 pricing,它是一個嵌套的 Costs 結(jié)構(gòu)體。如果定義了一個名為 widge t的 Item 結(jié)構(gòu)體,則圖 3 說明了其成員。
圖 3 在 widget 的成員中包含一個嵌套結(jié)構(gòu)體
它們可以按以下方式訪問:
//非法結(jié)構(gòu)體聲明 struct Date {int day = 23,month = 8,year = 1983; };請注意,wholesale 和 retail 不是 widget 的成員,pricing 才是。要訪問 wholesale 和 retail,必須首先訪問 widget 的定價 pricing,然后由于它是一個 Costs 結(jié)構(gòu)體,所以同樣可以使用點運算符訪問其 wholesale 和 retail 成員。
還要注意,對于所有結(jié)構(gòu)體來說,訪問成員時必須使用成員名稱,而不是結(jié)構(gòu)體名稱。例如,以下語句不合法:
//非法結(jié)構(gòu)體聲明 struct Date {int day = 23,month = 8,year = 1983; };在決定是否使用嵌套結(jié)構(gòu)體時,請考慮各種成員的相關(guān)性。一個結(jié)構(gòu)體將邏輯上屬于一體的項目綁定在一起。通常,結(jié)構(gòu)體的成員是描述某個對象的屬性。在上述示例中,對象是一個 widget(小零部件),而 partNum(部件編號)、description(描述)、wholesale(批發(fā))和 retail(零售)價格都是其屬性。
當(dāng)某些屬性相關(guān)并形成對象屬性的邏輯子組時,將它們綁定在一起并使用嵌套結(jié)構(gòu)體是有意義的。請注意下面程序內(nèi)部結(jié)構(gòu)體中屬性的相關(guān)性,它使用了嵌套結(jié)構(gòu)體。
//非法結(jié)構(gòu)體聲明 struct Date {int day = 23,month = 8,year = 1983; };程序輸出結(jié)果:
Annual costs for my 5-year-old cat Sassy are $507.00將結(jié)構(gòu)體傳遞給函數(shù)
與類對象一樣,結(jié)構(gòu)體變量也可以通過值、引用和常量引用傳遞給函數(shù)。默認情況下,它們通過值傳遞,這意味著需要生成整個原始結(jié)構(gòu)的副本并傳遞給函數(shù)。因為不希望浪費時間來復(fù)制整個結(jié)構(gòu)體,所以,除非結(jié)構(gòu)很小,否則一般會通過引用將結(jié)構(gòu)體傳遞給函數(shù)。但是,這樣意味著函數(shù)可以訪問原始結(jié)構(gòu)的成員變量,從而可能更改它們。如果不想讓函數(shù)更改任何成員變量值,那么可以考慮將結(jié)構(gòu)體變量作為一個常量引用傳遞給函數(shù)。
下面程序定義了一個結(jié)構(gòu)體變量并將其傳遞給了兩個函數(shù)。
程序輸出結(jié)果:
Enter the part number: 800 Enter the part description: Screwdriver Enter the quantity on hand: 135 Enter the unit price: 1.25Part Number : 800 Description : Screwdriver Units On Hand: 135 Price : $1.25從函數(shù)返回一個結(jié)構(gòu)體
也可以從函數(shù)返回結(jié)構(gòu)體變量。在這種情況下,函數(shù)的返回類型是結(jié)構(gòu)體的名稱。可以改寫程序 1 以允許 getItemData 函數(shù)創(chuàng)建 Invltem 結(jié)構(gòu)體的局部實例,將數(shù)據(jù)值放入其成員變量中,然后將其傳遞回 main,而不是將其作為引用變量從 main 接收。
以下是修改后的 getltemData 函數(shù)的樣子:
以下是從 main 中調(diào)用它的方法:
part = getItemData();
注意,C++ 只允許從函數(shù)返回單個值。然而,結(jié)構(gòu)體提供了解決這一限制的方法。即使一個結(jié)構(gòu)體可能有幾個成員,它在技術(shù)上還是一個單一的對象。通過在結(jié)構(gòu)體中打包多個值,可以從函數(shù)返回任意數(shù)量的值。
總結(jié)
以上是生活随笔為你收集整理的结构体引用_C/C++结构体完全攻略的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 10大反直觉的数学结论
- 下一篇: c++ curl 超时_cc++写网络爬