数组的sizeof

日期: 2024-10-25 07:02:06|浏览: 10|编号: 104980

友情提醒:信息内容由网友发布,请自鉴内容实用性。

数组sizeof

数组的值等于数组占用的内存字节数,如:

字符 a1[] = "abc";

int a2[3];

(a1); // 结果为4,字符末尾有NULL终止符

(a2); // 结果是3*4=12(取决于int)

有的朋友一开始以为是求数组元素的个数。现在,你应该知道这是错误的。那么应该如何找到数组元素的数量呢?很简单,通常有两种写法:

int c1 = ( a1 ) / ( int ); // 总长度/单个元素长度

int c2 = ( a1 ) / ( a1[0] ); // 总长度/第一个元素的长度

写到这里,我想问一下,下面c3和c4的值应该是多少?

无效 foo3(char a3[3])

int c3 = ( a3 ); // c3 ==

无效 foo4(char a4[])

int c4 = ( a4 ); // c4 ==

也许当您尝试回答 c4 的值时,您意识到 c3 是错误的。是的,c3!=3。这里的函数参数a3不再是数组类型,而是转化为指针,相当于char* a3。如果你仔细想一想,就不难理解其中的原因。当我们调用函数 foo1 时,程序将在堆栈上分配一个大小为 3 的数组。决不!数组是“按地址传递”,调用者只需要传递实参的地址即可,所以a3自然是指针类型(char*),而c3的值为4。

7. 结构

这是初学者最常问的问题,所以有必要在这里多花点时间。我们先看一个结构体:

S1

字符c;

整数我;

};

问(s1)等于多少,你就会开始聪明地思考。 char占1个字节,int占4个字节,所以总共应该是5个,是这样吗?你在你的机器上试过吗?也许你是对的,但很可能你是错的! VC6中默认设置得到的结果是8。

为什么受伤的总是我?

请不要沮丧,让我们考虑一下定义——结果等于对象或类型占用的内存字节数。好,我们看一下S1的内存分配情况:

S1 s1 = { 'a', };

定义完上述变量后,添加断点,运行程序,观察s1所在内存。你发现了什么?

以我的VC6.0为例,s1的地址为,其数据内容如下:

: 61 CC CC CC FF FF FF FF

我找到了为什么混入了3个字节的CC。看MSDN上的说明:

当为类型或 时,大小,可能为 的字节。

原来如此,这就是传说中的字节对齐!一个重要的话题出现了。

为什么我们需要字节对齐?计算机组成原理告诉我们,这将有助于加快计算机的访问速度,否则会占用更多的指令周期。为此,编译器会默认对结构体进行处理(其实其他地方的数据变量也是如此),使得宽度为2的基本数据类型(short等)位于能被2整除的地址处,宽度为4 基本数据类型(int等)位于能被4整除的地址处,以此类推。这样,两个数字之间可能需要添加填充字节,所以整个结构体的值就增加了。

让我们交换 S1 中 char 和 int 的位置:

S2

整数我;

字符c;

};

看看(S2)的结果。为什么还是8?然后看内存。结果发现成员c后面还有3个填充字节。这是为什么呢?别着急,下面我们来总结一下规则。

字节对齐的详细信息取决于编译器实现,但一般来说,满足三个准则:

1)结构体变量的首地址可以被其最宽的基本类型成员的大小整除;

2) 结构体各成员相对于结构体首地址的偏移量( )是成员大小的整数倍。如果需要,编译器会在成员之间添加填充字节( );

3)结构总尺寸为结构最宽基本型构件尺寸的整数倍。如有必要,编译器将在最后一个成员之后添加填充字节 ( )。

对于上述指南,有几点需要注意:

1)我们不是说过结构体成员的地址是其大小的整数倍吗?为什么我们又谈到了抵消?因为点1的存在,所以我们只能考虑成员的偏移量,这个想起来很简单。 。想想为什么。

通过宏()可以获得结构体成员相对于结构体首地址的偏移量。该宏也在.h中定义,如下:

# (s,m) ()&(((s *)0)->m)

比如想要获取c在S2中的偏移量,方法是

pos = (S2, c); // 位置等于4

2)基本类型是指前面提到的char、short、int、float等内置数据类型。这里所说的“数据宽度”是指它们的大小。由于结构体的成员可以是复合类型,例如另一个结构体,因此在寻找最宽的基本类型成员时,应该包括复合类型成员的子成员,而不是将复合成员作为一个整体来考虑。然而,在确定复合类型成员的偏移位置时,复合类型被视为一个整体。

这里描述起来有点混乱,想起来也有点混乱。我们来看一个例子(具体数值仍以VC6为例,不再解释):

S3

字符 c1;

S1s;

字符c2;

};

S1 的最宽简单成员的类型是 int。当考虑最宽的简单类型成员时,S3“分解”了S1,因此S3的最宽简单类型是int。这样,S3定义的变量存储空间的首地址需要能被4整除,整个(S3)值也应该能被4整除。

c1的偏移量为0,s的偏移量为0。此时,s是一个整体。作为结构体变量,它也满足前面三个条件,所以它的大小为8,偏移量为4。c1和s之间需要3个填充字节,但c2和s之间不需要,所以c2的偏移量为12,而c2的大小是13。13不能被4整除,所以必须加上尾数。 3 个填充字节。最后,(S3)的值为16。

由上面的描述,我们可以得到一个公式:

该结构体的大小等于最后一个成员的偏移量加上其大小加上末尾的填充字节数,即:

( ) = ( 最后一项 ) + ( 最后一项 ) + ( )

提醒:请联系我时一定说明是从浚耀商务生活网上看到的!