一、sizeof使用的场合:

1、sizeof操作符的一个主要用途是与存储分配和I/O系统那样的例程进行通信。例如:

 void* malloc(size_t size);
size_t fread(void *ptr, size_t size, size_t nmemb, FILE* stream)

2、用它可以看看某种类型的对象在内存中所占的单元字节。例如:

  void *memset(void *s, int c, sizeof(s));

3、在动态分配一对象时,可以让系统知道要分配多少内存。

4、便于一些类型的扩充。在windows中很多结构类型就有一个专用的字段用来存放该类型的字节大小。

5、由于操作数的字节数在实现时可能出现变化,建议在涉及操作数字节大小时用sizeof代替常量计算。

6、如果操作数就是函数中的数组形参或函数类型的形参,sizeof给出其指针的大小。

二、sizeof不能使用的场合:

sizeof操作符不能用于函数类型,不完全类型或位字段。不完全类型指具有未知存储大小的数据类型,如未知存储大小的数组类型、未知内容的结构或联合类型等。

三、

 cout<<sizeof(string*)<<endl; //
cout<<sizeof(int*)<<endl; //
cout<<sizof(char****)<<endl; // int f();
cout << sizeof(f) << endl; //编译错误
cout << sizeof(f()) << endl; // int a=;
cout << sizeof(a=) << endl; //输出4,
11 cout << a << endl; //输出6。sizeof只是个运算符,所以相当于符号替换,a=8被替换成int,并不会修改a的值。

四、

 #include <iostream>
using namespace std; int Sum(int i[]) {
int sumofi = ;
for (int j = ; j < sizeof(i)/sizeof(int); j++) //实际上,sizeof(i) = 4这里数组名在形参作为指针
sumofi += i[j];
return sumofi;
} int main() {
int allAges[] = {, , , , , };
cout<<Sum(allAges)<<endl;
return ;
}
Sum的本意是用sizeof得到数组的大小,然后求和。但是实际上,传入自函数Sum的,只是一个int 类型的指针,所以sizeof(i)=4,而不是24,所以会产生错误的结果。解决这个问题的方法使是用指针或者引用。
一般求数组的长度我们会习惯用函数模板。这个可以参考文章《函数模板》。
 
五、
 double* (*a)[][];
cout<<sizeof(a)<<endl; // 4 a为指针
cout<<sizeof(*a)<<endl; // 72 *a为一个有3*6个指针元素的数组
cout<<sizeof(**a)<<endl; // 24 **a为数组一维的6个指针
cout<<sizeof(***a)<<endl; // 4 ***a为一维的第一个指针
cout<<sizeof(****a)<<endl; // 8 ****a为一个double变量
解析:a是一个很奇怪的定义,他表示一个指向double*[3][6]类型数组的指针。既然是指针,所以sizeof(a)就是4。 既然a是执行double*[3][6]类型的指针,*a就表示一个double*[3][6]的多维数组类型,因此sizeof(*a)=3*6*sizeof(double*)=72。同样的,**a表示一个double*[6]类型的数组,所以sizeof(**a)=6*sizeof  (double*)=24。***a就表示其中的一个元素,也就是double*了,所以sizeof(***a)=4。至于****a,就是一个double了,所以sizeof(****a)=sizeof(double)=8。 
 #include <iostream>

 using namespace std;

 int main() {
char (*f)[];
int **c[][];
double *(*a)[][];
cout << sizeof(f) << endl; //
cout << sizeof(*f) << endl; //
cout << sizeof(**f) << endl; //
cout << sizeof(a) << endl; //
cout << sizeof(*a) << endl; //
cout << sizeof(**a) << endl; //
cout << sizeof(***a) << endl; //
cout << sizeof(****a) << endl; //
cout << sizeof(c) << endl; //
return ;
}
六、sizeof(class)
空类的大小为1,其他跟struct差不多,可以参见《字节对齐详解》里面的内容。需要指出的是class里面的virtual函数是独立开来的,virtual代表的是一个虚函数指针,它是一个虚函数表的地址入口。例如:
 class classB {
char a;
// double b;
// int c;
virtual func1(){}
};
因为虚函数指针占了四个字节,char占了一个字节,安照对齐原则,sizeof(classB)=8, 如果去掉注释int c,那就变成了12. 但,注意如果现在注释int c,而去掉double b的注释,guess what's it? 按一般来说,应该是16,一个double加char和一个指针,补足16位,但实际上是24,因为指针是单独拿出来算了,这就变成了double,加上char补足的八位,加上指针补足的八位,一共是24个字节了。
 

sizeof的更多相关文章

  1. 聊聊 C 语言中的 sizeof 运算

    聊聊 sizeof 运算 在这两次的课上,同学们已经学到了数组了.下面几节课,应该就会学习到指针.这个速度的确是很快的. 对于同学们来说,暂时应该也有些概念理解起来可能会比较的吃力. 先说一个概念叫内 ...

  2. c/c++中关于sizeof、strlen的使用说明

    sizeof: 一般指类型.变量等占用的内存大小(由于在编译时计算,因此sizeof不能用来返回动态分配的内存空间的大小) strlen: c字符串的长度(参数必须是字符型指针 char*,当数组名作 ...

  3. sizeof(转载)

    原文地址:http://blog.sina.com.cn/s/blog_5da08c340100bmwu.html 转载至:http://www.cnblogs.com/wangkangluo1/ar ...

  4. C语言中的sizeof()

    sizeof,一个其貌不扬的家伙,引无数菜鸟竟折腰,小虾我当初也没少犯迷糊,秉着"辛苦我一个,幸福千万人"的伟大思想,我决定将其尽可能详细的总结一下. 但当我总结的时候才发现,这个 ...

  5. 你必须知道的指针基础-4.sizeof计算数组长度与strcpy的安全性问题

    一.使用sizeof计算数组长度 1.1 sizeof的基本使用 如果在作用域内,变量以数组形式声明,则可以使用sizeof求数组大小,下面一段代码展示了如何使用sizeof: ,,,,,}; int ...

  6. c++面试常用知识(sizeof计算类的大小,虚拟继承,重载,隐藏,覆盖)

    一. sizeof计算结构体 注:本机机器字长为64位 1.最普通的类和普通的继承 #include<iostream> using namespace std; class Parent ...

  7. c语言 sizeof理解

    1.基本数据类型 char :1     short:2   int 4    long 4   long long :8    float:4    double :8字节. 2.数组:对应的基本数 ...

  8. sizeof与strlen的区别

    1 sizeof是操作符,而strlen是库函数: 2 sizeof的参数可以为任意变量或类型,而strlen必须以char*做参数,且字符串必须以‘/0’结尾: 3 数组名用作sizeof参数时不会 ...

  9. strlen()和sizeof()求数组长度

    在字符常量和字符串常量的博文里有提: 求字符串数组的长度 标准库函数strlen(s)可以返回字符串s的长度,在头文件<string.h>里. strlen(s)的判断长度的依据是(s[i ...

随机推荐

  1. 3.Java网络编程之IP

    前面两篇博文我们已经简单了解了IP.端口.协议以及两种参考模型,我们现在重新从程序角度来看下这个参考模型. 如果我们从事的是Web网站开发,那么我们应该知道HTML是一种超文本标记语言 (Hyper ...

  2. mybatis入门基础(八)-----查询缓存

    一.什么是查询缓存 mybatis提供查询缓存,用于减轻数据压力,提高数据库性能. mybaits提供一级缓存,和二级缓存. 1.1. 一级缓存是sqlSession级别的缓存.在操作数据库时需要构造 ...

  3. String源码中的"avoid getfield opcode"

    引言: 之前一篇文章梳理了String的不变性原则,还提到了一段源码中注释"avoid getfield opcode",当时通过查阅资料发现,这是为了防止 getfield(获取 ...

  4. 关于JSON的那些事儿

    JSON的那些事儿 曾经有一段时间,XML是互联网上传输结构化数据的事实标准,其突出特点是服务器与服务器间的通信.但是业内不少人认为XML过于繁琐.冗长,后面为了解决这个问题也出现了一些方案,但是由于 ...

  5. Struts2 源码分析——调结者(Dispatcher)之执行action

    章节简言 上一章笔者写关于Dispatcher类如何处理接受来的request请求.当然读者们也知道他并非正真的执行action操作.他只是在执行action操作之前的准备工作.那么谁才是正真的执行a ...

  6. SQL Server时间粒度系列----第8节位运算以及设置日历数据表节假日标志详解

    本文目录列表: 1.位运算 2.设置日历数据表节假日标志 3.总结语 4.参考清单列表   位运算   SQL Server支持的按位运算符有三个,分别为:按位与(&).按位或(|).按位异或 ...

  7. mysql 处理 NULL

    1.如果为空返回0 select ifnull(null,0) 2.如果为空返回0,否则返回1 select if(isnull(col),0,1) as col. MYSQL 中的IFNULL函数 ...

  8. 解决asp.net mvc的跨域请求问题

    web.config中配置如下内容: <system.webServer> <httpProtocol> <customHeaders> <add name= ...

  9. ASP.NET MVC 模块与组件(一)——发送邮件

    我的见解: 模块化与组件化是编程的一种思想:提高代码的重用性,提高开发效率. 常见的模块化就是函数与各种类型的封装,若是代码具有更高的重用价值(能够提供给别人使用),建议可以考虑封装成动态链接库(dl ...

  10. html中<radio>单选按钮控件标签用法解析及如何设置默认选中

    <input type="radio" name="radio" value="1">单选1 <input type=&q ...