笔试遇到很多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. 使用Win7+IIS7发布网站或服务步骤

    1.安装IIS服务:控制面板=>程序=>打开或关闭WINDOWS 功能=>Internet 信息服务=>WEB服务管理器全选√ 和万维网服务:应用程序开发功能: 2.打开IIS ...

  2. Caching和Purgeable Memory (译)

    Caching和Purgeable Memory对于开发者来说是一个至关重要的资源,尤其是当我们需要处理那些需要超大内存以及计算时间的对象或者是当计算机向磁盘写入数据时导致应用程序陷入停滞时特别有用处 ...

  3. 使用python读写windows剪切板

    import win32clipboard as w import win32con base_addr = 0x8e00000 buffer_len = 0x123 def getText(): w ...

  4. how to Enable Client Integration

    i got a problem,the problem is list cant use export to excel button in sharepoint 2010. I found my a ...

  5. C# Oracle海量数据瞬间插入到数据库的方法

    C# 海量数据瞬间插入到数据库的方法 当我们在数据库中进行大量的数据追加时,是不是经常因为数据量过大而苦恼呢?而所谓的海量数据,一般也是上万级的数据,比如我们要添加一百万条数据,应该如何提高它的效率呢 ...

  6. emoji处理方法汇总

    emoji资料 今天研究了emoji,挺有意思,资料挺多,摘要一些信息给大家分享,也算是自己记录学习. emoji介绍 Emoji (絵文字,词义来自日语えもじ,e-moji,moji在日语中的含义是 ...

  7. GridView分页排序

    <%@ Page Language="C#" AutoEventWireup="true" CodeFile="GridviewPage.asp ...

  8. SSH-KEY服务及批量分发与管理实战

    SSH服务 一.SSH服务介绍 SSH是Secure Shell Protocol的简写,由IETF网络工作小组制定:在进行数据传输之前,SSH先对联机数据包通过加密技术进行加密处理,加密后再进行数据 ...

  9. 使用bootstrap+asp.net mvc4+IBatis.Net实现的小程序

    这个项目用到了三个技术点 1.bootstap 3.0 2.asp.net mvc4 3.IBatis.Net 这个三个技术点分别解决前端界面展示.中间mvc路由控制.实体框架映射数据访问 重点分页问 ...

  10. UVA 11722

    You are going from Dhaka to Chittagong by train and you came to know one of your old friends is goin ...