struct的初始化,拷貝及指標成員的提示(摘自http://blog.chinaunix.net/u/9577/showart_417268.html)

來源:互聯網
上載者:User
摘自http://blog.chinaunix.net/u/9577/showart_417268.htmlstruct的初始化,拷貝及指標成員的提示


struct是C中重要的ADT。但是在一般講C的書中,往往只介紹了struct的定義、順序初始化及位域。
本文將筆者曾經用到的、看到的知識點羅列出來,與大家分享。

為了方便後面的介紹,先定義一個struct類型:
        struct User
        {
            int id;             //id
            char name[100];     //user name
            char *home;         //home directory
            int passwd;         //password
        };


1 初始化
struct資料有3中初始化方法:順序,C風格及C++風格的亂序。

1)順序
這種方法很常見,在一般的介紹C的書中都有介紹。順序初始化的特點是: 按照成員定義的順序,從前到後逐個初始化;允許只初始化部分成員;在被初始化的成員之前,不能有未初始化的成員。
eg:
        struct User oneUser = {10, "Lucy", "/home/Lucy"};
初始化之後,oneUser各個成員的值為:
        oneUser.id = 10;
        oneUser.name = "Lucy";
        oneUser.home = "/home/Lucy";
        oneUser.passwd = 0;

2)亂序(C風格)
順序的缺陷是必須按成員定義的順序逐個初始化,不能間隔。而亂序的方式則很好的解決了這個問題,因為這種方式是按照成員名進行。
eg:
        struct User oneUser = {
                               .name = "Lucy", 
                               .id = 10,
                               .home = "/home/Lucy"
                              };

3)亂序(C++風格)
C++風格的亂序初始化方式跟C風格的一樣,只是它更常用在C++代碼裡。
eg:
        struct User oneUser = {
                               name:"Lucy", 
                               id:10,
                               home:"/home/Lucy"
                              };


不論是哪種方式,都允許只初始化部分成員;未被初始化的成員預設為0(指標類型的成員預設為NULL)。兩種亂序初始化方法,即可以用在C代碼中,也可以用在C++代碼中。


2 拷貝
struct有兩種拷貝方式,一是直接賦值(=),另一種是用memcpy等庫函數實行記憶體拷貝。
eg:
        struct Temp a, b;
        //Set value to members of b
        a = b;
        memcpy(&a, &b, sizeof(a));
不管是哪種拷貝方式,都是將以&b開始的,大小為sizeof(struct Temp)的記憶體地區中的資料,簡單地複製到以&a開始的,同樣大小的記憶體地區。所以,這兩種方式與按成員賦值是等價的:
        a.id = b.id;
        a.name = b.name;
        a.home = b.home;
        a.passwd = b.passwd;
由此,我們不難看出,上面兩種拷貝方式都屬於淺拷貝。
             

3 指標成員的兩種提示
1) 為多個指標成員同時分配記憶體
如果一個struct中有多個指標類型的成員,我們通常需要為每個指標逐個成員分配記憶體空間,並在使用完時釋放它們;這樣頻繁調用malloc/free,難免讓人生厭。如果在分配記憶體之前,每個指標所指向記憶體地區的大小是確定的,那麼,我們可以為所有指標一次性分配記憶體地區;並在使用完後,一次性釋放。
eg:
       struct Inode
       {
          int id;

          char *file;
          int fie_len;

          char *path;
          int path_len;

          char *user;
          int user_len;
       };

       struct Inode data = {
                            .file_len = X,
                            .path_len = Y,
                            .user_len = X
                            };

       //Allocate memory
       data.file = (char *)malloc(data.file_len + data.path_len, data.user_len);
       data.path = data.file + data.file_len;
       data.user = data.path + data.path_len;


       //User
       ...


       //Free memory
       free(data.file);


2)變長數組的另類實現
將下面的定義
       struct File
       {
          TypeA dataA;
          ......
          char *data;
          TypeN dataN;         
       };
改成:
       struct File
       {
          TypeA dataA;
          ......         
          TypeN dataN;   
          char data[0];      
       };
即將指標成員換成大小為0的一維數組, 作為struct的最後一個成員(資料結構的可變部分必須作為最後一個成員),有兩個優點:
(1) 在緊鄰struct處為data分配記憶體地區,這樣在分配記憶體後無須為data賦值;
(2) 利用數組的特性,以指標的方式通過越界訪問data數組外的記憶體地區。
eg:
       struct File *pVar = (struct File *)malloc(sizeof(struct File) + DATA_LEN);
       strncpy(pVar->data, "Source data", DATA_LEN);
       

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.