zoukankan      html  css  js  c++  java
  • 关于sizeof的笔试面试题具体解释

    原创Blog,转载请注明处处

     http://blog.csdn.net/hello_hwc

    注意:sizeof是编译期计算出结果的,这一点对后面的理解非常重要

    一、关于结构体

    先看下代码

    #include "stdafx.h"
    #include <iostream>
    using namespace std;
    typedef struct  
    {
    	char a:3;
    	char b:3;
    	char c:3;
    	char d:3;
    	char e:3;
    }test1;
    typedef struct  
    {
    	char a:3;
    	char b:4;
    	char c:5;
    	char d:6;
    	char e:7;
    }test2;
    typedef struct  
    {
    	char a:1;
    	char b:2;
    	char c:3;
    	char d:4;
    	char e:5;
    }test3;
    typedef struct{
    	int a;
    	char b;
    	char d;
    	long c;
    }test4;
    typedef struct{
    	int a;
    	char b;
    	long c;
    	char d;
    }test5;
    
    
    int _tmain(int argc, _TCHAR* argv[])
    {
    	cout<<sizeof(test1)<<endl;
    	cout<<sizeof(test2)<<endl;
    	cout<<sizeof(test3)<<endl;
    	cout<<sizeof(test4)<<endl;
    	cout<<sizeof(test5)<<endl;
    	return 0;
    }
    然后贴上执行结果


    解释下为什么

    1、对于test1,结果是3Byte。有些同学好奇,3bit*5 = 15bit。不是应该占用2Byte吗?但是计算机没你大脑智能。它管理bit的方式是8bit一组。所以对于一组8bit,仅仅能放下两个3bit,另外2bit没用。所以,对于test1来说。三个Byte是这么分配的。

    1Byte(3bit,3bit,2bit填充)2Byte(3bit,3bit,2bit填充)3Byte(3bit,5bit填充)

    2、对于test2结果是4Byte.有了test1的解释,这里不难理解了吧。我再解释下内存分配。

    1Byte(3bit,4bit,1bit填充)2Byte(5bit,3bit填充)3Byte(6bit,2bit填充)4Byte(7bit,1bit填充)

    3、test3结果是3Byte。和上述两个类似

    4、test4的结果是12。为什么不是4+1+1+4呢?(我这里long是4Byte),由于C++对于Byte的管理仍然要内存对齐。我这里的内存对其是4Byte。所以。内存占用是这种4Byte(Int)4Byte(char,char,2Byte填充)4Byte(long)

    5、有些同学会好奇。为什么两个结构体声明换了个顺序,差了4Byte。

    相同是由于内存对齐


    二、字符串与char*和char数组

    // testforyou.cpp : Defines the entry point for the console application.
    //
    
    #include "stdafx.h"
    #include <iostream>
    #include <string>
    using namespace std;
    
    
    int _tmain(int argc, _TCHAR* argv[])
    {
    	string s = "hellohwc";
    	char * s1 = "hellohwc";
    	char s2[] = "hellohwc";
    	char s3[100];
    	char* s4=(char*)malloc(100);
    	void *s5=(void*)malloc(100);
    	cout<<sizeof(s)<<endl;
    	cout<<sizeof(s1)<<endl;
    	cout<<sizeof(s2)<<endl;
    	cout<<sizeof(s3)<<endl;
    	cout<<sizeof(s4)<<endl;
    	cout<<sizeof(s5)<<endl;
    	return 0;
    }
    
    执行结果


    解释下

    对于String类型。每一个编译器给分配内存的空间都是一定的。我这里是32Byte。

    所以,无论字符串长度多长,内存分配都是32。当然也有4,16等情况,因编译期不同而不同。

    1、char * s1,s1本身是个指针,所以长度是4个字节,跟后面指向什么没关系。

    2、s2是数组保存了一个字符串。因为字符串最后一个隐藏的结束符。

    所以,长度为8+1 = 9

    3、s3是数组。在编译期分配了100*1 = 100Byte,所以结果是100

    4、s4和s5都是指针,长度4Byte。

    三、类

    先看代码

    // testforyou.cpp : Defines the entry point for the console application.
    //
    
    #include "stdafx.h"
    #include <iostream>
    #include <string>
    using namespace std;
    
    class emptyClass1{
    public:
    	emptyClass1(){}
    	~emptyClass1(){}
    };
    class emptyClass2{
    public:
    	emptyClass2(){}
    	virtual ~emptyClass2(){}
    };
    class hwcBase{
    public:
    	hwcBase(){}
    	virtual  ~hwcBase(){}
    private:
    	int base;
    };
    
    class hwcSubFirst:hwcBase{
    public:
    	hwcSubFirst():hwcBase(){}
    	~hwcSubFirst(){}
    private:
    	int sub;
    };
    
    class hwcSubSecond:hwcBase{
    public:
    	hwcSubSecond():hwcBase(){}
    	~hwcSubSecond(){}
    private:
    	int sub;
    	char sub2;
    };
    
    int _tmain(int argc, _TCHAR* argv[])
    {
    	cout<<sizeof(emptyClass1)<<endl;
    	cout<<sizeof(emptyClass2)<<endl;
    	cout<<sizeof(hwcBase)<<endl;
    	cout<<sizeof(hwcSubFirst)<<endl;
    	cout<<sizeof(hwcSubSecond)<<endl;
    	return 0;
    }

    执行结果


    解释下:

    1、对于一个空的类。在内存中要存在一个标示来区分,所以即使是空的。也要分配一个字节

    2、相同是empty的类,可是有一个虚的析构函数,所以,保存了一个指针(vptr)指向虚表。

    一个指针4Byte

    3、hwcBase类,有一个Int占用4Byte,一个指针(vptr)。所以共占用8Byte

    3、hwcSubFirst,继承来一个Int,本身有一个Int。加上一个vptr指针,共12字节

    4、hwcSubSecond,和hwcSubFirst类似,可是多了一个char,考虑到内存对其。12+4 = 16字节


  • 相关阅读:
    Cocos2dx 3.0 过渡篇(二十五)死不了的贪食蛇(触摸版)
    IBinder对象在进程间传递的形式(一)
    【代码实现】PHP生成各种随机验证码
    win8 metro 调用摄像头拍摄照片并将照片保存在对应的位置
    薏米红豆粥功效及做法介绍
    应用程序无法正常启动0xc0150002 解决方式
    贪心算法
    Linux 进程通信之 ——信号和信号量总结
    关于 ioctl 的 FIONREAD 參数
    google域名邮箱申请 gmail域名邮箱申请(企业应用套件)指南
  • 原文地址:https://www.cnblogs.com/zfyouxi/p/5124015.html
Copyright © 2011-2022 走看看