您的位置:主页 > 技术请教 > 综合新闻

sizeof进行结构体大小的判断

发布时间:2018-04-16 12:07  浏览:

typedef struct
{
int a;
char b;
}A_t;
typedef struct
{
int a;
char b;
char c;
}B_t;
typedef struct
{
char a;
int b;
char c;
}C_t;
void main()
{
char*a=0;
cout<cout<cout<cout<cout<}
为什么会是那样地的的水果呢?


2. 态度:
sizeof有三种态度塑造,如次:
1) sizeof( object ); // sizeof( 不赞成 );
2) sizeof( type_name ); // sizeof( 典型 );
3) sizeof object; // sizeof 不赞成;

5. 手变量的sizeof
鉴于它在这时贮藏地址,过后,合理地,它使相当本质上的地址打杂工的宽度。。因而在32位计算图表中,一

手变量的重提值得是4(以八位位组为单位)。,可以意图,将来的的64位体系

中手变量的sizeof水果为8。
char* pc = "abc";
int* pi;
string* ps;
char** ppc = &pc;
void PF) 有或起作用手
sizeof( pc ); // 水果是4。
sizeof( pi ); // 水果是4。
sizeof( ps ); // 水果是4。
sizeof( ppc ); // 水果是4。
sizeof( pf );// 水果是4。
手变量的sizeof值与手意味的不赞成无稍微相干,它是接受手变量的内存。

体积相当,因而,MFC音讯处置有或起作用运用两决定因素wParam、lParam可以做准备杂多的复杂的人杂种

建筑物(运用要点建筑物的手)。

6. 限制的sizeof
限制的sizeof值使相当限制所使从事内存八位位组的号码,如:
char a1[] = "abc";
int A2 [ 3 ]
sizeof( a1 ); // 水果是4。,在字母串的终结仍每一空结果符。
sizeof( a2 ); // 水果是3×4=12(不求再进int)。
某个陪伴起飞时把sizeof作为了求限制元素的号码,现时,你得意识这是错的,那

我们的得健康状况方法找到限制元素的合计?轻易的,通常有两种使安定办法。:
int c1 = sizeof( a1 ) / sizeof( char ); // 奇特的事物元素的总巨大/巨大的巨大。
int c2 = sizeof( a1 ) / sizeof( A1 [ 0 ] ); // 根本的元素总巨大/巨大的巨大。
把它写在这时,提一问,上面的C3,C4值得是差不多?
void foo3(char A3 [ 3 ]
{
int c3 = sizeof( a3 ); // c3 ==
}
void foo4(char a4[])
{
int c4 = sizeof( a4 ); // c4 ==
}
或许当你触球答复c4的值时曾经看法到c3答错了,是的,c3!=3。这时的有或起作用决定因素A3不再是

限制典型,而挑剔变为每一手,当量的焦 a3,为什么?不难去想它。,我们的的受话器

功用婚配foo1工夫,顺序会在堆栈上分派3个限制吗?不!限制是地址,使转移者

把过来提到的地址传过来。,因而A3合理地是手典型(char),C3的值是4。。

7. 建筑物体的sizeof
这是初学者最常问的成绩经过。,因而这时有很多钢笔和书本知识是要素的。。让我们的先看一眼建筑物:

struct S1
{
char c;
int i;
};
问sizeof(s1)使相当差不多?光泽度的你开端深思了,char占1八位位组。,int理由为4八位位组,那样地的累积而成

得是5。真的那样地吗?你在你的机具上缓刑过吗?或许你是对的。,但很能够你错了!V

C6中默许设置的水果是8。。
为什么?为什么我永远负伤?
请不要排粪,我们的来好好光泽剂一下sizeof的限界——sizeof的水果使相当不赞成或许典型所占

内存八位位组的号码,好吧,让我们的看一眼S1的内存分派:
S1 s1 = {  a , 0xFFFFFFFF };
在限界了上述的变量后来,添加每一断点,运转顺序,环顾S1产地的内存。,你找到了什么?
以我的判例,地址是0x0012ff78 S1,最高纪录的达到如次:
0012FF78: 61 CC CC CC FF FF FF FF
你找到了什么?方法混合3八位位组的cc在正切中要害?看一眼机构:
When applied to a structure type or variable, sizeof returns the actual size,

which may include padding bytes inserted for 不相容的。
在前的那样地,这是引渡切中要害八位位组不相容的。!每一要紧的话锋呈现了。。
为什么需求八位位组不相容的?计算图表结合规律指导我们的那样地的有助于放慢计算图表的取数昌盛,若非

你得花更多的讲授圆状物。。为了这事目标的,编辑者将默许处置这事建筑物(说起来,最高纪录变换了

异样是同样地的。,根本最高纪录典型(短,等)宽度为2谎言海报上。,让宽

4(int等)的根本最高纪录典型谎言每一可认为d的地址上。,如此等等。那样地的,在两号码字正切中要害

您能够需求添加填电荷八位位组。,因而总计达建筑物体的sizeof值就增长了。
让我们的在S1中互通式立体交叉char和int的得名次。:
struct S2
{
int i;
char c;
};
看一眼sizeof(S2)的水果为差不多,为什么依然是8?再看一遍牢记,在前的的身体部位C依然有3个淤塞词

节,那是为什么?别担心这事了。,总结了以下规矩。

八位位组不相容的项目和编辑者造成,但通常,适合三项基准:
1) 建筑物变量的第每一地址可以经过它的体积排除。;
2) 建筑物体每个身体部位相在附近的建筑物体首地址的偏移量(offset)都是身体部位体积的概数倍,如有

编辑者需求在身体部位暗中添加填电荷八位位组(本质上的)。 添加);
3) 建筑物的总体积是最大量的的概数倍。,假使有需求,编辑者将在极限的。

在每一身体部位后来,添加填电荷八位位组(影子 p添加)。
在附近的上述的基准,有几点需求解说。:
1) 并挑剔说建筑物的每一身体部位的地址是概数m。,你怎地再谈反抗性的?鉴于仍一秒钟

1点的在,因而我们的要不是思索身体部位的偏移量。,这是轻易忆及的。。想想为什么。
建筑物体某个身体部位相在附近的建筑物体首地址的偏移量可以经过宏offsetof()来赢得,这事宏也在

中间物的限界,如次:
#define offsetof(s,m) (size_t)&(((s *)0)->m)
拿 ... 来说,想受理S2中C的偏移量,办法为
size_t pos = offsetof(S2, c);// POS使相当4
2) 根本典型是指前面提到的相似char。、short、int、float、内置最高纪录典型,如双,

这时所说的“最高纪录宽度”执意指其sizeof的体积。鉴于建筑物的身体部位可以是复合典型的。,比

作为另每一建筑物,因而,当找寻最广为流传地的根本典型的身体部位时,一种复合典型身体部位的亚段应包含,

而挑剔把复合身体部位名声每一全部。除了,当决定复合典型身体部位的偏移得名次时,它是

作为全部处理。
这时叙述的是有一点儿疼痛。,深思短距离猛力地。,让我们的设法这事判例(详细的值依然是vc。

以6为例,后来弱解说了。:
struct S3
{
char c1;
S1 s;
char c2
};
S1最简略的身体部位的典型是int。,S3看S1时最广为流传地和简略典型的困难,因而

S3中最广为流传地和最简略的典型是int。,那样地的,S3限界的变量,它的贮藏空隙的第每一地址需求除号4。,整

个sizeof(S3)的值也得被4精确除法。
C1的偏移量是0。,S的偏移量是差不多?在这有一点儿上,S是每一全部。,它还达到了前三个基准作为建筑物变量。

,按大小排列是8,偏移量为4。,在C1和s暗中需求3个填电荷八位位组。,在C2和S暗中无要素。,

因而C2的偏移量是12。,C2的体积是13。,13不克不及除号4。,3在终结处包装材料

电荷八位位组。极限的受理sizeof(S3)的值为16。
经过在上文中叙述,我们的可以受理每一方案:
建筑物体的体积使相当极限的每一身体部位的偏移量补充其体积再补充末了的填电荷八位位组数量,即:

sizeof( struct ) = offsetof( last item ) + sizeof( last item ) + sizeof( trail

ing padding )

到这时,陪伴们得对建筑物体的sizeof受胎每一完全新的的看法,除了不要太喜悦为时过早。,有每一

效果sizeof的要紧参数还未被注重到,这是编辑者的包讲授。。它用于修补建筑物的不相容的方法。

方法的,差别的解释和轻蔑地差别的编辑者,经过# VC6编制 包的造成,它也可以坦率地修正。

ZP编辑者出轨。#pragma 包的根本用法是:#pragma pack( n ),n是八位位组不相容的数。,其取值

为1、2、4、8、16,默许值是8。,假使这事值比建筑物体身体部位的sizeof值小,过后身体部位的偏移量

合计得因为这事值。,即是说,建筑物构件的偏移量必然要两个最少的。,方案如次:
offsetof( item ) = min( n, sizeof( item ) )
再看一遍判例:
#pragma 打包(推) // 设置目前包堆栈以拿住堆栈
#pragma 包(2) 得在限界建筑物从前运用。
struct S1
{
char c;
int i;
};
struct S3
{
char c1;
S1 s;
char c2
};
#pragma 包装(POP) // 回复先前的包设置
计算sizeof(S1)时,min(2, sizeof(i))的值为2,因而我的偏移量是2。,补充sizeof(i)使相当

6,可除号2,因而总计达S1的体积是6。。
异样,在附近的sizeof(S3),s的偏移量是2。,C2的偏移量是8。,补充sizeof(c2)使相当9,不克不及运用

2分,添加每一填电荷八位位组,因而sizeof(S3)使相当10。
现时,陪伴可以吸疼痛气,

仍一件事要注重,空建筑物(无最高纪录身体部位)的体积挑剔0。,但1。想每一不

空隙变量是方法被采用的、方法区别这两种差别的空建筑物变量呢?,“

空建筑物的变量也得贮藏。,那样地的编辑者也就要不是为其分派每一八位位组的空隙用于占位了。

如次:
struct S5 { };
sizeof( S5 ); // 水果是1。

8. 含位域建筑物体的sizeof
先前某个人说过。,位域身体部位不克不及独自被取sizeof值,这时我们的要议论的是每一具有位域的建筑物。

的sizeof,它是专为其独特的而列出的。。
C99委派int、unsigned 整数和乔治英国数学家和逻辑学家可作为位域典型,除了编辑者曾经连续的长时间了差不多接受的编辑者。,允

对立面典型的在。
运用位的首要目标的是紧缩贮藏。,它的普通规矩是:
1) 假使毗连担任守队队员担任守队队员的典型胜任的,且其位宽积和决不典型的sizeof体积,前面的担任守队队员将是

在前每一担任守队队员的侧面,直到它不克不及使适应;
2) 假使毗连担任守队队员担任守队队员的典型胜任的,但其位宽积和大于典型的sizeof体积,前面的担任守队队员将是

重复的贮藏单元开端,它的偏移量是其典型的概数倍。;
3) 假使毗连担任守队队员担任守队队员的典型差别,编辑者的详细造成是差别的。,VC6以紧缩的方法

,Dev-C 以紧缩办法;
4) 假使担任守队队员担任守队队员与非域担任守队队员一齐伸开。,它不紧缩。;
5) 总计达建筑物的总体积是体积的概数倍。。

让我们的设法这事判例。。
示例1:
struct BF1
{
char f1 : 3;
char f2 : 4;
char f3 : 5;
};
它的内存规划是:
|_f1__|__f2__|_|____f3___|____|
|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|
0 3   7 8   1316
位典型是char。,第每一八位位组要不是拿住f1和F2。,因而F2被紧缩成第每一八位位组。,F3要不是

从下每一八位位组开端。因而sizeof(BF1)的水果为2。
示例2:
struct BF2
{
char f1 : 3;
short f2 : 4;
char f3 : 5;
};
鉴于毗连区域的差别典型,在VC6中其sizeof为6,在c 中,2。
示例3:
struct BF3
{
char f1 : 3;
char f2;
char f3 : 5;
};
非域担任守队队员在里面的织进。,弱发生紧缩。,两VC6和Dev-C 的体积为3。

9. 小型伴舞乐队的sizeof
这种建筑物在内存安排中是订购的。,财团是堆叠的。,身体部位共享长内存,因而总计达衔接

合体的sizeof也执意每个身体部位sizeof的最大量的。建筑物的身体部位也可以是复合典型的。,这时,

复合典型身体部位被认为每一全部。。
因而,在上面的判例中,U的sizeof值使相当sizeof(s)。
union U
{
int i;
char c;
S1 s;
};

本文地址:https://www.48zhe.com/jsqj/1554.html
上一篇:上一篇:sizeof进行结构体大小的判断
下一篇:下一篇:没有了

无相关信息
Copyright © 2016-2017 bodog - bodog博狗 - 博狗 版权所有 地址: