sizeof函数功能:计算数据空间的字节数

1.与strlen()比较
strlen计算字符数组的字符数,以"\0"为结束判断,不计算为'\0'的数组元素。
sizeof计算数据(包括数组、变量、类型、结构体等)所占内存空间,用字节数表示(当然用在字符数组计算"\0"的大小)。
2.指针与静态数组的sizeof操作
指针均可看为变量类型的一种。所有指针变量的sizeof 操作结果均为4。

实例1::char *p;
sizeof(p)=4;
sizeof(*p) = 1; //相当于sizeof(char);
实例2:
对于静态数组,sizeof可直接计算数组大小;
例:int a[10];
char b[]="hello";
sizeof(a)等于4*10=40;
sizeof(b)等于6;

void fun(char p[])
{
sizeof(p); //等于4,数组做型参时,数组名称当作指针使用!!
}

实例3(经典考题):
double* (*a)[3][6];
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。

3.格式的写法
sizeof操作符,对变量或对象可以不加括号,但若是类型,须加括号。
4.使用sizeof时string的注意事项
string s="hello";
sizeof(s)等于string类的大小(32),sizeof(s.c_str())得到的是与字符串长度(4)。
5.union 与struct的空间计算
总体上遵循两个原则:
(1)整体空间是占用空间最大的成员(类型)所占字节的整数倍
(2)数据对齐原则----数据在内存中按照结构成员先后顺序进行排序,当排到该成员变量时,其前面已摆放的空间大小必须是该成员类型大小的整倍数,如果不够则补齐,以此向后类推。。。。。
注意:数组按照单个变量一个一个的摆放,而不是看成整体。如果成员中有自定义的类、结构体,也要注意数组问题。
实例4:[引用其他帖子的内容]
因为对齐问题使结构体的sizeof变得比较复杂,看下面的例子:(默认对齐方式下)
struct s1
{
char a;
double b;
int c;
char d;
};

struct s2
{
char a;
char b;
int c;
double d;
};

cout<<sizeof(s1)<<endl; // 24
cout<<sizeof(s2)<<endl; // 16

同样是两个char类型,一个int类型,一个double类型,但是因为对齐问题,导致他们的大小不同。计算结构体大小可以采用元素摆放法,我举例子说明一下:首先,CPU判断结构体的对界,根据上一节的结论,s1和s2的对界都取最大的元素类型,也就是double类型的对界8。然后开始摆放每个元素。
对于s1,首先把a放到8的对界,假定是0,此时下一个空闲的地址是1,但是下一个元素b是double类型,要放到8的对界上,离1最接近的地址是8了,所以b被放在了8,此时下一个空闲地址变成了16,下一个元素c的对界是4,16可以满足,所以c放在了16,此时下一个空闲地址变成了20,下一个元素d需要对界1,也正好落在对界上,所以d放在了20,结构体在地址21处结束。由于s1的大小需要是8的倍数,所以21-23的空间被保留,s1的大小变成了24。
对于s2,首先把a放到8的对界,假定是0,此时下一个空闲地址是1,下一个元素的对界也是1,所以b摆放在1,下一个空闲地址变成了2;下一个元素c的对界是4,所以取离2最近的地址4摆放c,下一个空闲地址变成了8,下一个元素d的对界是8,所以d摆放在8,所有元素摆放完毕,结构体在15处结束,占用总空间为16,正好是8的倍数。

这里有个陷阱,对于结构体中的结构体成员,不要认为它的对齐方式就是他的大小,看下面的例子:
实例5:
struct s1
{
char a[8];
};

struct s2
{
double d;
};

struct s3
{
s1 s;
char a;
};

struct s4
{
s2 s;
char a;
};
cout<<sizeof(s1)<<endl; // 8
cout<<sizeof(s2)<<endl; // 8
cout<<sizeof(s3)<<endl; // 9
cout<<sizeof(s4)<<endl; // 16;
s1和s2大小虽然都是8,但是s1的对齐方式是1,s2是8(double),所以在s3和s4中才有这样的差异。
所以,在自己定义结构体的时候,如果空间紧张的话,最好考虑对齐因素来排列结构体里的元素。

相关常数:
sizeof int:4
sizeof short:2
sizeof long:4
sizeof float:4
sizeof double:8
sizeof char:1
sizeof p:4
sizeof WORD:2
sizeof DWORD:4

sizeof函数总结相关推荐

  1. C/C++ sizeof函数解析——解决sizeof求结构体大小的问题

    C/C++ sizeof函数解析--解决sizeof求结构体大小的问题 参考文章: (1)C/C++ sizeof函数解析--解决sizeof求结构体大小的问题 (2)https://www.cnbl ...

  2. 【C 语言】字符串操作 ( strlen 与 sizeof 函数 | 计算 字符串长度 与 内存块大小 )

    文章目录 一.strlen 与 sizeof 函数 二.计算 字符串长度 与 内存块大小 一.strlen 与 sizeof 函数 strlen() 函数的作用是获取字符串大小 , 其原理是 从 内存 ...

  3. 【C 语言】数据类型本质 ( sizeof 函数 | 数据类型大小 )

    文章目录 一.sizeof 函数 二.数据类型大小 三.代码示例 一.sizeof 函数 sizeof() 函数可以计算 数据类型 的大小 ; sizeof (类型说明符/表达式) 可以向函数中传递 ...

  4. sizeof(函数名)=?

    sizeof(函数名)=? 直接上代码 #include <stdio.h>int foo(void) {printf("hello\n");return 0; }in ...

  5. C语言 sizeof 函数 - C语言零基础入门教程

    目录 一.sizeof 函数简介 二.sizeof 函数实战 三.猜你喜欢 零基础 C/C++ 学习路线推荐 : C/C++ 学习目录 >> C 语言基础入门 一.sizeof 函数简介 ...

  6. C ++基础 | sizeof函数(endl 和 \ n),定义常量(Define Constants),枚举常量(Enumerated Constants)_2

    目录 sizeof函数(endl 和 "\ n") 定义常量 枚举常量 sizeof函数(endl 和 "\ n") 与其他编程语言一样,在内存中分配变量的大小 ...

  7. 数组名不等于指针---sizeof()函数求数组大小错误问题

    前言: 今天在项目中需要求采样点的数量并且遍历,采样点用数组存储,自定义了一个函数想要用sizeof求其长度,然后遍历,结果失败了,查阅之后发现以下问题: 在main函数中,sizeof是可以正常工作 ...

  8. C语言学习笔记---strlen()函数和sizeof()函数

      strlen() 函数和 sizeof() 函数通常都可以用来计算数组或者字符串的长度.在使用的时候很容易混淆.下面就通过几个简单的示例来看一看这两个函数的具体差别. int main() {ch ...

  9. C语言命名、循环、sizeof函数、递归

    变量命名---骆驼峰命名法!!! /*************************************************************/ continue  跳出此次循环进入下 ...

  10. 用sizeof函数对变量数据所占字节数进行测量

    /*文件名:test.c *完成日期:2016.3.28 * *目的:使用sizeof函数对各种类型的变量所占的字节数进行测量 */ #include <stdio.h> #include ...

最新文章

  1. 马斯克发首款会上火星的电动皮卡:28万起,可防弹,造型相当“赛博朋克”...
  2. linux中配置jmeter环境变量,linux java 和jmeter 环境变量配置文件笔记(原)
  3. [转]NUnit详细使用方法
  4. Universe Naming Rule
  5. Android之BaseRecyclerViewAdpater(3.0.4版本)当页面第二次滑到底部的时候没有触发OnLoadMoreListener监听的onLoadMore函数
  6. php中上传图片怎么显示出来,PHP上传图片类显示缩略图功能
  7. 【Python3网络爬虫开发实战】1.3.1-lxml的安装
  8. 移动端数据爬取和Scrapy框架
  9. Android StickHeaderRecyclerView - 让recyclerview头部固定
  10. html5小说阅读器源码,文本源码阅读器(NexusTextView)
  11. ofdm导频信道估计matlab,OFDM导频信道估计
  12. 沪深股票的复权计算(复权因子的应用)
  13. zcmu-1359 NBA (水题)
  14. 第二课 SS7信令系统网络简介
  15. canvas绘制图形API(一)
  16. VGA接口和HDMI接口有什么区别 哪个好
  17. 如何用C#制作 微信个人机器人
  18. 小米MIUI12开启或关闭volte功能
  19. Maven问题之Lastupdated
  20. 2018-决策树约束的建筑点云提取方法

热门文章

  1. C#如何判断一个字符串中是否有非英文、数字字符
  2. 趣学python教孩子学编程_[转载]学编程要从娃娃抓起——教孩子学Python
  3. 网络适配器(代码48)Realtek PCIe GbE Family Controller
  4. 如何将电脑磁盘的主分区转化为逻辑分区(不会格式化磁盘)
  5. 宁波机器人餐厅需要预约吗_宁波机器人餐厅 比雇人一年能省20多万元
  6. 问题解决—Unable to sync with device; possible link problem or link software version mismatch such as hyd
  7. Java程序员常用的各种快捷键和命令:
  8. YOLOv7改进结构系列:最新结合DO-DConv卷积提高性能涨点,打造高性能检测器
  9. android开发提示对话框,Android中Notification 提示对话框
  10. cmd之拷贝、删除文件夹