C++ sizeof的使用总结
说明:以下代码在VS2008中通过,在32位操作系统下。
1. 定义
sizeof是一个操作符(operator)。
其作用是返回一个对象或类型所占的内存字节数。
其返回值类型为size_t。(size_t在头文件stddef.h中定义,它依赖于编译系统的值,一般定义为 typedef unsigned int size_t;)
2. 语法
sizeof有三种语法形式:
1) sizeof (object); //sizeof (对象)
2) sizeof object; //sizeof 对象
3) sizeof (type_name); //sizeof (类型)
对象可以是各种类型的变量,以及表达式(一般sizeof不会对表达式进行计算)。
sizeof对对象求内存大小,最终都是转换为对对象的数据类型进行求值。
sizeof (表达式); //值为表达式的最终结果的数据类型的大小
例子:(32位机器下)
- int i;
- sizeof(int); //值为4
- sizeof(i); //值为4,等价于sizeof(int)
- sizeof i; //值为4
- sizeof(2); //值为4,等价于sizeof(int),因为2的类型为int
- sizeof(2 + 3.14); //值为8,等价于sizeof(double),因为此表达式的结果的类型为double
- char ary[sizeof(int) * 10]; //OK,编译无误
最新的C99标准规定sizeof也可以在运行时刻进行计算。
如下面的程序在Dev-C++中可以正确执行:
- int n;
- n = 10; // n动态赋值
- char ary[n]; // C99也支持数组的动态定义
- cout<<sizeof(ary); // ok. 输出10
但在没有完全实现C99标准的编译器中就行不通了,上面的代码在VC6中就通不过编译。所以我们最好还是认为sizeof是在编译期执行的,这样不会带来错误,让程序的可移植性强些。
1. 基本数据类型的sizeof
这里的基本数据类型是指short、int、long、float、double这样的简单内置数据类型。
由于它们的内存大小是和系统相关的,所以在不同的系统下取值可能不同。
2. 结构体的sizeof
结构体的sizeof涉及到字节对齐问题。
为什么需要字节对齐?计算机组成原理教导我们这样有助于加快计算机的取数速度,否则就得多花指令周期了。为此,编译器默认会对结构体进行处理(实际上其它地方的数据变量也是如此),让宽度为2的基本数据类型(short等)都位于能被2整除的地址上,让宽度为4的基本数据类型(int等)都位于能被4整除的地址上,依次类推。这样,两个数中间就可能需要加入填充字节,所以整个结构体的sizeof值就增长了。
字节对齐的细节和编译器的实现相关,但一般而言,满足三个准则:
1) 结构体变量的首地址能够被其最宽基本类型成员的大小所整除。
2) 结构体的每个成员相对于结构体首地址的偏移量(offset)都是成员大小的整数倍,如有需要,编译器会在成员之间加上填充字节(internal adding)。
3) 结构体的总大小为结构体最宽基本类型成员大小的整数倍,如有需要,编译器会在最末一个成员后加上填充字节(trailing padding)。
注意:空结构体(不含数据成员)的sizeof值为1。试想一个“不占空间“的变量如何被取地址、两个不同的“空结构体”变量又如何得以区分呢,于是,“空结构体”变量也得被存储,这样编译器也就只能为其分配一个字节的空间用于占位了。
例子:
- struct S1
- {
- char a;
- int b;
- };
- sizeof(S1); //值为8,字节对齐,在char之后会填充3个字节。
- struct S2
- {
- int b;
- char a;
- };
- sizeof(S2); //值为8,字节对齐,在char之后会填充3个字节。
- struct S3
- {
- };
- sizeof(S3); //值为1,空结构体也占内存。
3. 联合体的sizeof
结构体在内存组织上市顺序式的,联合体则是重叠式,各成员共享一段内存;所以整个联合体的sizeof也就是每个成员sizeof的最大值。
例子:
- union u
- {
- int a;
- float b;
- double c;
- char d;
- };
- sizeof(u); //值为8
4. 数组的sizeof
数组的sizeof值等于数组所占用的内存字节数。
注意:1)当字符数组表示字符串时,其sizeof值将’/0’计算进去。
2)当数组为形参时,其sizeof值相当于指针的sizeof值。
例子1:
- char a[10];
- char n[] = "abc";
- cout<<"char a[10] "<<sizeof(a)<<endl;//数组,值为10
- cout<<"char n[] = /"abc/" "<<sizeof(n)<<endl;//字符串数组,将'/0'计算进去,值为4
例子2:
- void func(char a[3])
- {
- int c = sizeof(a); //c = 4,因为这里a不在是数组类型,而是指针,相当于char *a。
- }
- void funcN(char b[])
- {
- int cN = sizeof(b); //cN = 4,理由同上。
- }
5. 指针的sizeof
指针是用来记录另一个对象的地址,所以指针的内存大小当然就等于计算机内部地址总线的宽度。
在32位计算机中,一个指针变量的返回值必定是4。
指针变量的sizeof值与指针所指的对象没有任何关系。
例子:
- char *b = "helloworld";
- char *c[10];
- double *d;
- int **e;
- void (*pf)();
- cout<<"char *b = /"helloworld/" "<<sizeof(b)<<endl;//指针指向字符串,值为4
- cout<<"char *b "<<sizeof(*b)<<endl; //指针指向字符,值为1
- cout<<"double *d "<<sizeof(d)<<endl;//指针,值为4
- cout<<"double *d "<<sizeof(*d)<<endl;//指针指向浮点数,值为8
- cout<<"int **e "<<sizeof(e)<<endl;//指针指向指针,值为4
- cout<<"char *c[10] "<<sizeof(c)<<endl;//指针数组,值为40
- cout<<"void (*pf)(); "<<sizeof(pf)<<endl;//函数指针,值为4
6. 函数的sizeof
sizeof也可对一个函数调用求值,其结果是函数返回值类型的大小,函数并不会被调用。
对函数求值的形式:sizeof(函数名(实参表))
注意:1)不可以对返回值类型为空的函数求值。
2)不可以对函数名求值。
3)对有参数的函数,在用sizeof时,须写上实参表。
例子:
- #include <iostream>
- using namespace std;
- float FuncP(int a, float b)
- {
- return a + b;
- }
- int FuncNP()
- {
- return 3;
- }
- void Func()
- {
- }
- int main()
- {
- cout<<sizeof(FuncP(3, 0.4))<<endl; //OK,值为4,sizeof(FuncP(3,0.4))相当于sizeof(float)
- cout<<sizeof(FuncNP())<<endl; //OK,值为4,sizeof(FuncNP())相当于sizeof(int)
- /*cout<<sizeof(Func())<<endl; //error,sizeof不能对返回值为空类型的函数求值*/
- /*cout<<sizeof(FuncNP)<<endl; //error,sizeof不能对函数名求值*/
- }
C++ sizeof的使用总结的更多相关文章
- 聊聊 C 语言中的 sizeof 运算
聊聊 sizeof 运算 在这两次的课上,同学们已经学到了数组了.下面几节课,应该就会学习到指针.这个速度的确是很快的. 对于同学们来说,暂时应该也有些概念理解起来可能会比较的吃力. 先说一个概念叫内 ...
- c/c++中关于sizeof、strlen的使用说明
sizeof: 一般指类型.变量等占用的内存大小(由于在编译时计算,因此sizeof不能用来返回动态分配的内存空间的大小) strlen: c字符串的长度(参数必须是字符型指针 char*,当数组名作 ...
- sizeof(转载)
原文地址:http://blog.sina.com.cn/s/blog_5da08c340100bmwu.html 转载至:http://www.cnblogs.com/wangkangluo1/ar ...
- C语言中的sizeof()
sizeof,一个其貌不扬的家伙,引无数菜鸟竟折腰,小虾我当初也没少犯迷糊,秉着"辛苦我一个,幸福千万人"的伟大思想,我决定将其尽可能详细的总结一下. 但当我总结的时候才发现,这个 ...
- 你必须知道的指针基础-4.sizeof计算数组长度与strcpy的安全性问题
一.使用sizeof计算数组长度 1.1 sizeof的基本使用 如果在作用域内,变量以数组形式声明,则可以使用sizeof求数组大小,下面一段代码展示了如何使用sizeof: ,,,,,}; int ...
- c++面试常用知识(sizeof计算类的大小,虚拟继承,重载,隐藏,覆盖)
一. sizeof计算结构体 注:本机机器字长为64位 1.最普通的类和普通的继承 #include<iostream> using namespace std; class Parent ...
- c语言 sizeof理解
1.基本数据类型 char :1 short:2 int 4 long 4 long long :8 float:4 double :8字节. 2.数组:对应的基本数 ...
- sizeof与strlen的区别
1 sizeof是操作符,而strlen是库函数: 2 sizeof的参数可以为任意变量或类型,而strlen必须以char*做参数,且字符串必须以‘/0’结尾: 3 数组名用作sizeof参数时不会 ...
- sizeof
一.sizeof使用的场合: 1.sizeof操作符的一个主要用途是与存储分配和I/O系统那样的例程进行通信.例如: void* malloc(size_t size); size_t fread(v ...
- strlen()和sizeof()求数组长度
在字符常量和字符串常量的博文里有提: 求字符串数组的长度 标准库函数strlen(s)可以返回字符串s的长度,在头文件<string.h>里. strlen(s)的判断长度的依据是(s[i ...
随机推荐
- ReactiveCocoa入门教程——第一部分(转)
作为一个iOS开发者,你写的每一行代码几乎都是在响应某个事件,例如按钮的点击,收到网络消息,属性的变化(通过KVO)或者用户位置的变化(通过CoreLocation).但是这些事件都用不同的方式来处理 ...
- mysql学习笔记4
用phpmyadmin创建数据库时出现 #1064 - You have an error in your SQL syntax; check the manual that corresponds ...
- 某deed笔试题
1. 删除ra,输入s,然后从前往后扫,遇到直接删除,O(n),算水题吧. 2. 矩阵乘法,看完题,感觉这么简单,估计有什么套路,仔细再读一遍,发现真是水题,50*50*50=125000,在2s时 ...
- Java知识总结--数据库
1 薪水排序后薪水排名在第3-5的员工 1)select * from(select ename,sal,rownum rn from (select ename,sal from emp_44 wh ...
- DataGridView 绑定数据后修改列类型
dataGridView1.DataSource = dt; dataGridView1.Columns.RemoveAt(); //删除要被替换的列 DataGridViewLinkColumn l ...
- MongoDB入门三步曲2--基本操作(续)--聚合、索引、游标及mapReduce
mongodb 基本操作(续)--聚合.索引.游标及mapReduce 目录 聚合操作 MapReduce 游标 索引 聚合操作 像大多关系数据库一样,Mongodb也提供了聚合操作,这里仅列取常见到 ...
- sublime text3设置文件类型(CR/LF)
- hdu 5646 DZY Loves Partition 二分+数学分析+递推
链接:http://acm.hdu.edu.cn/showproblem.php?pid=5646 题意:将n分成k个正整数之和,要求k个数全部相同:并且这k个数的乘积最大为多少?结果mod 1e^9 ...
- ServiceController组件控制计算机服务
private void Form1_Load(object sender, EventArgs e) { //下面的示例使用 ServiceController 类检查IIS服务是否已停止.如果该服 ...
- MaskedTextBox控件实现输入验证
Mask属性可以验证用户在文本中输入数据的格式 this.maskedTextBox1.Mask = "000000-00000000-000A";//身份证号码18位 this. ...