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上要特別注意這種寫法是否能夠使用囉!

2015年9月22日 星期二

alias 的使用 .bashrc

http://jslinux.pixnet.net/blog/post/15534168-%E5%A5%BD%E7%94%A8%E7%9A%84-alias-%E6%8C%87%E4%BB%A4


寫在home底下的  .bashrc

# User specific aliases and functions
alias grep='grep --color=auto -n '
alias cat='cat -n '

 alias tmux='TERM=xterm-256color tmux -2'
~

2015年7月3日 星期五

source Insight 使用技巧

最近使用soruce insight 的一些常用技巧


Source Insight 4 遇到使用上非常log 卡頓
    => Options ->  Preference ->Display -> Page number in status bar  打勾取消


2015年5月19日 星期二

struct 宣告 在big_endian 和 little_endian 上的排列

若是以bit 為單位在
big_endian : struct 由上而下 在記憶體的位置則是以bits為單位  由高位排至低位
little_endian :struct 由上而下 在記憶體的位置以1byte 為單位  由最高位byte的最低位bit開始 往記憶體低位排



以ipv6 addr packet 的前4個byte  為例 (from wiki)

例子如下:
#ifdef _BIG_ENDIAN
uint32 version:4;
uint32 tclassH:4;

uint32 tclassL:4;
uint32 flow_lblH:4;

uint32 flow_lblL:16;
#elif  _LITTLE_ENDIAN
uint32 tclassH:4;
  uint32 version:4;

uint32 flow_lblH:4;
uint32 tclassL:4;

uint32 flow_lblL:16;
#endif

其中big_endian 其實也可以寫的更簡潔
uint32 version:4;
uint32 tclass:8;
uint32 flow_lblL:20;