C/C++中的sizeof
来源:互联网 发布:数控车床软件编程 编辑:程序博客网 时间:2024/06/16 00:41
在介绍sizeof之前,先明确一点:sizeof是操作符,不是函数!
对sizeof的学习与理解主要参考MSDN上的介绍,也参考了一些其他博客或论坛中的解说。
1、sizeof的介绍:
sizeof的语法是
sizeof unary-expression sizeof ( type-name )
MSDN中说sizeof运算符的结果是size_t类型,是包含文件 STDDEF.H 中定义的整数类型。不过我没在stddef.h中找到size_t的定义,但是从stddef.h包含的头文件crtdefs.h中找到了它的定义(我使用的编译器是VS2013中的VC的编译器):
#ifndef _SIZE_T_DEFINED#ifdef _WIN64typedef unsigned __int64 size_t;#else /* _WIN64 */typedef _W64 unsigned int size_t;#endif /* _WIN64 */#define _SIZE_T_DEFINED#endif /* _SIZE_T_DEFINED */
关于size_t详细信息不在这里说明。
2、sizeof的使用:
(1)操作数是类型名称
sizeof(类型名称);
输入以下代码:
printf("%lu,%lu,%lu\n",sizeof(char),sizeof(char*),sizeof(char[5]));输出结果是:
1,8,5可知,第一个得到的是类型所用字节数,第二个得到的是指针所占字节数,第三个得到的是数组所占字节数。
补充:
以上结果是32位系统的情况;如果是64位系统,得到的结果可能会不同。
(2)操作数是表达式
sizeof(表达式);
或
sizeof 表达式;
输入以下代码:
char arr[] = "i am a student!";printf("%lu,%lu,%lu,%lu,%lu,%lu\n" \ ,sizeof arr, sizeof *arr, sizeof &arr[0], \ sizeof(arr), sizeof(*arr), sizeof(&arr[0]));输出的结果是:
16,1,8,16,1,8可知,是否使用括号,表示的结果是相同的。第一个得到的是数组所占用的总字节数,第二个得到的是数组中的第一个元素所占用的字节数;第三个是指针所占字节数。
(3)操作数是类或结构体
以结构体为例,输入以下代码:
struct test{ int i; //sizeof(i) = 4 int arr[3]; //sizeof(arr) = 12; char c; //sizeof(c) = 1; char *str; //sizeof(str) = 8;};int main(void) { struct test tt[10]; printf("%lu,%lu,%lu,%lu\n", \ sizeof(tt[0].i), sizeof(tt[0].arr), \ sizeof(tt[0].c), sizeof(tt[0].str)); printf("%lu,%lu,%lu,%lu\n", \sizeof(struct test), sizeof tt[0], \sizeof tt, sizeof *tt); return 0;}输出的结果是:
4,12,1,832,32,320,32表面上看,一个结构体test所占据的空间应该为4+12+1+8=25,但实际上test被分配的空间是32。其原因与结构体分配内存空间时的对齐原则有关。具体细节见《C语言中结构体的对齐规则》。
类的情况与结构体的类似。
3、通过宏实现sizeof的定义
关于这点方法,是从帖子“谁知道sizeof这个关键字的源码实现在哪个地方可以找到?”中得到的启发。
输入以下代码:
#define sizeof1(type) ((char*)((type*)0+1)-(char*)0)#define sizeof2(var) ((char*)(&var+1)-(char*)&var)int main(void) { int i; char c; double d; printf("%lu, %lu.\n",sizeof1(char), sizeof2(c)); printf("%lu, %lu.\n",sizeof1(int), sizeof2(i)); printf("%lu, %lu.\n",sizeof1(double), sizeof2(d));return 0;}输出的结果是:
1, 1.4, 4.8, 8.表示定义没有问题。
注意事项
因为sizeof操作符在编译过程中就确定了,所以有一些注意事项。
(1)关于sizeof(i++)
sizeof在编译的时候取得是i这个变量的类型所占的空间,因为在编译的时候就被i的字节数代替了,所以不会再进行自加操作。
(2)运算符永远不会产生0
当类为空或指向空指针时,输入以下代码:
class Test1{};class Test2{ int i; char c; double d;};int main() {Test1 *t1 = NULL, *pt1 = new Test1;Test2 *t2 = NULL, *pt2 = new Test2;cout << sizeof(*t1) << ", " << sizeof(*pt1) << "\n";cout << sizeof(*t2) << ", " << sizeof(*pt2) << "\n";return 0;}输出结果为:
1, 116, 16(3)运算符不能用于的操作数
- 函数(但sizeof可以应用于指向函数的指针)
- 位域
- 未定义的类
- void类型
- 动态分配的数组
- 外部数组
- 不完整类型
- 带括号的不完整类型的名称
总之sizeof适用的操作数是能够在编译步骤中确定下来的数,是静态的。
(4)数组中的元素数量
直接上代码:
#define GetLen(arr) sizeof(arr)/sizeof(arr[0])int main() {char str[] = "This is a string.";cout << "The length of str is: " << GetLen(str) << endl;return 0;}输出结果是:
The length of str is: 18
- C语言中的sizeof
- C语言中的sizeof
- c语言中的sizeof()
- C语言中的sizeof
- C语言中的sizeof
- C/C++中的sizeof
- C语言中的sizeof()
- 解析C语言中的sizeof
- 解析C语言中的sizeof
- 解析C语言中的sizeof
- 解析C语言中的sizeof
- 解析C语言中的sizeof
- 解析C语言中的sizeof
- 解析C语言中的sizeof
- 解析C语言中的sizeof
- 解析C语言中的sizeof
- 解析C语言中的sizeof
- 解析C语言中的sizeof
- vs报错解决方法
- 自定义pch文件,设置宏定义
- CentOS7 yum 安装git
- 深度学习笔记(持续更新)
- 经典算法之选择排序(直接选择、堆排序)
- C/C++中的sizeof
- ping
- Android逆向之旅---解析编译之后的AndroidManifest文件格式
- vue2.0 axios前后端数据处理
- java中判断一个数是否在数组中
- 整数排序
- 修改map中的值
- 微信小程序demo1计算器
- NB朴素贝叶斯理论推导与三种常见模型