c语⾔中sizeof需要引⽤的头⽂件,对C语⾔中的sizeof的介绍分
析
引导语::sizeof是C语⾔中判断数据类型或者表达式长度符,以下是⼩编分享给⼤家的,欢迎阅读!
1.定义
sizeof是C/C++中的⼀个操作符***operator***,作⽤就是返回⼀个对象或者类型所占的内存字节数。返回值类型为size_t,在头⽂件stddef.h中定义。
这是⼀个依赖于编译系统的值,⼀般定义为typedef unsigned int size_t;编译器林林总总,但作为⼀个规范,都会保证char、signed
char和unsigned char的sizeof值为1,毕竟char是编程能⽤的最⼩数据类型。
MSDN上的解释为:
The sizeof keyword gives the amount of storage, in bytes, associated with avariable or a
type ***including aggregate types***. This keyword returns a value of type
size_t.
2. 语法:
sizeof有三种语法形式,如下:
1*** sizeof*** object ***; // sizeof*** 对象 ***;
2*** sizeof*** type_name ***; // sizeof*** 类型 ***;
3*** sizeof object; // sizeof 对象;
所以⼀下三种sizeof的使⽤都是对的
复制代码 代码如下:
#include
main******
{
int b;
printf***"%dn",sizeof b***;
printf***"%dn",sizeof***b******;
printf***"%dn",sizeof***int******;
}
3. 基本数据类型的sizeof
这⾥的基本数据类型指short、int、long、float、double这样的简单内置数据类型,由于它们都是和系
统相关的,所以在不同的系统下取值可能不同,这务必引起我们的注意,尽量不要在
这⽅⾯给⾃⼰程序的移植造成⿇烦。⼀般的,在32位编译环境中,sizeof***int***的’取值为4。
4. 指针变量的sizeof
等于计算机内部地址总线的宽度。所以在32位计算机中,⼀个指针变量的返回值必定是4***注意结果是以
字节为单位***,可以预计,在将来的64位系统中指针变量的sizeof结果为8。
指针变量的sizeof值与指针所指的对象没有任何关系,正是由于所有的指针变量所占内存⼤⼩相等,所以
MFC消息处理函数使⽤两个参数WPARAM、LPARAM就能传递各种复杂的消息结构***使⽤
指向结构体的指针***。
5. 数组的sizeof
数组的sizeof值等于数组所占⽤的内存字节数,如:
char a1[] = "abc";
int a2[3];
sizeof*** a1 ***; // 结果为4,字符 末尾还存在⼀个NULL终⽌符
sizeof*** a2 ***; // 结果为3*4=12***依赖于int***
sizeof当作了求数组元素的个数是不对的,求数组元素的个数有下⾯两种写法:int c1 = sizeof*** a1 ***
/ sizeof*** char ***; // 总长度/单个元素的长度
int c2 = sizeof*** a1 *** / sizeof*** a1[0] ***; // 总长度/第⼀个元素的长度.注意数组名做函数参数传递
时退化为指针。
6. 结构体的sizeof
struct S1
{
char c;
int i;
};
sizeof的结果等于对象或者类型所占的内存字节数,好吧,那就让我们来看看S1的内存分配情况:S1 s1
= { 'a', 0xFFFFFFFF };s1的地址为0x0012FF78,其数据内容如下:
0012FF78: 61 CC CC CC FF FF FF FF中间夹杂了3个字节的CC看看MSDN上的说明:When applied to a structure type or variable, sizeof returns the actual size, which may
include padding bytes inserted for alignment.
这就是字节对齐!为什么需要字节对齐计算机组成原理教导我们这样有助于加快计算机的取数速度,否则
就得多花指令周期了。为此,编译器默认会对结构体进⾏处理***实际上其它地⽅的数
据变量也是如此***,让宽度为2的基本数据类型***short等***都位于能被2整除的地址上,让宽度为4的基本
数据类型***int等***都位于能被4整除的地址上,以此类推。这样,两个数中间就可能
需要加⼊填充字节,所以整个结构体的sizeof值就增长了。
1.sizeof是运算符,跟加减乘除的性质其实是⼀样的,在编译的时候进⾏执⾏,⽽不是在运⾏时才执⾏。
那么如果编程中验证这⼀点呢?
复制代码 代码如下:
#include
using namespace std;
int main******
{
int i=1;
cout<
sizeof***++i***;
cout<
return 1;
}
输⼊结果为 1
1
sizeof 中的++i 的副作⽤并没有显⽰出来,原因只可能有⼀个,在编译的时候sizeof执⾏以后将++i 处理了,++i 的副作⽤因此被消除了。如果sizeof 是在运⾏时进⾏的话,则肯定要注意++i 。实际上sizeof的实现应该是⽤宏来做的,宏在编译时进⾏执⾏。具体实现可以参考下⾯。
2.sizeof***'a'***在C语⾔中的结果是4,在C++中结果是1,看过某篇⽂章说C中sizeof侧重于“数”,⽽C++中sizeof更侧重于“字符”。
3.⽂章中讲了两个⽤宏实现sizeof的经典应⽤
复制代码 代码如下:
//适⽤于⾮数组
#define _sizeof***T*** ******size_t*********T****0 + 1******
//适⽤于数组
#define array_sizeof***T*** ******size_t******&T+1***-***size_t******&T******
先举两个⼩例⼦说明两个宏的应⽤,对于第⼀个如 _sizeof***int***; 的结果就是4;对于第⼆个先声明⼀个⼤⼩为4的数组int a[4];那么
array_sizeof***a***结果为16.
对于⾮数组的宏定义,先是将0转换为T*类型的指针所指向的地址***此时地址为0***。然后对T类型的地址加1,相当于加上了T类型的⼤⼩***即得到了⾮数组T的⼤⼩***。前⾯的size_t只是将地址转化为int型的整数返回。
⼀个简单的例⼦:int* p; p=p+1; --------p是⼀个int*类型的指针, p+1在地址空间上相当于加上了4个字节。
对 于数组的宏定义,类似于⾮数组的宏定义,为了⽅便理解,这⾥可以把数组T看成⼀个⽤户⾃定义的类型,&T表⽰数组类型的指针,对于数组类型指针加 1相当于在地址上加上了该数组⼤⼩。由于是
⽤户⾃定义的类型所以不能强制将0转化为数组类型的地址,只能⽤加1后的地址减去之前的地址,得到的差值就是数 组本⾝所占的字节⼤⼩。
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论