在上一篇文章中,我們學習了枚舉
、位段
和聯(lián)合體
的相關(guān)內(nèi)容,在文章的末尾,我們還差了關(guān)于聯(lián)合體的存儲
問題的內(nèi)容,今天我們將學習該部分的內(nèi)容,好了,話不多說,開整?。?!
結(jié)構(gòu)體的存儲方式
結(jié)構(gòu)體
在內(nèi)存中是如何存儲的呢,是按里面的變量內(nèi)容,在內(nèi)存中的連續(xù)地址中存儲還是如何呢,我們先看以下代碼:
#include<stdio.h>
struct test
{
int a;
char b;
char c;
};
int main()
{
struct test tes;
printf("%d\n",sizeof(tes));
return 0;
}
大家猜猜結(jié)果是多少呢?是不是6
呢,又或是其他,我們編譯查看結(jié)果:
8是怎么來的呢,我們下面進行講解。
對齊原則
實際上,結(jié)構(gòu)體
在內(nèi)存中的對齊方式遵循以下的規(guī)則:
1、第一個成員在與結(jié)構(gòu)體變量偏移量為0的地址處
2、其他成員變量要對齊到某個數(shù)字(對齊數(shù))的整數(shù)倍的地址處。
3、結(jié)構(gòu)體總大小為最大對齊數(shù)(每個成員變量都有一個對齊數(shù))的整數(shù)倍
4、如果嵌套了結(jié)構(gòu)體的情況,嵌套的結(jié)構(gòu)體對齊到自己的最大對齊數(shù)的整數(shù)倍處,結(jié)構(gòu)體的整體大小就是所有最大對齊數(shù)(含嵌套結(jié)構(gòu)體的對齊數(shù))的整數(shù)倍,
對齊數(shù)
在上述的第二條原則中,我們提到了對齊數(shù)
的概念,所謂的的對齊數(shù):
對齊數(shù)=編譯器默認的一個對齊數(shù)與該成員大小的較小值
也就是在不同的編譯器中,對齊數(shù)是不太一樣的,以vscode為例,其默認對齊數(shù)為8;
在了解了對齊原則和對齊數(shù)之后,我們再分析上述代碼的結(jié)果8
是如何得到的,分析過程如下圖,圖中標注較為清晰,不再贅述:
上述代碼是在結(jié)構(gòu)體中先定義
了1個整型,然后定義兩個字符變量,如果先定義兩個字符變量再定義整型變量
結(jié)果會不會有區(qū)別呢,代碼如下:
#include<stdio.h>
struct test
{
char b;
char c;
int a;
};
int main()
{
struct test tes;
printf("%d\n",sizeof(tes));
return 0;
}
編譯結(jié)果如下:
可以發(fā)現(xiàn)結(jié)果仍為
8,不在此處進行分析,我們分析最后一種情況:定義一個字符變量、然后定義整型,然后再定義字符變量,代碼如下:
#include<stdio.h>
struct test
{
char b;
char c;
int a;
};
int main()
{
struct test tes;
printf("%d\n",sizeof(tes));
return 0;
}
2023/07/04 修改:上述代碼應該為:
#include<stdio.h>
struct test
{
char b;
int a;
char c;
};
int main()
{
struct test tes;
printf("%d\n",sizeof(tes));
return 0;
}
我們先分析,然后查看結(jié)果,分析過程如下:
我們查看結(jié)果,發(fā)現(xiàn)確實為12個字節(jié)
通過上述兩道題目的分析,我想你一定掌握了結(jié)構(gòu)體在內(nèi)存中的存放方式,此外我們也發(fā)現(xiàn)一個問題:
定義相同內(nèi)容的結(jié)構(gòu)體,定義的順序不同,占用的空間大小也不同。
因此在定義結(jié)構(gòu)體時,如何定義最好呢,我們推薦:
變量大小中,成員較小的放在前面定義,大小中較大的放在后面定義
因為這樣可以節(jié)省內(nèi)存空間
。
聯(lián)合體的大小
昨天沒有講解聯(lián)合體
的大小是因為該部分內(nèi)容涉及到對齊數(shù)
的知識,今天可以講解了,聯(lián)合體的大小遵循以下的原則:
1、聯(lián)合體的大小至少為整個內(nèi)容中最大的變量的大小
;2、當最大成員大小不是最大對齊數(shù)的整數(shù)倍的時候,就要對齊到最大對齊數(shù)的整數(shù)倍。
我們使用以下代碼查看聯(lián)合體的大?。?/p>
#include<stdio.h>
union test
{
int a ;
char b;
char c[20];
};
int main()
{
union test tes;
printf("%d\n",sizeof(tes));
return 0;
}
聯(lián)合體中,對齊數(shù)
分別為4 1 1 ,因此最大對齊數(shù)為4,聯(lián)合體中的最大大小為20
,也是最大對齊數(shù)4的倍數(shù)
,因此結(jié)果應該為20,
查看結(jié)果:
可以看到大小為20個字節(jié),并不是 4+1+20 = 25字節(jié),我們將c的改為3字節(jié),再查看結(jié)果
這個就交給大家自行分析嘍。文章來源:http://www.zghlxwxcb.cn/news/detail-518444.html
上述內(nèi)容即使今天的全部內(nèi)容了,感謝大家的觀看。
如果方便,辛苦大家點個贊和關(guān)注哦!
您的點贊或評論或關(guān)注是對我最大的肯定,謝謝大家!?。?span toymoban-style="hidden">文章來源地址http://www.zghlxwxcb.cn/news/detail-518444.html
到了這里,關(guān)于C語言學習(三十一)---結(jié)構(gòu)體、聯(lián)合體的在內(nèi)存中的存儲的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!