内射老阿姨1区2区3区4区_久久精品人人做人人爽电影蜜月_久久国产精品亚洲77777_99精品又大又爽又粗少妇毛片

C語言結(jié)構(gòu)體內(nèi)存對齊和offsetof宏、container-創(chuàng)新互聯(lián)

1.結(jié)構(gòu)體變量中的元素如何訪問

(1)數(shù)組中元素的訪問方式:表面上有2種方式(數(shù)組下標方式和指針方式);實質(zhì)上都是指針方式訪問。
(2)結(jié)構(gòu)體變量中的元素訪問方式:只有一種,用.或者->的方式來訪問。
(C語言規(guī)定用結(jié)構(gòu)體變量來訪問元素用. 用結(jié)構(gòu)體變量的指針來訪問元素用->。)

創(chuàng)新互聯(lián)長期為上千家客戶提供的網(wǎng)站建設服務,團隊從業(yè)經(jīng)驗10年,關(guān)注不同地域、不同群體,并針對不同對象提供差異化的產(chǎn)品和服務;打造開放共贏平臺,與合作伙伴共同營造健康的互聯(lián)網(wǎng)生態(tài)環(huán)境。為濱海企業(yè)提供專業(yè)的網(wǎng)站制作、成都網(wǎng)站設計,濱海網(wǎng)站改版等技術(shù)服務。擁有10余年豐富建站經(jīng)驗和眾多成功案例,為您定制開發(fā)。2.結(jié)構(gòu)體的對齊訪問

總結(jié)下:結(jié)構(gòu)體對齊的分析要點和關(guān)鍵:
1、結(jié)構(gòu)體對齊要考慮:結(jié)構(gòu)體整體本身必須安置在4字節(jié)對齊處,結(jié)構(gòu)體對齊后的大小必須4的倍數(shù)(編譯器設置為4字節(jié)對齊時,如果編譯器設置為8字節(jié)對齊,則這里的4是8)
2、結(jié)構(gòu)體中每個元素本身都必須對其存放,而每個元素本身都有自己的對齊規(guī)則。
3、編譯器考慮結(jié)構(gòu)體存放時,以滿足以上2點要求的最少內(nèi)存需要的排布來算。

gcc支持但不推薦的對齊指令:#pragma pack() #pragma pack(n) (n=1/2/4/8)

我們需要#prgama pack(n)開頭,以#pragma pack()結(jié)尾,定義一個區(qū)間,這個區(qū)間內(nèi)的對齊參數(shù)就是n。

#pragma pack(1)
struct mystruct
{short d;
	int b;
	char a;
};
#pragma pack()
gcc推薦的對齊指令__attribute__((packed)) attribute((aligned(n)))

(1)__attribute__((packed))使用時直接放在要進行內(nèi)存對齊的類型定義的后面,然后它起作用的范圍只有加了這個東西的這一個類型。packed的作用就是取消對齊訪問。

struct mystruct
{short d;
	int b;
	char a;
}__attribute__((packed));

(2)__attribute__((aligned(n)))使用時直接放在要進行內(nèi)存對齊的類型定義的后面,然后它起作用的范圍只有加了這個東西的這一個類型。它的作用是讓整個結(jié)構(gòu)體變量整體進行n字節(jié)對齊(注意是結(jié)構(gòu)體變量整體n字節(jié)對齊,而不是結(jié)構(gòu)體內(nèi)各元素也要n字節(jié)對齊)

struct mystruct
{short d;
	int b;
	char a;
}__attribute__((aligned(16)));

參考閱讀blog:
結(jié)構(gòu)體字節(jié)對齊參考博客

GCC___attribute__關(guān)鍵字和字節(jié)對齊

3.offsetof宏

(1)offsetof宏的作用是:用宏來計算結(jié)構(gòu)體中某個元素和結(jié)構(gòu)體首地址的偏移量(其實質(zhì)是通過編譯器來幫我們計算)。
(2)offsetof宏的原理:我們虛擬一個type類型結(jié)構(gòu)體變量,然后用type.member的方式來訪問那個member元素,繼而得到member相對于整個變量首地址的偏移量。

// TYPE是結(jié)構(gòu)體類型,MEMBER是結(jié)構(gòu)體中一個元素的元素名
// 這個宏返回的是member元素相對于整個結(jié)構(gòu)體變量的首地址的偏移量,類型是int
#define offsetof(TYPE, MEMBER) ((int) &((TYPE *)0)->MEMBER)

(TYPE *)0這是一個強制類型轉(zhuǎn)換,把0地址強制類型轉(zhuǎn)換成一個指針,這個指針指向一個TYPE類型的結(jié)構(gòu)體變量。 (實際上這個結(jié)構(gòu)體變量可能不存在,但是只要我不去解引用這個指針就不會出錯)。
((TYPE *)0)->MEMBER (TYPE *)0是一個TYPE類型結(jié)構(gòu)體變量的指針,通過指針指針來訪問這個結(jié)構(gòu)體變量的member元素

&((TYPE *)0)->MEMBER等效于&(((TYPE *)0)->MEMBER),意義就是得到member元素的地址。但是因為整個結(jié)構(gòu)體變量的首地址是0,

4.container_of宏
// TYPE是結(jié)構(gòu)體類型,MEMBER是結(jié)構(gòu)體中一個元素的元素名
// 這個宏返回的是member元素相對于整個結(jié)構(gòu)體變量的首地址的偏移量,類型是int
#define offsetof(TYPE, MEMBER) ((int) &((TYPE *)0)->MEMBER)

// ptr是指向結(jié)構(gòu)體元素member的指針,type是結(jié)構(gòu)體類型,member是結(jié)構(gòu)體中一個元素的元素名
// 這個宏返回的就是指向整個結(jié)構(gòu)體變量的指針,類型是(type *)
#define container_of(ptr, type, member) ({	\
	const typeof(((type *)0)->member) * __mptr = (ptr);	\
	(type *)((char *)__mptr - offsetof(type, member)); })

(1)作用:知道一個結(jié)構(gòu)體中某個元素的指針,反推這個結(jié)構(gòu)體變量的指針。有了container_of宏,我們可以從一個元素的指針得到整個結(jié)構(gòu)體變量的指針,繼而得到結(jié)構(gòu)體中其他元素的指針。
(2)typeof關(guān)鍵字的作用是:typepef(a)時由變量a得到a的類型,typeof就是由變量名得到變量數(shù)據(jù)類型的。
(3)這個宏的工作原理:先用typeof得到member元素的類型定義成一個指針,然后用這個指針減去該元素相對于整個結(jié)構(gòu)體變量的偏移量(偏移量用offsetof宏得到的),減去之后得到的就是整個結(jié)構(gòu)體變量的首地址了,再把這個地址強制類型轉(zhuǎn)換為type *即可。

struct mystruct
{short d;
	int b;
	char a;
};

int main(void)
{struct mystruct s1;
	struct mystruct *ps = NULL;
	int *p = &(s1.a);
	
	printf("s1 = %p.\n", &s1);
	
	ps = container_of(p, struct mystruct, a);
	
	printf("ps = %p.\n", ps);
	
	return 0;
}

知道一個結(jié)構(gòu)體中a元素的指針,反推這個結(jié)構(gòu)體變量的指針。
結(jié)果為:
s1 = 0x7ffd8cd5d2fc. ps = 0x7ffd8cd5d2fc.

你是否還在尋找穩(wěn)定的海外服務器提供商?創(chuàng)新互聯(lián)www.cdcxhl.cn海外機房具備T級流量清洗系統(tǒng)配攻擊溯源,準確流量調(diào)度確保服務器高可用性,企業(yè)級服務器適合批量采購,新人活動首月15元起,快前往官網(wǎng)查看詳情吧

網(wǎng)頁標題:C語言結(jié)構(gòu)體內(nèi)存對齊和offsetof宏、container-創(chuàng)新互聯(lián)
當前地址:http://m.rwnh.cn/article22/cedgjc.html

成都網(wǎng)站建設公司_創(chuàng)新互聯(lián),為您提供手機網(wǎng)站建設、服務器托管網(wǎng)站策劃、網(wǎng)站設計ChatGPT、網(wǎng)站改版

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)

搜索引擎優(yōu)化
东乡| 格尔木市| 东丽区| 贡觉县| 昌平区| 蕉岭县| 望城县| 秀山| 外汇| 金沙县| 松滋市| 扎兰屯市| 泽库县| 克什克腾旗| 驻马店市| 温泉县| 宜章县| 全州县| 炉霍县| 咸丰县| 定州市| 吉林省| 托里县| 华阴市| 卢氏县| 土默特左旗| 哈巴河县| 渭南市| 营山县| 揭西县| 大连市| 颍上县| 阿坝| 双桥区| 鄂温| 灵寿县| 禄劝| 涡阳县| 湘乡市| 沙坪坝区| 商都县|