自制編程語言2.1柔性數組

柔性數組是c99中的玩意,在c89中並沒有,起初柔性數組叫做柔性數組成員(flexible array memeber),因為它必須要放在一個結構體中作為結構體成員存在,下面介紹它的來頭。

看似功能簡單的語言,往往更底層,且更靈活,受限制較少,在自由發揮之下往往可以碾壓那些高級語言,比如彙編和C就是創造力無限的兩種語言,就像蓋房子,底層語言給用戶提供的是原材料,比較累但是想蓋啥樣的房子都行,高級語言提供的是房子的結構,它只需要小部分工作,房子就成型了,因此蓋房子更快,但是風格也相對單一,就拿c語言來說他可是開發linux內核的語言,不過linux說沒有采用c++是因為好的c++程序員很少,c程序員才是對代碼精煉的極致追求者,這也正是柔性數組誕生的原因,在結構體彙總經常需要單獨存儲一個字符串,由於字符串的長度不固定,一種較為常見的做法是在結構體中加一個指針作為結構體成員,用該指針指向字符串,舉個例子,假設結構體是從堆中動態分配的,這和咱們編譯器中的應用更接近,見下面

<code>struct sample{
	int length;
  char* str;
}
struct sample * s = malloc(sizeof(struct sample))
s->length=10;
s->str = malloc(s.length+1)
strcpy(s->str,"abcdefghij",10)
s->str[s->length] = '\0'/<code>

功能實現了,此方法完全可以勝任,但是這樣一來,字符串str佔用的內存和結構體s本身還是分離的,而且字符串需要額外維護一個用malloc申請的動態內存,因此c程序員認為還可能有優化的地方,如果當字符串本身就位於struct中不是更好嗎,你也想到了,在struct的末尾放一個數組就行了,此數組專門用來存儲字符串,但是我們是想讓結構體存儲不同長度的字符串,可是字符串長度若不是固定的話,結構體的長度也就不固定了,編譯器需要在編譯的時候就確定出數據類型,的主要目的就是確定該數據類型的長度,就是內存大小,因此不同的長度就等於定義了多種不同給的數據類型,我們不能為每種長度的字符串單獨建一個struct吧,因此為了使得結構體長度固定,位於結構體中的數組的長度應該為0.把結構體改為一以下代碼。

<code>struct sample{
	int length;
  char str[0];
}
char* string = "abcdefghij";
int lengt = strlen(string);
struct sample* s=malloc(sizeof(struct sample)+length+1)
s->length=length+1;
strcpy(s->str,string,length);
s->str[s->length] = '\0';/<code>

見第三行,儘管數組str的長度為0,但是後面8-10行我們把它當成包括實際字符串長度的數組來運用,這UIran會涉及越界,但是隻要做好邊界控制就可以,其內存佈局如圖


自制編程語言2.1柔性數組

其中灰色的部分便是結構體struct sample原本的大小;

但是c標準規定不能定義0長度的數組,所以有些編譯器就把0長度的數組作為自己的非標準擴展,畢竟得民心者得天下,GCC就支持此類型數組,鑑於標準是來自用戶的合理需求,較新的C99就收錄了此標準,它使用不完整的類型來實現此需求,因此柔性數組成員被扶正了C99規定,柔性數組成員在結構體中只以符號地址的身份存在,並且一定是結構體的最後一個成員,以上結構體在C99中如下展示。

<code>struct sample{
	int length;
  char str[];
};/<code>

str數組名後[]並沒有元素個數,因此str只作為符號地址存在與結構體中,提醒一下,儘管這裡是用字符舉例,但任何類型都可以用於柔性數組成員。

over


分享到:


相關文章: