技術(shù)交流QQ群:1027579432,歡迎你的加入!
1.Cpp中的結(jié)構(gòu)體
- C/C++數(shù)組允許定義可存儲相同類型數(shù)據(jù)項的變量,但是結(jié)構(gòu)體是C++中另一種用戶自定義的可用的數(shù)據(jù)類型,它允許存儲不同類型的數(shù)據(jù)項。結(jié)構(gòu)體用于表示一條記錄,假設(shè)想要跟蹤圖書館中書本的狀態(tài),可能需要跟蹤每本書的下列屬性:
Title: 標題 Author: 作者 Subject: 類別 Book ID: 書的ID
2.定義結(jié)構(gòu)體
- 為了定義結(jié)構(gòu)體,必須使用struct語句。struct語句定義了一個包含多個成員的新的數(shù)據(jù)類型!struct語句的格式如下:
struct 結(jié)構(gòu)體類型的名字{ 成員1類型 成員1的名字; 成員2類型 成員2的名字; ... 成員n類型 成員n的名字; }結(jié)構(gòu)體變量名; -
在結(jié)構(gòu)體定義的末尾,最后一個分號之前,可以指定一個或多個結(jié)構(gòu)變量,這是可選的。實例如下:
struct Book{ // Book是結(jié)構(gòu)體類型名 char title[50]; char author[50]; char subject[100]; int book_id; }book; // book是變量名
3.訪問結(jié)構(gòu)體成員
- 為了訪問結(jié)構(gòu)體的成員,使用成員訪問運算符'.',成員訪問運算符是結(jié)構(gòu)體變量名稱和要訪問的結(jié)構(gòu)體成員之間的一個點號,見具體的實例:
Books book1; // 定義結(jié)構(gòu)體類型Books的變量book1 Books book2; // 定義結(jié)構(gòu)體類型Books的變量book2 // book1詳細介紹 strcpy(book1.title, "C++教程"); strcpy(book1.author, "菜鳥教程"); strcpy(book1.subject, "編程語言"); book1.book_id = 123; // 輸出book1的詳細信息 cout << "book1的標題: " << book1.title << endl; cout << "book1的作者: " << book1.author << endl; cout << "book1的類別: " << book1.subject << endl; cout << "book1的id: " << book1.book_id << endl; cout << "----------------------------------------------------\n"; // book2詳細介紹 strcpy(book2.title, "白夜行"); strcpy(book2.author, "東野圭吾"); strcpy(book2.subject, "文學(xué)"); book2.book_id = 666; // 輸出book2的詳細信息 cout << "book2的標題: " << book2.title << endl; cout << "book2的作者: " << book2.author << endl; cout << "book2的類別: " << book2.subject << endl; cout << "book2的id: " << book2.book_id << endl;
4.結(jié)構(gòu)體作為函數(shù)參數(shù)
- 把結(jié)構(gòu)體作為函數(shù)的參數(shù),傳遞參數(shù)的方式與其他類型的變量或指針類型,具體見下面的實例:
// 結(jié)構(gòu)體作為函數(shù)參數(shù) void print_book_info(struct Books book){ cout << "書的標題: " << book.title << endl; cout << "書的作者: " << book.author << endl; cout << "書的類別: " << book.subject << endl; cout << "書的id: " << book.book_id << endl; } print_book_info(book1); cout << "----------------------------------------------------\n"; print_book_info(book2);
5.指向結(jié)構(gòu)體的指針
- 定義指向結(jié)構(gòu)體的指針,方式與定義指向其他類型變量的指針類型:
struct Books *struct_pointer; - 在上述定義的指針變量中存儲結(jié)構(gòu)體變量的地址,為了查找結(jié)構(gòu)體變量的地址,把&運算符放在結(jié)構(gòu)體名稱的前面:
struct_pointer = &book1; - 為了使用指向該結(jié)構(gòu)體的指針來訪問結(jié)構(gòu)體的成員,必須使用箭頭->運算符:
struct_pointer->title; - 具體見下面的實例:
// 指向結(jié)構(gòu)體的指針,下面的函數(shù)以結(jié)構(gòu)體指針作為函數(shù)形參 void print_book_info_with_pointer(struct Books *book_pointer){ cout << "書的標題: " << book_pointer->title << endl; cout << "書的作者: " << book_pointer->author << endl; cout << "書的類別: " << book_pointer->subject << endl; cout << "書的id: " << book_pointer->book_id << endl; } // 指向結(jié)構(gòu)體的指針 print_book_info_with_pointer(&book1); // 通過傳book1的地址來輸出book1信息 cout << "----------------------------------------------------\n"; print_book_info_with_pointer(&book2); // 通過傳book2的地址來輸出book2信息
6.typedef關(guān)鍵字
- 下面是一種更簡單的定義結(jié)構(gòu)體的方式,可以為創(chuàng)建的類型取一個"別名",實例如下:
// 使用typedef創(chuàng)建結(jié)構(gòu)體 typedef struct Book_Info{ char title[50]; char author[50]; char subject[100]; int book_id; }Book_Info; - 可以直接使用Book_Info來定義Book_Info類型的變量,而不需要使用struct關(guān)鍵字,如下面的實例:
Book_Info book1_info, book2_info; - 可以使用typedef關(guān)鍵字來定義非結(jié)構(gòu)類型,如下面的實例:
typedef long int *pint32; pint32 x, y, z; // x,y,z都是指向長整型long int的指針
7.結(jié)構(gòu)體知識點總結(jié)
- 結(jié)構(gòu)體和C++中只有三點區(qū)別,除此之外無任何區(qū)別:
- class中默認的成員訪問權(quán)限是private的,而struct中則是public的
- 從class繼承默認是private繼承的,而從struct繼承默認是piblic繼承的
- class可以定義模板,而struct不可以
- C++中的結(jié)構(gòu)體關(guān)鍵字typedef可以直接省略,甚至不省略的話,還會提示你省略;原因:C語言的 struct 定義了一組變量的集合,C編譯器并不認為這是一種新的類型;C++中的struct是一個新類型的定義聲明, 所以可以省略typedef, 定義變量的時候也可以省略struct, 而不用像C語言那樣沒使用typedef取新名字時, 就需要用"struct 結(jié)構(gòu)體名"這種形式定義變量。
- 如果在結(jié)構(gòu)體能夠完成的目的的情況下,就沒必要使用類;C與C++結(jié)構(gòu)體中,前者不能有函數(shù),后者可以有。
- .與->運算符區(qū)別:訪問結(jié)構(gòu)的成員時使用點運算符,而通過指針訪問結(jié)構(gòu)的成員時,則使用箭頭運算符。也就是說,用結(jié)構(gòu)體定義了一個實體,那么這個實體要引用他里面的成員,就用 . 操作符,如果用結(jié)構(gòu)體定義的是一個結(jié)構(gòu)指針,那么要引用他里面的成員就用->。
struct Employee{ char name[50]; int age; char address[50]; }emp; - 點運算符.使用如下:
strcpy(emp.name, "Curry_Coder"); - 如果p_emp是一個指針,指向數(shù)據(jù)類型為Employee的對象,則要把值zara賦值給對象emp的name,需要使用箭頭運算符->,箭頭運算符->使用如下:
strcpy(p_emp->name, "zara");
8.結(jié)構(gòu)體的繼承
- C++中的struct對C中的struct進行了擴充,它已經(jīng)不再只是一個包含不同數(shù)據(jù)類型的數(shù)據(jù)結(jié)構(gòu)了,它已經(jīng)獲取了太多的功能。struct能包含成員函數(shù);struct能繼承;struct能實現(xiàn)多態(tài);與class的區(qū)別是:最本質(zhì)的一個區(qū)別就是默認的訪問控制,體現(xiàn)在兩個方面:
- 默認的繼承訪問權(quán)限:struct是public的,class是private的;
struct A{ char a; }; struct B:A{ char b; };- 這個時候B是public繼承A的,如果都將上面的struct改成class,那么B是private繼承A的,這就是默認的繼承訪問權(quán)限。所以我們在平時寫類繼承的時候,通常會這樣寫:
struct B: public A; - 就是為了指明是public繼承,而不是用默認的private繼承;到底默認是public繼承還是private繼承,取決于子類而不是基類;struct可以繼承class,同樣class也可以繼承struct,那么默認的繼承訪問權(quán)限是看子類到底是用的struct還是class。如下:
struct A{}; class B: A{}; // private繼承 struct C: B{}; // public繼承
- 這個時候B是public繼承A的,如果都將上面的struct改成class,那么B是private繼承A的,這就是默認的繼承訪問權(quán)限。所以我們在平時寫類繼承的時候,通常會這樣寫:
-
struct作為數(shù)據(jù)結(jié)構(gòu)的實現(xiàn)體,它默認的數(shù)據(jù)訪問控制是public的。而class作為對象的實現(xiàn)體,它默認的成員變量訪問控制是 private的。當你覺得你要做的更像是一種數(shù)據(jù)結(jié)構(gòu)的話,那么用struct,如果你要做的更像是一種對象的話,那么用class。
struct A //定義一個struct { char c1; int n2; double db3; }; A a={'p',7,3.1415926}; //定義時直接賦值- 向上面的struct中加入一個構(gòu)造函數(shù)(或虛函數(shù)),struct也不能用{}賦初值了。原因:加入一個構(gòu)造函數(shù)或是一個虛函數(shù)會使 struct更體現(xiàn)出一種對象的特性,而使此{}操作不再有效。事實上,是因為加入這樣的函數(shù),使得類的內(nèi)部結(jié)構(gòu)發(fā)生了變化。而加入一個普通的成員函數(shù)呢?你會發(fā)現(xiàn){}依舊可用。其實你可以將普通的函數(shù)理解成對數(shù)據(jù)結(jié)構(gòu)的一種算法,這并不打破它數(shù)據(jù)結(jié)構(gòu)的特性。
- 默認的繼承訪問權(quán)限:struct是public的,class是private的;