struct的初始化,拷貝及指標成員的使用技巧

2022-08-21 00:27:12 字數 2472 閱讀 5328

struct是c中重要的adt。但是在一般講c的書中,往往只介紹了struct的定義、順序初始化及位域。

本文將筆者曾經用到的、看到的知識點羅列出來,與大家分享。

為了方便後面的介紹,先定義乙個struct型別:

struct user

;

1 初始化

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

1)順序

這種方法很常見,在一般的介紹c的書中都有介紹。順序初始化的特點是: 按照成員定義的順序,從前到後逐個初始化;允許只初始化部分成員;在被初始化的成員之前,不能有未初始化的成員;未顯示初始化的自動設為0。

eg:

struct user oneuser = ;

初始化之後,oneuser各個成員的值為:

oneuser.id = 10;

oneuser.name = "lucy";

oneuser.home = "/home/lucy";

oneuser.passwd = 0;

2)亂序(c風格)

順序的缺陷是必須按成員定義的順序逐個初始化,不能間隔。而亂序的方式則很好的解決了這個問題,因為這種方式是按照成員名進行。

eg:

struct user oneuser = ;

3)亂序(c++風格)

c++風格的亂序初始化方式跟c風格的一樣,只是它更常用在c++**裡。

eg:

struct user oneuser = ;

不論是哪種方式,都允許只初始化部分成員;未被初始化的成員預設為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

;

struct inode data = ;

//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

;

改成:

struct file

;

即將指標成員換成大小為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);

(**:

struct的初始化

在android的底層裝置定義中,會出現很多這樣的 結構體初始化專案 裝置檔案操作方法表 static struct file operations hello fops 這就是指定初始化在linux裝置驅動程式,它源自iso c99標準。這種方式的優勢就在於由此初始化不必嚴格按照定義時的順序。已知...

直接初始化和拷貝初始化

定義 示例 string dots 10,直接初始化 string s dots 直接初始化 string s2 dots 拷貝初始化 string null book 9 999 99999 9 拷貝初始化 string nines string 100,9 拷貝初始化注 直接初始化實際上是要求編...

struct結構體初始化

參考 初始化方式 第1 種 定義時初始化 方式一 點操作符 struct a a1 方式二 struct a a1 方式三 struct a a1 核心喜歡用方式一,使用方式二和方式三時,成員初始化順序可變,使用方式三時初始化順序不可變。第2 種 在c 中,結構體與類在使用上已沒有本質上的區別了,所...