笔试遇到很多sizeof的小题,博主基础堪忧,怒总结如下,还是要巩固基础啊啊啊!

sizeof操作符 对象所占 栈内存空间的大小单位是字节

关键词:char  数组 指针 结构体 class

【注意】

① sizeof(NULL) 结果为1, "\n"转义字符算作1位

② 是栈内存的大小,不是堆,也不是静态全局区

class A1{
public:
int a;
static int b; //静态变量存放在全局数据区域
A1();
~A1();
}; void main(){
cout << sizeof(A1) <<endl; //输出结果 4
}

v

1.基本类型占内存大小

  32位机     64位机器
类型 字节数      
int 4      
char 1      
指针 4     8
bool 1      
float 4 浮点型    
short 2      
long 4      
double 8 双精度浮点型    

2.sizeof(指针)  任意类型指针,结果为4

3.sizeof(数组)    元素大小*n

注意:数组名作为参数传递时,退化为指针,不传值不退化

如 int data[30] = {1,2,3,4};

  sizeof(data); //30*4为120

  int getSize(int data[ ] ){

    return sizeof(data);} // 返回4

4.静态数组vs动态数组

静态数组见上文,动态数组是初始化一个指针

5 sizeof(class)

"类的大小就是类中成员变量(非静态,遵循内存对齐)加上指向虚函数表的指针 以及 指向虚基类表的指针加起来的和。"

一个空类所占空间为 1 ,单继承,多重继承的空类均为 1 ,虚继承的空类设计虚表,虚指针,所以是4

    cout<<"空类: " <<sizeof(A) <<endl;       //
cout<<"单继承空类: " <<sizeof(C) <<endl; //
cout<<"多继承空类: " <<sizeof(D) <<endl; //1
cout<<"虚单继承空类: " <<sizeof(E) <<endl;//
cout<<"虚多继承空类: " <<sizeof(F) <<endl;//

6.sizeof(函数),对函数的返回值类型,【注意】不能对void操作

7.sizeof( string )

本质上string是一个类,在同一库中相同一点是,无论你的string里放多长的字符串,它的sizeof()都是固定的,字符串所占的空间是从堆中动态分配的,与sizeof()无关。

32位机 vs2008测试 sizeof(string) 为32,  猜测是指针*  4*8=32,为什么??????????

    string str="he";
string str1[]={"hello", "program", "world"};
cout <<"string: "<<sizeof(str) <<"\n"<< //
"str1: " <<sizeof(str1) <<"\n"<<endl; //96

8.sizeof(struct)  结构体 字节对齐(以下为转载)

首先,可以用pack预处理指令来禁止字节对齐(很少用到)

#pragma pack(1)
struct a{
char cV;
int iV;
};
#pragma pack()

 

这是初学者问得最多的一个问题,所以这里有必要多费点笔墨。让我们先看一个结构体:

  1. struct S1
  2. {
  3. char c;
  4. int i;
  5. };

问sizeof(s1)等于多少聪明的你开始思考了,char占1个字节,int占4个字节,那么加起来就应该是5。是这样吗你在你机器上试过了吗也许你是对的,但很可能你是错的!VC6中按默认设置得到的结果为8。

扩展:

  1. struct bs
  2. {
  3. char c1;
  4. char c2;
  5. int a;
  6. };
  7. int main()
  8. {
  9. bs t;
  10. cout<<"sizeof(bs):"<<sizeof(bs)<<endl;//输出sizeof(bs): 8
  11. cout<<"sizeof(t):"<<sizeof(t)<<endl;//输出sizeof(t): 8
  12. }
  1. struct bs
  2. {
  3. char c1;
  4. int a;
  5. char c2;
  6. };
  7. int main()
  8. {
  9. bs t;
  10. cout<<"sizeof(bs):"<<sizeof(bs)<<endl;//输出sizeof(bs): 12
  11. cout<<"sizeof(t):"<<sizeof(t)<<endl;//输出sizeof(t): 12
  12. }

Why为什么受伤的总是我请不要沮丧,我们来好好琢磨一下sizeof的定义——sizeof的结果等于对象或者类型所占的内存字节数,好吧,那就让我们来看看S1的内存分配情况:
S1 s1 = { 'a', 0xFFFFFFFF };
定义上面的变量后,加上断点,运行程序,观察s1所在的内存,你发现了什么以我的VC6.0为例,s1的地址为0x0012FF78,其数据内容如下:
0012FF78: 61 CC CC CC FF FF FF FF
发现了什么怎么中间夹杂了3个字节的CC看看MSDN上的说明:
When applied to a structure type or variable, sizeof returns the actual size, which may include padding bytes inserted for alignment.
原来如此,这就是传说中的字节对齐啊!

一个重要的话题出现了。为什么需要字节对齐计算机组成原理教导我们这样有助于加快计算机的取数速度,否则就得多花指令周期了。为此,编译器默认会对结构体进行处理(实际上其它地方的数
据变量也是如此),让宽度为2的基本数据类型(short等)都位于能被2整除的地址上,让宽度为4的基本数据类型(int等)都位于能被4整除的地址上,以此类推。这样,两个数中间就可能需要加入填充字节,所以整个结构体的sizeof值就增长了。
让我们交换一下S1中char与int的位置:

  1. struct S2
  2. {
  3. int i;
  4. char c;
  5. };

看看sizeof(S2)的结果为多少,怎么还是8再看看内存,原来成员c后面仍然有3个填充字节,这又是为什么啊别着急,下面总结规律。

字节对齐的细节和编译器实现相关,但一般而言,满足三个准则:
1) 结构体变量的首地址能够被其最宽基本类型成员的大小所整除;
2) 结构体每个成员相对于结构体首地址的偏移量(offset)都是成员大小的整数倍,如有需要编译器会在成员之间加上填充字节(internal adding);
3) 结构体的总大小为结构体最宽基本类型成员大小的整数倍,如有需要编译器会在最末一个成员之后加上填充字节(trailing padding)。

对于上面的准则,有几点需要说明:
1) 前面不是说结构体成员的地址是其大小的整数倍,怎么又说到偏移量了呢因为有了第1点存在,所以我们就可以只考虑成员的偏移量,这样思考起来简单。想想为什么。
结构体某个成员相对于结构体首地址的偏移量可以通过宏offsetof()来获得,这个宏也在stddef.h中定义,如下:
#define offsetof(s,m) (size_t)&(((s *)0)->m)
例如,想要获得S2中c的偏移量,方法为
size_t pos = offsetof(S2, c);// pos等于4

2) 基本类型是指前面提到的像char、short、int、float、double这样的内置数据类型,这里所说的“数据宽度”就是指其sizeof的大小。由于结构体的成员可以是复合类型,比如另外一个结构体,所以在寻找最宽基本类型成员时,应当包括复合类型成员的子成员,而不是把复合成员看成是一个整体。但在确定复合类型成员的偏移位置时则是将复合类型作为整体看待。
这里叙述起来有点拗口,思考起来也有点挠头,还是让我们看看例子吧(具体数值仍以VC6为例,以后不再说明):

  1. struct S3
  2. {
  3. char c1;
  4. S1 s;
  5. char c2
  6. };

S1的最宽简单成员的类型为int,S3在考虑最宽简单类型成员时是将S1“打散”看的,所以S3的最宽简单类型为int,这样,通过S3定义的变量,其存储空间首地址需要被4整除,整个sizeof(S3)的值也应该被4整除。c1的偏移量为0,s的偏移量呢这时s是一个整体,它作为结构体变量也满足前面三个准则,所以其大小为8,偏移量为4,c1与s之间便需要3个填充字节,而c2与s之间就不需要了,所以c2的偏移量为12,算上c2的大小为13,13是不能被4整除的,这样末尾还得补上3个填充字节。最后得到sizeof(S3)的值为16。

 

传送门:笔试题【C++基础】 sizeof题目

sizeof与strlen【C++基础】sizeof 与 strlen的区别

参考: C/C++ 笔试面试(1)—— sizeof

【C++基础】sizeof 数组 指针 空NULL的更多相关文章

  1. C语言基础 (9) 数组指针

    复习 只要把地址拿到就能这么操作.. (这里是合法的地址,不是野指针) 只有定义变量后,此变量的地址才是合法的地址 野指针就是保存没有意义地址的指针变量 操作野指针变量本身不会有任何问题 操作野指针所 ...

  2. go语言基础之数组指针做函数参数

    1.数组指针做函数参数 示例: package main //必须有个main包 import "fmt" //p指向实现数组a,它是指向数组,它是数组指针 //*p代表指针所指向 ...

  3. 嵌入式-C语言基础:数组指针

    定义一个数组指针,指向二维数组: int a[3][4]={{1,2,3,4},{5,6,7,8},{9,10,11,12}}; int (*p)[4];//定义二维指针数组 p=a;//指向二维数组 ...

  4. 数组类型与sizeof与指针的引用

    以char类型为例: char a[100];     //a类型为char[100]    &a类型为 char (*)[100]    *a类型为char char *p = a;     ...

  5. 释放内存触发断点及数组、指针的NULL初始化

    Visual Studio调试时,出现“触发一个断点”内存释放出现异常 数组和对应指针的NULL初始化 数组使用之前要先对其初始化 char Outi[4] = { NULL }; char Outj ...

  6. sizeof数组名和字符指针是有区别的

    sizeof数组名和字符指针是有区别的. #include <stdio.h> #include <stdlib.h> void change(char url[]); int ...

  7. PHP递归方式把一个数组里面的null转换为空字符串”的方法

    在一些接口的调用中,直接查询数据库出来的字段可能为null字段,但是为了简便前端的判断,需要把null转换成空字符串'',这个时候就需要递归的方式进行.直接上代码如下: //递归方式把数组或字符串 n ...

  8. [C++基础]那些容易被混淆的概念:函数/数组指针-指针函数/数组,类/函数模板-模板类/函数

    函数指针-指针函数 函数指针的重点是指针.表示的是一个指针,它指向的是一个函数.eg: int (*pf)(); 指针函数的重点是函数.表示的是一个函数,它的返回值是指针.eg: int* fun() ...

  9. C++基础 (8) 第八天 数组指针 模板指针 C语言中的多态 模板函数

    1昨日回顾 2 多态的练习-圆的图形 3多态的练习-程序员薪资 4员工管理案例-抽象类和技术员工的实现 employee.h: employee.cpp: technician.h: technici ...

随机推荐

  1. python学习day1--python基础

    Python的优缺点 先看优点 Python的定位是“优雅”.“明确”.“简单”,所以Python程序看上去总是简单易懂,初学者学Python,不但入门容易,而且将来深入下去,可以编写那些非常非常复杂 ...

  2. Javascript之改变盒子颜色

    index.html: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http:/ ...

  3. [转]SQL中使用WITH AS提高性能-使用公用表表达式(CTE)简化嵌套SQL

    一.WITH AS的含义     WITH AS短语,也叫做子查询部分(subquery factoring),可以让你做很多事情,定义一个SQL片断,该SQL片断会被整个SQL语句所用到.有的时候, ...

  4. SQL按照日、周、月、年统计数据

    写sql语句分别按日,星期,月,季度,年统计销售额 --按日 select sum(consume),day([date]) from consume_record where year([date] ...

  5. Linux系统下给VMWare安装Tools

    1.进入Linux系统. 2.在VMware的窗口菜单中选VM >> install VMware Tools,虚拟机自动将VMware-tools装入虚拟光驱中. 3.在虚拟光驱里找出V ...

  6. Objective-C 【@property和@synthesize关键字】

    ------------------------------------------- @property关键字的使用及注意事项 直接上代码和注释了! // //@property关键字的使用 //① ...

  7. @Resource和@Autowired的区别

    @Resource的作用相当于@Autowired,只不过@Autowired按byType自动注入,而@Resource默认按 byName自动注入罢了.@Resource有两个属性是比较重要的,分 ...

  8. Percona-Server-5.5.33-31.1安装

    一.下载 http://www.percona.com/downloads/Percona-Server-5.5/ Percona-Server-5.5.33-31.1 选择 binary 选择lin ...

  9. 韩顺平细说Servlet视频系列之tom相关内容

    韩顺平细说Servlet视频系列之tom相关内容 tomcat部署项目操作(注意:6.0版本以后的支持该操作,5.x版本需要另外配置?待验证!) 项目发布到tomcat的webapps文件下,然后启动 ...

  10. 用C语言实现统计一个文件夹中各种文件的比例

    <UNIX环境高级编程>中的程序清单4-7就介绍了如何实现递归地统计某个目录下面的文件!我刚开始看过它的代码后,觉得照着敲太没意思了,所以就合上书自己写了一遍!为此还写了一篇博文,这是博文 ...