C語言數(shù)據(jù)起始地址對齊方式(續(xù))

開篇廢話

這幾天一直忙著積累知識,還沒有來得及總結(jié)呢,前些日子講述了一種在C語言環(huán)境中設(shè)置數(shù)組的對齊的方式,但是那個方式的演示是在IAR 的編程環(huán)境中給予支持的,對于icf文件(連接文件)在gcc中叫做ld文件,很多人都沒有接觸過,更不知道如何去設(shè)置段的方式進(jìn)行對齊。

正篇

還是上篇中講述的那個需求,在最近的某個月黑風(fēng)高的夜晚,睡覺之前的我突發(fā)奇想,想到一種另類的解決辦法,也就是套用結(jié)構(gòu)體的辦法去實現(xiàn)數(shù)組的首地址對齊方式。

需求:實現(xiàn)一個大數(shù)組 array_a[3874]的首地址在一個4字節(jié)或者8字節(jié)對齊的地址上。

首先,構(gòu)造一個簡單的結(jié)構(gòu)體:

struct test
{
    char a[3874];
    int  b ;
};

使用C99/C++中支持的靜態(tài)初始化結(jié)構(gòu)體的辦法進(jìn)行賦值:

static struct test test1 = {
    .a[3874] = {1,2,3,4...},      //C++   C99以上才支持這種賦值方式。
};

這樣子定義的數(shù)組a[3874]的首地址就是位于一個4字節(jié)對齊的地址上的。

如果要8字節(jié)對齊呢?將結(jié)構(gòu)體改為如下,初始化的方式同上即可。

struct test
{
    char a[3874];
    double b ;
};

為啥這樣子就可以了呢?
是這樣子的:

解釋如下

這里使用了一種結(jié)構(gòu)體字節(jié)對齊來解決了數(shù)組首地址對齊的問題:因為結(jié)構(gòu)體字節(jié)對齊滿足三個準(zhǔn)則

引用自cnblogs上一位大神(clover_toeic)的博客 文章名為《C語言字節(jié)對齊問題詳解
》這里不便提供具體鏈接,感興趣的朋友自行百度。

  1. 結(jié)構(gòu)體變量的首地址能夠被最寬基本類型成員大小所整除;
  2. 結(jié)構(gòu)體每個成員相對于結(jié)構(gòu)體首地址的偏移量(offset)都是成員大小的的整數(shù)倍,如有需要編譯器會在成員之間加上填充字節(jié);
  3. 結(jié)構(gòu)體的總大小為結(jié)構(gòu)體最寬基本類型成員大小的整數(shù)倍,如有需要,編譯器會在最末一個成員加上填充字節(jié);

上述解決辦法正是使用了第一個原則,比如第二個結(jié)構(gòu)體中:

struct test 
{
    char a[3874];
    double b ;
};

可以看出該結(jié)構(gòu)體中最寬的基本類型成員是double,在32位機器中占用64bit也就是8Byte,所以我們的結(jié)構(gòu)體首部地址存在于一個8Byte對齊的地址上,而成員中的第一個 char a[3874],正好是從結(jié)構(gòu)體中首地址開始占用的,a[0]的地址就是結(jié)構(gòu)體的首地址;

總結(jié),此方法優(yōu)于之前提出的在鏈接文件中劃分塊的方式進(jìn)行對齊,因為這種方式不依賴編譯器,是一種通用的方法。

感謝

如果我的文章有哪里有錯的地方,勞煩讀者指出哈。如果覺得我的文章對您有用,那就麻煩回復(fù)我一下,表示有用。如果確實很有用,就請點一個喜歡,謝謝啦。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容