C++中的結(jié)構(gòu)體

技術(shù)交流QQ群:1027579432,歡迎你的加入!

1.Cpp中的結(jié)構(gòu)體

  • C/C++數(shù)組允許定義可存儲(chǔ)相同類(lèi)型數(shù)據(jù)項(xiàng)的變量,但是結(jié)構(gòu)體是C++中另一種用戶(hù)自定義的可用的數(shù)據(jù)類(lèi)型,它允許存儲(chǔ)不同類(lèi)型的數(shù)據(jù)項(xiàng)。結(jié)構(gòu)體用于表示一條記錄,假設(shè)想要跟蹤圖書(shū)館中書(shū)本的狀態(tài),可能需要跟蹤每本書(shū)的下列屬性:
        Title: 標(biāo)題
        Author: 作者
        Subject: 類(lèi)別
        Book ID: 書(shū)的ID
    

2.定義結(jié)構(gòu)體

  • 為了定義結(jié)構(gòu)體,必須使用struct語(yǔ)句。struct語(yǔ)句定義了一個(gè)包含多個(gè)成員的新的數(shù)據(jù)類(lèi)型!struct語(yǔ)句的格式如下:
        struct 結(jié)構(gòu)體類(lèi)型的名字{
            成員1類(lèi)型 成員1的名字;
            成員2類(lèi)型 成員2的名字;
            ...
            成員n類(lèi)型 成員n的名字;
        }結(jié)構(gòu)體變量名;
    
  • 在結(jié)構(gòu)體定義的末尾,最后一個(gè)分號(hào)之前,可以指定一個(gè)或多個(gè)結(jié)構(gòu)變量,這是可選的。實(shí)例如下:
        struct Book{  // Book是結(jié)構(gòu)體類(lèi)型名
            char title[50];
            char author[50];
            char subject[100];
            int book_id;
        }book; // book是變量名
    

3.訪(fǎng)問(wèn)結(jié)構(gòu)體成員

  • 為了訪(fǎng)問(wèn)結(jié)構(gòu)體的成員,使用成員訪(fǎng)問(wèn)運(yùn)算符'.',成員訪(fǎng)問(wèn)運(yùn)算符是結(jié)構(gòu)體變量名稱(chēng)和要訪(fǎng)問(wèn)的結(jié)構(gòu)體成員之間的一個(gè)點(diǎn)號(hào),見(jiàn)具體的實(shí)例:
        Books book1;   // 定義結(jié)構(gòu)體類(lèi)型Books的變量book1
        Books book2;   // 定義結(jié)構(gòu)體類(lèi)型Books的變量book2
        // book1詳細(xì)介紹
        strcpy(book1.title, "C++教程");
        strcpy(book1.author, "菜鳥(niǎo)教程");
        strcpy(book1.subject, "編程語(yǔ)言");
        book1.book_id = 123;
        // 輸出book1的詳細(xì)信息
        cout << "book1的標(biāo)題: " << book1.title << endl;
        cout << "book1的作者: " << book1.author << endl;
        cout << "book1的類(lèi)別: " << book1.subject << endl;
        cout << "book1的id: " << book1.book_id << endl;
        cout << "----------------------------------------------------\n";
        // book2詳細(xì)介紹
        strcpy(book2.title, "白夜行");
        strcpy(book2.author, "東野圭吾");
        strcpy(book2.subject, "文學(xué)");
        book2.book_id = 666;
        // 輸出book2的詳細(xì)信息
        cout << "book2的標(biāo)題: " << book2.title << endl;
        cout << "book2的作者: " << book2.author << endl;
        cout << "book2的類(lèi)別: " << book2.subject << endl;
        cout << "book2的id: " << book2.book_id << endl;
    

4.結(jié)構(gòu)體作為函數(shù)參數(shù)

  • 把結(jié)構(gòu)體作為函數(shù)的參數(shù),傳遞參數(shù)的方式與其他類(lèi)型的變量或指針類(lèi)型,具體見(jiàn)下面的實(shí)例:
        // 結(jié)構(gòu)體作為函數(shù)參數(shù)
        void print_book_info(struct Books book){
        cout << "書(shū)的標(biāo)題: " << book.title << endl; 
        cout << "書(shū)的作者: " << book.author << endl;
        cout << "書(shū)的類(lèi)別: " << book.subject << endl;
        cout << "書(shū)的id: " << book.book_id << endl;
        }
        print_book_info(book1);
        cout << "----------------------------------------------------\n";   
        print_book_info(book2);
    

5.指向結(jié)構(gòu)體的指針

  • 定義指向結(jié)構(gòu)體的指針,方式與定義指向其他類(lèi)型變量的指針類(lèi)型:
        struct Books *struct_pointer;
    
  • 在上述定義的指針變量中存儲(chǔ)結(jié)構(gòu)體變量的地址,為了查找結(jié)構(gòu)體變量的地址,把&運(yùn)算符放在結(jié)構(gòu)體名稱(chēng)的前面:
        struct_pointer = &book1;
    
  • 為了使用指向該結(jié)構(gòu)體的指針來(lái)訪(fǎng)問(wèn)結(jié)構(gòu)體的成員,必須使用箭頭->運(yùn)算符:
        struct_pointer->title;
    
  • 具體見(jiàn)下面的實(shí)例:
        // 指向結(jié)構(gòu)體的指針,下面的函數(shù)以結(jié)構(gòu)體指針作為函數(shù)形參
            void print_book_info_with_pointer(struct Books *book_pointer){
            cout << "書(shū)的標(biāo)題: " << book_pointer->title << endl; 
            cout << "書(shū)的作者: " << book_pointer->author << endl;
            cout << "書(shū)的類(lèi)別: " << book_pointer->subject << endl;
            cout << "書(shū)的id: " << book_pointer->book_id << endl;
        }
         // 指向結(jié)構(gòu)體的指針
        print_book_info_with_pointer(&book1);  // 通過(guò)傳book1的地址來(lái)輸出book1信息
        cout << "----------------------------------------------------\n";   
        print_book_info_with_pointer(&book2);  // 通過(guò)傳book2的地址來(lái)輸出book2信息
    

6.typedef關(guān)鍵字

  • 下面是一種更簡(jiǎn)單的定義結(jié)構(gòu)體的方式,可以為創(chuàng)建的類(lèi)型取一個(gè)"別名",實(shí)例如下:
        // 使用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來(lái)定義Book_Info類(lèi)型的變量,而不需要使用struct關(guān)鍵字,如下面的實(shí)例:
        Book_Info book1_info, book2_info;
    
  • 可以使用typedef關(guān)鍵字來(lái)定義非結(jié)構(gòu)類(lèi)型,如下面的實(shí)例:
        typedef long int *pint32;
        pint32 x, y, z;  // x,y,z都是指向長(zhǎng)整型long int的指針
    

7.結(jié)構(gòu)體知識(shí)點(diǎn)總結(jié)

  • 結(jié)構(gòu)體和C++中只有三點(diǎn)區(qū)別,除此之外無(wú)任何區(qū)別:
    • class中默認(rèn)的成員訪(fǎng)問(wèn)權(quán)限是private的,而struct中則是public的
    • 從class繼承默認(rèn)是private繼承的,而從struct繼承默認(rèn)是piblic繼承的
    • class可以定義模板,而struct不可以
  • C++中的結(jié)構(gòu)體關(guān)鍵字typedef可以直接省略,甚至不省略的話(huà),還會(huì)提示你省略;原因:C語(yǔ)言的 struct 定義了一組變量的集合,C編譯器并不認(rèn)為這是一種新的類(lèi)型;C++中的struct是一個(gè)新類(lèi)型的定義聲明, 所以可以省略typedef, 定義變量的時(shí)候也可以省略struct, 而不用像C語(yǔ)言那樣沒(méi)使用typedef取新名字時(shí), 就需要用"struct 結(jié)構(gòu)體名"這種形式定義變量。
  • 如果在結(jié)構(gòu)體能夠完成的目的的情況下,就沒(méi)必要使用類(lèi);C與C++結(jié)構(gòu)體中,前者不能有函數(shù),后者可以有。
  • .與->運(yùn)算符區(qū)別:訪(fǎng)問(wèn)結(jié)構(gòu)的成員時(shí)使用點(diǎn)運(yùn)算符,而通過(guò)指針訪(fǎng)問(wèn)結(jié)構(gòu)的成員時(shí),則使用箭頭運(yùn)算符。也就是說(shuō),用結(jié)構(gòu)體定義了一個(gè)實(shí)體,那么這個(gè)實(shí)體要引用他里面的成員,就用 . 操作符,如果用結(jié)構(gòu)體定義的是一個(gè)結(jié)構(gòu)指針,那么要引用他里面的成員就用->。
        struct Employee{
            char name[50];
            int age;
            char address[50];
        }emp;
    
  • 點(diǎn)運(yùn)算符.使用如下:
        strcpy(emp.name, "Curry_Coder");
    
  • 如果p_emp是一個(gè)指針,指向數(shù)據(jù)類(lèi)型為Employee的對(duì)象,則要把值z(mì)ara賦值給對(duì)象emp的name,需要使用箭頭運(yùn)算符->,箭頭運(yùn)算符->使用如下:
        strcpy(p_emp->name, "zara");
    

8.結(jié)構(gòu)體的繼承

  • C++中的struct對(duì)C中的struct進(jìn)行了擴(kuò)充,它已經(jīng)不再只是一個(gè)包含不同數(shù)據(jù)類(lèi)型的數(shù)據(jù)結(jié)構(gòu)了,它已經(jīng)獲取了太多的功能。struct能包含成員函數(shù);struct能繼承;struct能實(shí)現(xiàn)多態(tài);與class的區(qū)別是:最本質(zhì)的一個(gè)區(qū)別就是默認(rèn)的訪(fǎng)問(wèn)控制,體現(xiàn)在兩個(gè)方面:
    • 默認(rèn)的繼承訪(fǎng)問(wèn)權(quán)限:struct是public的,class是private的;
          struct A{
              char a;
          };
          struct B:A{
              char b;
          };
      
      • 這個(gè)時(shí)候B是public繼承A的,如果都將上面的struct改成class,那么B是private繼承A的,這就是默認(rèn)的繼承訪(fǎng)問(wèn)權(quán)限。所以我們?cè)谄綍r(shí)寫(xiě)類(lèi)繼承的時(shí)候,通常會(huì)這樣寫(xiě):
            struct B: public A;
        
      • 就是為了指明是public繼承,而不是用默認(rèn)的private繼承;到底默認(rèn)是public繼承還是private繼承,取決于子類(lèi)而不是基類(lèi);struct可以繼承class,同樣class也可以繼承struct,那么默認(rèn)的繼承訪(fǎng)問(wèn)權(quán)限是看子類(lèi)到底是用的struct還是class。如下:
            struct A{};
            class B: A{};  // private繼承
            struct C: B{}; // public繼承
        
    • struct作為數(shù)據(jù)結(jié)構(gòu)的實(shí)現(xiàn)體,它默認(rèn)的數(shù)據(jù)訪(fǎng)問(wèn)控制是public的。而class作為對(duì)象的實(shí)現(xiàn)體,它默認(rèn)的成員變量訪(fǎng)問(wèn)控制是 private的。當(dāng)你覺(jué)得你要做的更像是一種數(shù)據(jù)結(jié)構(gòu)的話(huà),那么用struct,如果你要做的更像是一種對(duì)象的話(huà),那么用class。
          struct A //定義一個(gè)struct
          {
              char c1;
              int n2;
              double db3;
          };
          A a={'p',7,3.1415926}; //定義時(shí)直接賦值 
      
      • 向上面的struct中加入一個(gè)構(gòu)造函數(shù)(或虛函數(shù)),struct也不能用{}賦初值了。原因:加入一個(gè)構(gòu)造函數(shù)或是一個(gè)虛函數(shù)會(huì)使 struct更體現(xiàn)出一種對(duì)象的特性,而使此{(lán)}操作不再有效。事實(shí)上,是因?yàn)榧尤脒@樣的函數(shù),使得類(lèi)的內(nèi)部結(jié)構(gòu)發(fā)生了變化。而加入一個(gè)普通的成員函數(shù)呢?你會(huì)發(fā)現(xiàn){}依舊可用。其實(shí)你可以將普通的函數(shù)理解成對(duì)數(shù)據(jù)結(jié)構(gòu)的一種算法,這并不打破它數(shù)據(jù)結(jié)構(gòu)的特性。

9.參考博客

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容