C语言函数sizeof
详细说明了sizeof的用法,很全! sizeof是C语言的一种单目操作符,如C语言的其他操作符++、--等。它并不是函数。sizeof操作符以字节形式给出了其操作数的存储大小。操作数可以是一个表达式或括在括号内的类型名。操作数的存储大小由操作数的类型决定。 二、sizeof的使用方法 1、用于数据类型 sizeof使用形式:sizeof(type) 数据类型必须用括号括住。如sizeof(int)。 2、用于变量 sizeof使用形式:sizeof(var_name)或sizeof var_name 变量名可以不用括号括住。如sizeof (var_name),sizeof var_name等都是正确形式。带括号的用法更普遍,大多数程序员采用这种形式。 注意:sizeof操作符不能用于函数类型,不完全类型或位字段。不完全类型指具有未知存储大小的数据类型,如未知存储大小的数组类型、未知内容的结构或联合类型、void类型等。 如sizeof(max)若此时变量max定义为int max(),sizeof(char_v) 若此时char_v定义为char char_v [MAX]且MAX未知,sizeof(void)都不是正确形式。 ### C语言中的`sizeof`操作符详解 #### 一、`sizeof`操作符的基本概念 `sizeof`是C语言中的一个单目操作符,用来获取指定类型或变量的存储大小,通常以字节为单位。它并非是一个真正的函数,而是一种特殊的语法结构。 #### 二、`sizeof`的操作数 `sizeof`操作符可以接受以下几种形式的操作数: 1. **数据类型**: - 使用形式:`sizeof(type)`。 - 数据类型必须用括号括起来。例如:`sizeof(int)`。 2. **变量**: - 使用形式:`sizeof(var_name)` 或 `sizeof var_name`。 - 变量名可以不使用括号括起来,例如:`sizeof(var_name)` 和 `sizeof var_name` 都是正确的形式。但是,为了保持代码的可读性和一致性,建议始终使用括号。 #### 三、注意事项 `sizeof`操作符有一些特定的限制: - **不适用于函数类型、不完全类型或位字段**。 - 不完全类型是指那些具有未知存储大小的数据类型,比如未知大小的数组类型、未知内容的结构体或联合类型、`void`类型等。 - 下面是一些错误的例子: - `sizeof(max)`,如果变量`max`被定义为`int max();` - `sizeof(char_v)`,如果`char_v`被定义为`char char_v[MAX];`且`MAX`未知。 - `sizeof(void)`。 #### 四、`sizeof`返回值的类型 `sizeof`操作符的结果是一个无符号整型数值,具体来说是`size_t`类型,这个类型由`<stddef.h>`头文件定义。`size_t`通常是`unsigned int`的同义词,并且确保结果能够表示任何对象的大小。 #### 五、基本类型的大小 根据ANSI C标准,各种基本类型的标准大小如下: - `char`, `unsigned char`, `signed char`: 1字节 - `int`, `unsigned int`, `short int`, `unsigned short`: 至少2字节 - `long int`, `unsigned long`, `float`: 至少4字节 - `double`, `long double`: 至少8字节 具体实现可能会有所不同,例如,在Microsoft C/C++ 7.0版本中: - `near`指针:2字节 - `far`/`huge`指针:4字节 - 在Unix系统中,指针通常是4字节。 #### 六、结构体与联合体中的`sizeof` 对于结构体或联合体,`sizeof`操作符的计算规则更为复杂。它不仅要考虑每个成员的大小,还要考虑对齐的要求。 1. **结构体成员对齐**: - 每个成员都必须按照某种对齐方式来存放,即成员的地址相对于结构体首地址的偏移量必须是该成员类型大小的整数倍。 - 结构体总大小还需要考虑到成员之间由于对齐要求产生的额外空间。 2. **示例**: - 考虑一个结构体:`struct { char b; double x; };`,`sizeof`该结构体的结果可能不是`sizeof(char) + sizeof(double)`等于9字节,而是12字节。 - 这是因为`double`类型需要在内存中对齐到8字节边界,而在某些系统上,结构体成员的对齐方式可能需要额外的空间。 #### 七、具体示例 以结构体`struct MyStruct`为例: ```c struct MyStruct { double dda1; char dda; int type; }; ``` 1. **计算`sizeof(MyStruct)`**: - `sizeof(MyStruct)`的结果通常不是`sizeof(double) + sizeof(char) + sizeof(int)`等于13字节。 - 在VC环境下,`sizeof(MyStruct)`的值为16字节。 - 这是因为编译器为了提高处理器访问速度,会对结构体成员进行一定的对齐处理。 - 对于VC而言,对齐的方式取决于成员类型,例如: - `char`类型的成员偏移为`sizeof(char)`等于1字节。 - `int`类型的成员偏移为`sizeof(int)`等于4字节。 - `float`类型的成员偏移为`sizeof(float)`等于4字节。 - `double`类型的成员偏移为`sizeof(double)`等于8字节。 - `short`类型的成员偏移为`sizeof(short)`等于2字节。 - 为了使结构体成员在内存中的布局满足这些对齐要求,编译器会在必要时添加填充字节。 - 对于`struct MyStruct`,`dda1`占用8字节,`dda`占用1字节,`type`占用4字节,但为了满足对齐要求,总大小为16字节。 通过以上分析,我们可以清楚地理解`sizeof`操作符在C语言中的使用方法及其背后的原理。这对于编写高效且符合内存布局优化要求的程序至关重要。