2015年10月14日 星期三

有關C語言的struct進階初始化



假設有一個student的結構定義如下:

typedef struct student{
  char name[50];
  int studentNo;
  int age;
}student;


按照一般教科書上的寫法,初始化的方式是先宣告一個struct student的變數,然後再用點(dot)運算子去存取內部成員並賦值,例如:

struct student st1;
st1.name = "Peter";
st1.studentNo = 1234;
st1.age = 18;


但是進階的初始化方法卻是宣告直接再以點(dot)運算子賦值,例如:

student st1={
  .name = "Peter",
  .age = 18,
  .studentNo = 1234
};


原來點運算子就可以等同struct內的成員,多個成員則用(,)來分開,類似陣列(array)的宣告方法,不同的是,他賦值的順序是可以不用按照struct定義內的先後順序的!

說到陣列(array),他的宣告也是有幾種神奇的方法。
例如:

int a[7] = { [4]=29, 33, [2]=15 };
相當於
int a[7] = { 0, 0, 15, 0, 29, 33, 0 };

可以用[index]= value 的方法指定給特定的元素,沒有指派的值就是0這樣。

結合上面struct的用法,也可以一併使用combo連續技,例如:

student st2[5]={
  [3]={
      .name = "Titus",
      .age = 22,
      .studentNo = 1041 },
  [2]={
      .studentNo = 1042
      .age = 23,
      .name = "Stephen", },
}

[index]= 可以不必按照順序,裡頭的成員也不必按照順序,其餘沒指派的元素會自動初始化為0。


當然也可以將一連串連續的元素賦予相同的值,例如:

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


其實這些進階的寫法有什麼實際的好處我也還沒參透(難道是這樣「看起來」有比較OO嗎?哈哈),但至少能看懂這些,以後再看別人的code有用這種語法時就不會再覺得好古怪好神奇了。這些小東西看在用JAVA或C#的人可能不值一提,不過我在這古老而傳統的C語言上能看見這些寫法,仍是感到十分特別又有趣的,所以說,C語言也是會與時俱進的!C語言好棒阿!(這種將C變成既簡潔又充滿彈性的極致語言我看就是Ruby了吧!哈哈!)

PS:以上應該都是使用革奴牌(GNU gcc)的延伸C語法,而不是標準的C語法,如果你是在非GNU gcc的compiler上要特別注意這種寫法是否能夠使用囉!