1. 程式人生 > >對結構體初始化

對結構體初始化

對結構體

struct a {

int b;

int c;

}

有幾種初始化方式:

struct a a1 = {
 .b = 1,
 .c = 2
};
或者
struct a a1 = {
 b:1,
 c:2
}
或者
struct a a1 = { 1, 2};

核心喜歡用第一種,使用第一種和第二種時,成員初始化順序可變。

轉一篇文章

在閱讀GNU/Linux核心程式碼時,我們會遇到一種特殊的結構初始化方式。該方式是某些C教材(如譚二版、K&R二版)中沒有介紹過的。這種方式稱為指定初始化(designated initializer)。下面我們看一個例子,Linux-2.6.x/drivers/usb/storage/usb.c中有這樣一個結構體初始化專案:
static struct usb_driver usb_storage_driver = {
       .owner = THIS_MODULE,
       .name = "usb-storage",
       .probe = storage_probe,
       .disconnect = storage_disconnect,
       .id_table = storage_usb_ids,
};
    乍一看,這與我們之前學過的結構體初始化差距甚遠。其實這就是前面所說的指定初始化在Linux裝置驅動程式中的一個應用,它源自ISO C99標準。以下我摘錄了C Primer Plus第五版中相關章節的內容,從而就可以很好的理解2.6版核心採用這種方式的優勢就在於由此初始化不必嚴格按照定義時的順序。這帶來了極大的靈活性,其更大的益處還有待大家在開發中結合自身的應用慢慢體會。
    已知一個結構,定義如下
struct book {
    char title[MAXTITL];
    char author[MAXAUTL];
    float value;
};
    C99支援結構的指定初始化專案,其語法與陣列的指定初始化專案近似。只是,結構的指定初始化專案使用點運算子和成員名(而不是方括號和索引值)來標識具體的元素。例如,只初始化book結構的成員value,可以這樣做:
    struct book surprise = { .value = 10.99 };
    可以按照任意的順序使用指定初始化專案:
    struct book gift = { .value = 25.99,
                                    .author = "James Broadfool",
                                    .title = "Rue for the Toad"};
    正像陣列一樣,跟在一個指定初始化專案之後的常規初始化專案為跟在指定成員後的成員提供了初始值。另外,對特定成員的最後一次賦值是它實際獲得的值。例如,考慮下列宣告:
    struct book gift = { .value = 18.90,
                                    .author = "Philionna pestle",
                                    0.25};
    這將把值0.25賦給成員value,因為它在結構宣告中緊跟在author成員之後。新的值0.25代替了早先的賦值18.90。
    有關designated initializer的進一步資訊可以參考c99標準的6.7.8節Ininialization。

摘自:

 

5.22 特定的初始化

標準C89需要初始化語句的元素以固定的順序出現,和被初始化的陣列或結構體中的元素順序一樣。

在ISO C99中,你可以按任何順序給出這些元素,指明它們對應的陣列的下標或結構體的成員名,並且GNU C也把這作為C89模式下的一個擴充套件。這個擴充套件沒有在GNU C++中實現。

為了指定一個數組下標,在元素值的前面寫上“[index] =”。比如:

int a[6] = { [4] = 29, [2] = 15 };
            

相當於:

int a[6] = { 0, 0, 15, 0, 29, 0 };
            

下標值必須是常量表達式,即使被初始化的陣列是自動的。

一個可替代這的語法是在元素值前面寫上“.[index]”,沒有“=”,但從GCC 2.5開始就不再被使用,但GCC仍然接受。為了把一系列的元素初始化為相同的值,寫為“[first ... last] = value”。這是一個GNU擴充套件。比如:

int widths[] = { [0 ... 9] = 1, [10 ... 99] = 2, [100] = 3 };
            

如果其中的值有副作用,這個副作用將只發生一次,而不是範圍內的每次初始化一次。

注意,陣列的長度是指定的最大值加一。

在結構體的初始化語句中,在元素值的前面用“.fieldname =

 ”指定要初始化的成員名。例如,給定下面的結構體,

struct point { int x, y; };
            

和下面的初始化,

struct point p = { .y = yvalue, .x = xvalue };
            

等價於:

struct point p = { xvalue, yvalue };
            

另一有相同含義的語法是“.fieldname:”,不過從GCC 2.5開始廢除了,就像這裡所示:

struct point p = { y: yvalue, x: xvalue };
            

[index]”或“.fieldname”就是指示符。在初始化共同體時,你也可以使用一個指示符(或不再使用的冒號語法),來指定共同體的哪個元素應該使用。比如:

union foo { int i; double d; };
            union foo f = { .d = 4 };
            

將會使用第二個元素把4轉換成一個double型別來在共同體存放。相反,把4轉換成union foo型別將會把它作為整數i存入共同體,既然它是一個整數。(參考5.24節向共同體型別轉換。)

你可以把這種命名元素的技術和連續元素的普通C初始化結合起來。每個沒有指示符的初始化元素應用於陣列或結構體中的下一個連續的元素。比如,

int a[6] = { [1] = v1, v2, [4] = v4 };
            

等價於

int a[6] = { 0, v1, v2, 0, v4, 0 };
            

當下標是字元或者屬於enum型別時,標識陣列初始化語句的元素特別有用。例如:

int whitespace[256]
            = { [' '] = 1, ['\t'] = 1, ['\h'] = 1,
            ['\f'] = 1, ['\n'] = 1, ['\r'] = 1 };
            

你也可以在“=”前面寫上一系列的“.fieldname”和“[index]”指示符來指定一個要初始化的巢狀的子物件;這個列表是相對於和最近的花括號對一致的子物件。比如,用上面的struct point宣告:

struct point ptarray[10] = { [2].y = yv2, [2].x = xv2, [0].x = xv0 };
            

如果同一個成員被初始化多次,它將從最後一次初始化中取值。如果任何這樣的覆蓋初始化有副作用,副作用發生與否是非指定的。目前,gcc會捨棄它們併產生一個警告。

相關推薦

結構初始

對結構體 struct a { int b; int c; } 有幾種初始化方式: struct a a1 = {  .b = 1,  .c = 2 }; 或者 struct a a1 = {  b:1,  c:2 } 或者 struct a a1 =

1.結構體型別建立 2.結構初始 3.結構記憶體齊 4.位段,位段計算機大小。 5.列舉 6.聯合

結構體型別的建立 1.結構體的宣告 結構是一些值的集合,這些值稱為成員變數。每個結構體的成員可以是不同型別的變數。 struct Student { char name[20];//名字 short age;//年齡 char sex[5

Linux下C結構初始

直觀 tro 擴展性 方式 建議 struct 初始化方式 www 寫到 原文地址在這裏: http://www.cnblogs.com/Anker/p/3545146.html 我 只把裏面的主要介紹和代碼寫到這裏了. 順序初始化   教科書上講C語言結構體初始化

結構初始及定義1

HA int tdi %d struct 初始 student har nbsp #include<stdio.h> struct student{ int num; char name[20]; float score; }; int m

memset結構初始

http log 結構 sha 方便 AR test name truct memset可以方便的清空一個結構類型的變量或數組。    如:   struct sample_struct   {   char csName[16];   int iSeq;   int iT

結構初始

upload image scrip mat roc java span tag 授權 結構體初始化 如果結構體沒有實現任何初始化函數,Swift 默認給生成一個包含所有成員變量的初始化構造器。 struct RocketConfiguration { let

自定義型別 結構體型別建立 結構初始

結構體 結構體的基礎知識: 結構是一些值的集合,這些值稱為成員變數。結構的每個成員可以是不同型別的變數。 結構體的宣告: struct tag //struct是結構體關鍵字,tag為結構體標籤 { member-list; //成員列表 }variable-list;//變

結構初始方法

三種方式都可以:   1 #include <stdio.h>   2 typedef struct {   3     int a;   4     int b;

c++結構初始

https://blog.csdn.net/qq_30835655/article/details/76850894 struct job { string name; int salary; job(string _name,int _sala

c: 結構初始的四種方法

定義 struct InitMember { int first; double second; char* third; float four; }; 方法一:定義時賦值 struct InitMember test = {-10,3.141590,“method one”,0.25};

結構初始 訪問的三種方式(結構指標)

輸出三個學生中成績最高的學生資訊 1>  #include<stdio.h> typedef struct student {     int num;     char name[10];     int score; } Student; int m

C語言--結構初始

一、結構體基本初始化方法 定義 struct Mystruct { int first; double second; char* third; float four; }; 1、方法一:定義時賦值 賦值時注意定義時各個成員的順序,不能錯位。

C語言結構初始的四種方法

定義 struct InitMember { int first; double second; char* third; float four; }; 方法一:定義時賦值 struct InitMember t

C語言結構初始結構指標

結構體初始化 #include <stdio.h> //結構體的宣告和定義方法 //1.宣告和定義分離 struct weapon{ char name[20]; in

結構初始結構指標.結構陣列.結構函式的呼叫賦值等

#include "stdio.h" #include "stdlib.h" #include "string.h" int fun(void); /************************************* int ARRSCORE[3]={133,123

陣列,結構初始 {0}

  一直以為 int a[256]={0};是把a的所有元素初始化為0,int a[256]={1};是把a所有的元素初始化為1. 除錯的時檢視記憶體發現不是那麼一回事,翻了一下《The C++ Programming Language》總算有定論。PDF的竟然不然複製,

C/C++結構初始與賦值

1.結構體的初始化 結構體是常用的自定義構造型別,是一種很常見的資料打包方法。結構體物件的初始化有多種方式,分為指定初始化、順序初始化、建構函式初始化。假如有如下結構體。 struct A { int b; int c; } (1)指定初始

C++ 與 C 語言 結構初始

C++中的struct可以看作class,結構體也可以擁有建構函式,所以我們可以通過結構體的建構函式來初始化結構體物件。(在C++中,結構體與類在使用上已沒有本質上的區別了,所以

結構成員賦值-標記結構初始語法-結構成員前面加小數點

指定成員初始化 static struct file_opretions sep4020_key_fops = { .ower = THIS, .read = sep4020_

結構初始方式

   幾種結構體的初始化方式.?12345678910111213141516171819202122232425262728293031323334353637383940struct student