结构体引用_C/C++结构体完全攻略
結構體是一個由程序員定義的數據類型,可以容納許多不同的數據值。在過去,面向對象編程的應用尚未普及之前,程序員通常使用這些從邏輯上連接在一起的數據組合到一個單元中。一旦結構體類型被聲明并且其數據成員被標識,即可創建該類型的多個變量,就像可以為同一個類創建多個對象一樣。
雖然今天結構體較少使用,但知道它們是什么,以及如何使用它們仍然很重要,這并不僅僅是因為可以在較老的程序中遇到它們,還因為在某些情況下,類的實例無法使用,這時必須使用結構體。
聲明結構體的方式和聲明類的方式大致相同,其區別如下:
1、使用關鍵字 struct 而不是關鍵字 class。
2、盡管結構體可以包含成員函數,但它們很少這樣做。所以,通常情況下結構體聲明只會聲明成員變量。
3、結構體聲明通常不包括 public 或 private 的訪問修飾符。
4、類成員默認情況是私有的,而結構體的成員則默認為 public。程序員通常希望它們保持公開,只需使用默認值即可。
以下是一個結構體聲明的示例,該結構體將 5 個變量綁定在一起,保存了員工的工資單數據。這個特殊結構體的名稱是 PayRoll。請注意,它以大寫字母開頭,這和類名使用大寫字母開頭的約定一樣。另外還要注意,與類聲明一樣,在結構體聲明的大括號后面必須有一個分號。
正如在類的對象被創建之前,類聲明不會被實例化一樣,結構體聲明不會創建任何結構體的實例。本示例中的結構體聲明只是告訴編譯器PayRoll結構體看起來的樣子。它本質上是創建一個名為 PayRoll 的新數據類型。
定義 PayRoll 結構體的變量和定義其他任何變量的方式并無二致,首先列出數據類型,然后是變量名稱。以下定義語句創建了 PayRoll 結構體的 3 個變量:
PayRoll deptHead, foreman, associate;它們每一個都是 PayRoll 結構體的實例,可以被分配和擁有自己的內存,以保存其成員數據。請注意,盡管 3 個結構體變量具有不同的名稱,但每個變量都包含具有相同名稱的成員,如圖 1 所示。
圖 1 每個結構體變量都包含具有相同名稱的成員
初始化結構體
當定義結構體變量時,可以通過兩種方式初始化它:使用初始化列表或構造函數。
初始化列表
初始化結構體變量成員的最簡單的方法是使用初始化列表。初始化列表是用于初始化一組內存位置的值列表。列表中的項目用逗號分隔并用大括號括起來。
例如,假設已經聲明了以下 Date 結構體:
定義和初始化 Date 變量的方式是:先指定變量名,后接賦值運算符和初始化列表,如下所示:
Date birthday = {23, 8, 1983};該聲明定義 birthday 是一個 Date 結構體的變量,大括號內的值按順序分配給其成員。所以 birthday 的數據成員已初始化,如圖 2 所示。
圖 2 已經初始化的 birthday 的數據成員
也可以僅初始化結構體變量的部分成員。例如,如果僅知道要存儲的生日是8月23日, 但不知道年份,則可以按以下方式定義和初始化變量:
Date birthday = {23,8};這里只有 day 和 month 成員被初始化,year 成員未初始化。但是,如果某個結構成員未被初始化,則所有跟在它后面的成員都需要保留為未初始化。使用初始化列表時,C++ 不提供跳過成員的方法。以下語句試圖跳過 month 成員的初始化。這是不合法的。
Date birthday = {23,1983}; //非法還有一點很重要,不能在結構體聲明中初始化結構體成員,因為結構體聲明只是創建一個新的數據類型,還不存在這種類型的變量。例如,以下聲明是非法的:
//非法結構體聲明 struct Date {int day = 23,month = 8,year = 1983; };因為結構體聲明只聲明一個結構體“看起來是什么樣子的”,所以不會在內存中創建成員變量。只有通過定義該結構體類型的變量來實例化結構體,才有地方存儲初始值。
構造函數初始化結構體
雖然初始化列表易于使用,但它有兩個缺點:
如果有某個成員未被初始化,那么在這種情況下,跟隨在該成員后面的成員都不能初始化。
如果結構體包括任何諸如字符串之類的對象,那么在許多編譯器上它都將無法運行。
在這些情況下,可以使用構造函數來初始化結構體成員變量,這和初始化類成員變量是相同的。與類構造函數一樣,結構體的構造函數必須是與結構體名稱相同的公共成員函數,并且沒有返回類型。因為默認情況下,所有結構體成員都是公開的,所以不需要使用關鍵字 public。
以下是一個名為 Employee 的結構體的聲明語句,它包含一個具有兩參數的構造函數,以便在創建一個 Employee 變量而不向其傳遞任何參數時,提供默認值:
訪問結構體成員
結構體成員的訪問方式與類的公共成員一樣,都是使用點運算符。但是,類的數據成員通常是私有的,必須通過函數訪問。因為結構數據成員是公共的,所以它們可以被直接訪問,并且可以像常規變量一樣使用。以下語句即可為前面創建的每個 PayRoll 變量的 empNumber 成員賦值:
//非法結構體聲明 struct Date {int day = 23,month = 8,year = 1983; };以下語句將顯示 deptHead 變量所有成員的內容:
//非法結構體聲明 struct Date {int day = 23,month = 8,year = 1983; };下面的程序是使用 PayRoll 結構體的完整程序。請注意,在 cin 語句、cout 語句和數學運 算中,單個結構體成員的用法和常規變量基本上是一樣的。
//非法結構體聲明 struct Date {int day = 23,month = 8,year = 1983; };程序輸出結果:
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 結構體的一個實例。此后就可以通過變量名稱和點運算符來訪問其中的 5 個數據成員。例如,在第 22 行中,以下語句將讀取變量的 empNumber 成員中的值:
cin >> employee.empNumber; //正確如果試圖通過結構體類型的名稱來訪問該成員,那么結果將是錯誤的:
cin >> Payroll.empNumber; //錯誤結構體嵌套
正如一個類的對象可以嵌套在另一個類中一樣,一個結構體的實例也可以嵌套在另一個結構體中。例如,來看以下聲明:
//非法結構體聲明 struct Date {int day = 23,month = 8,year = 1983; };Costs 結構體有兩個 double 類型成員,wholesale 和 retail。Item 結構體有 3 個成員,前 2 個是 partNum 和 description,它們都是 string 對象。第 3 個是 pricing,它是一個嵌套的 Costs 結構體。如果定義了一個名為 widge t的 Item 結構體,則圖 3 說明了其成員。
圖 3 在 widget 的成員中包含一個嵌套結構體
它們可以按以下方式訪問:
//非法結構體聲明 struct Date {int day = 23,month = 8,year = 1983; };請注意,wholesale 和 retail 不是 widget 的成員,pricing 才是。要訪問 wholesale 和 retail,必須首先訪問 widget 的定價 pricing,然后由于它是一個 Costs 結構體,所以同樣可以使用點運算符訪問其 wholesale 和 retail 成員。
還要注意,對于所有結構體來說,訪問成員時必須使用成員名稱,而不是結構體名稱。例如,以下語句不合法:
//非法結構體聲明 struct Date {int day = 23,month = 8,year = 1983; };在決定是否使用嵌套結構體時,請考慮各種成員的相關性。一個結構體將邏輯上屬于一體的項目綁定在一起。通常,結構體的成員是描述某個對象的屬性。在上述示例中,對象是一個 widget(小零部件),而 partNum(部件編號)、description(描述)、wholesale(批發)和 retail(零售)價格都是其屬性。
當某些屬性相關并形成對象屬性的邏輯子組時,將它們綁定在一起并使用嵌套結構體是有意義的。請注意下面程序內部結構體中屬性的相關性,它使用了嵌套結構體。
//非法結構體聲明 struct Date {int day = 23,month = 8,year = 1983; };程序輸出結果:
Annual costs for my 5-year-old cat Sassy are $507.00將結構體傳遞給函數
與類對象一樣,結構體變量也可以通過值、引用和常量引用傳遞給函數。默認情況下,它們通過值傳遞,這意味著需要生成整個原始結構的副本并傳遞給函數。因為不希望浪費時間來復制整個結構體,所以,除非結構很小,否則一般會通過引用將結構體傳遞給函數。但是,這樣意味著函數可以訪問原始結構的成員變量,從而可能更改它們。如果不想讓函數更改任何成員變量值,那么可以考慮將結構體變量作為一個常量引用傳遞給函數。
下面程序定義了一個結構體變量并將其傳遞給了兩個函數。
程序輸出結果:
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從函數返回一個結構體
也可以從函數返回結構體變量。在這種情況下,函數的返回類型是結構體的名稱。可以改寫程序 1 以允許 getItemData 函數創建 Invltem 結構體的局部實例,將數據值放入其成員變量中,然后將其傳遞回 main,而不是將其作為引用變量從 main 接收。
以下是修改后的 getltemData 函數的樣子:
以下是從 main 中調用它的方法:
part = getItemData();
注意,C++ 只允許從函數返回單個值。然而,結構體提供了解決這一限制的方法。即使一個結構體可能有幾個成員,它在技術上還是一個單一的對象。通過在結構體中打包多個值,可以從函數返回任意數量的值。
總結
以上是生活随笔為你收集整理的结构体引用_C/C++结构体完全攻略的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 10大反直觉的数学结论
- 下一篇: 人类最强运载火箭诞生!马斯克吹的牛再次兑