這種求結(jié)構(gòu)體成員大小的方法你可能還沒掌握~
掃描二維碼
隨時隨地手機看文章
在C語言編程中,有時候需要知道某結(jié)構(gòu)體中某成員的大小,比如使用堆內(nèi)存來存儲結(jié)構(gòu)體中的某成員時,需要知道該成員的大小,才好確定所需申請的空間大小。
求某結(jié)構(gòu)體中某成員的大小,你會怎么做?
例子:
typedef struct
{
char a;
char c;
short b;
int d;
char e;
}test_struct;
求 d 成員所占內(nèi)存空間的大小。
方法一
我們可以先定義一個結(jié)構(gòu)體變量,然后再使用sizeof求出。
左右滑動查看全部代碼>>>
#include <stdio.h>
typedef struct
{
char a;
char c;
short b;
int d;
char e;
}test_struct;
int main(void)
{
test_struct test_s;
printf("sizeof(test_s.d) = %d\n", sizeof(test_s.d));
return 0;
}
運行結(jié)果:
但是我們?yōu)榱说玫揭粋€成員的大小,而專門定義一個結(jié)構(gòu)體變量,而這個變量也沒有其它的用途,有點浪費資源,或者說這種方法low了。
方法二
肉眼觀察法。。。。。
比如在32bit環(huán)境下,我們一眼看出d是int類型,就是4個字節(jié)。然后想咋用就咋用。這個簡單就不討論了。
方法三
裝逼法。。。
代碼:
左右滑動查看全部代碼>>>
#include <stdio.h>
typedef struct
{
char a;
char c;
short b;
int d;
char e;
}test_struct;
int main(void)
{
printf("sizeof(((test_struct*)0)->d) = %d\n", sizeof(((test_struct*)0)->d));
printf("sizeof(((test_struct*)0)->a) = %d\n", sizeof(((test_struct*)0)->a));
printf("sizeof(((test_struct*)0)->b) = %d\n", sizeof(((test_struct*)0)->b));
printf("sizeof(((test_struct*)0)->c) = %d\n", sizeof(((test_struct*)0)->c));
return 0;
}
運行結(jié)果:
類似((test_struct*)0)->d這樣的用法是個固定用法,把0地址轉(zhuǎn)換為test_struct結(jié)構(gòu)的指針,對于結(jié)構(gòu)體指針,使用->符號就是取其成員,再使用sizeof就可以求得其大小。
這里不一定是0地址,其它地址也可以,但一般都會使用0地址。這種方法較方法一的好處就是不用定義一個多余的變量。
這種方法很重要,需要掌握,可能你平時編程不會使用這種方法,但這種方法很重要。在很多優(yōu)秀的代碼中會出現(xiàn)類似形式的宏代碼,例如:
上例可封裝一個宏定義:
左右滑動查看全部代碼>>>
#define MEM_SIZE(type, member) sizeof(((type*)0)->member)
求某成員在結(jié)構(gòu)體中的偏移量:
左右滑動查看全部代碼>>>
#define OFFSETOF(type, member) ( (size_t)( &( ( (type*)0 )->member ) ) )
求結(jié)構(gòu)體偏移量在C語言頭文件中stddef.h也有提供,使用方法如:
左右滑動查看全部代碼>>>
#include <stdio.h>
#include <stddef.h>
#define OFFSETOF(type, member) ( (size_t)( &( ( (type*)0 )->member ) ) )
typedef struct
{
char a;
char c;
short b;
int d;
char e;
}test_struct;
int main(void)
{
/* stddef.h宏 */
printf("offset(a): %d\n", offsetof(test_struct, a));
printf("offset(c): %d\n", offsetof(test_struct, c));
printf("offset(b): %d\n", offsetof(test_struct, b));
printf("offset(d): %d\n", offsetof(test_struct, d));
printf("offset(e): %d\n", offsetof(test_struct, e));
/* 自定義宏 */
printf("OFFSETOF(a): %d\n", OFFSETOF(test_struct, a));
printf("OFFSETOF(c): %d\n", OFFSETOF(test_struct, c));
printf("OFFSETOF(b): %d\n", OFFSETOF(test_struct, b));
printf("OFFSETOF(d): %d\n", OFFSETOF(test_struct, d));
printf("OFFSETOF(e): %d\n", OFFSETOF(test_struct, e));
return 0;
}
運行結(jié)果:
使用這個求結(jié)構(gòu)體偏移量的宏我們就可以很好地知道結(jié)構(gòu)體成員的在內(nèi)存中的存儲情況。關(guān)于結(jié)構(gòu)體內(nèi)存對齊,可移步至往期筆記:結(jié)構(gòu)體內(nèi)存對齊你真的弄懂了?
以上就是本次分享的求結(jié)構(gòu)體成員的三種方法。重點掌握方法三,因為在很多優(yōu)秀的代碼中都有使用到類似的方法。
猜你喜歡
為了便于公眾號讀者交流學(xué)習(xí),小編創(chuàng)建了相關(guān)相關(guān)交流群??游挥邢蓿信d趣的朋友可以掃碼下方二維碼加我微信,由我邀請入群:
歡迎大家進(jìn)群交流、共同進(jìn)步。同時,我也會關(guān)注一些大家問的一些問題,從中挑選一些具有代表性的、并且在我知識范圍內(nèi)的問題寫出相關(guān)文章做分享。
免責(zé)聲明:本文內(nèi)容由21ic獲得授權(quán)后發(fā)布,版權(quán)歸原作者所有,本平臺僅提供信息存儲服務(wù)。文章僅代表作者個人觀點,不代表本平臺立場,如有問題,請聯(lián)系我們,謝謝!





