C++面试题之sizeof面试题

//sizeof面试题1.cpp
//What is the output of the following code?
//[美国某著名计算机软硬件公司面试题]

#include<iostream>
#include<stdio.h>
#include<string.h>
using namespace std;
struct{
 short a1;
 short a2;
 short a3;
}A;
struct{
 long a1;
 short a2;
}B;

int main()
{
 char* ss1="0123456789";
 char ss2[]="0123456789";
 char ss3[100]="0123456789";
 int ss4[100];
 char q1[]="abc";
 char q2[]="a/n";
 char* q3="a/n";
 char* str1=(char*)malloc(100);
 void *str2=(void*)malloc(100);

 cout<<sizeof(ss1)<<" ";
 cout<<sizeof(ss2)<<" ";
 cout<<sizeof(ss3)<<" ";
 cout<<sizeof(ss4)<<" ";
 cout<<sizeof(q1)<<" ";
 cout<<sizeof(q2)<<" ";
 cout<<sizeof(q3)<<" ";
 cout<<sizeof(A)<<" ";
 cout<<sizeof(B)<<" ";
 cout<<sizeof(str1)<<" ";
 cout<<sizeof(str2)<<" ";

 return 0;
}


//解析:
//ss1是一个字符指针,指针的大小是一个定植,就是4。
//q2里面有一个"/n","/n"算做一位,所以它的空间大小是3。
//A 和B是两个结构体。在默认情况下,为了方便对结构体内元素的访问和管理,当结构体内的元素的长度都
//小于处理器的位数的时候,便以结构体里面最长的数据元素为对齐单位,也就是说,结构体的长度一定是
//最长的数据元素的整数倍。如果结构体内存在长度大于处理器位数的元素,那么就以处理器的位数为对齐
//单位。但是结构体内类型相同的连续元素将在连续的空间内,和数组一样。
//
//结构体A中有3个short类型变量,各自以2字节对齐,结构体对齐参数按默认的8字节对齐,则a1、a2、a3都
//取2字节对齐,sizeof(A)为6,其也是2的整数倍。B中a1为4字节对齐,a2 为2字节对齐,结构体默认对齐参数
//为8,则a1取2字节对齐;结构体大小6字节,6不为4的整数倍,增加到8时,符合所有条件,则sizeof(B)为8。
//
//CPU的优化规则大致原则是这样的:对于n字节的元素(n=2,4,8,...) ,它的首地址能被n整除,才能获得最好的
//性能。设计编译器的时候可以遵循这个原则:对于每一个变量,可以从当前位置向后找到第一个满足这个条件
//的地址作为首地址。例子比较特殊,因为即使采用这个原则,得到的结果也应该为6(long的首地址偏移量0000
//,short首地址偏移量0004,都符合要求)。但是结构体一般会面临数组分配的问题。编译器为了优化这种情况,
//干脆把它的大小设为8,这样就没有麻烦了,否则的话,会出现单个结构体的大小为6,而大小为n的结构体
//数组大小却为8*(n-1)+6的尴尬局面。IBM出这道题并不在于考查理解语言本身和编译器,而在于应聘者对
//计算机底层机制的理解和设计程序的原则。也就是说,如果让你设计编译器,你将怎样解决内存对齐的问题。

 

 

 

 

//sizeof面试题2.cpp
//What is the ouput of the following code?
//[德国某著名电子/通信/IT企业2005年11月面试题]
#include<iostream>
using namespace std;

class A{
};

class A2{
 char d,e;
};

struct B{
};

struct C{
 char b,c;
};

struct D{
 int x,y;
};

int main()
{
 cout<<sizeof(A)<<endl;
 cout<<sizeof(A2)<<endl;
 A *p1=new A();
 A p2;
    A *p3; 
 cout<<sizeof(p1)<<endl;
    cout<<sizeof(p2)<<endl;
 cout<<sizeof(p3)<<endl;
 cout<<sizeof(B)<<endl;
 cout<<sizeof(C)<<endl;
 cout<<sizeof(D)<<endl;
 return 0;
}

//解析:
// 对于一个类而言,即使它是一个空的类,编译器仍然要给它一个空间,所以类A即便什么都没有,它的空间大小
//依然是1。

 

 

 

 

//sizeof面试题3.cpp
//求解下面程序的结果。
//[中国某著名通信企业H面试题]
#include<iostream>
using namespace std;

class A1{
public:
 int a;
 static int b;
 A1();
 ~A1();
};

class A2{
public:
 int a;
 char c;
 A2();
 ~A2();
};

class A3{
public:
 float a;
 char c;
 A3();
 ~A3();
};

class A4{
public:
 float a;
 int b;
 char c;
 A4();
 ~A4();
};

class A5{
public:
 double d;
 float a;
 int b;
 char c,e;
 A5();
 ~A5();
};


int main()
{
 cout<<sizeof(A1)<<endl;
 cout<<sizeof(A2)<<endl;
    cout<<sizeof(A3)<<endl;
 cout<<sizeof(A4)<<endl; 
 cout<<sizeof(A5)<<endl;
 return 0;
}

//解析:
//因为静态变量是存放在全局数据区的,而sizeof计算栈中分配的大小,是不会计算在内的,所以sizeof(A1)
//是4。
//为了照顾数据对齐,int大小为4,char大小为1,所以sizeof(A2)是8。
// 为了照顾数据对齐,float大小为4,char大小为1,所以sizeof(A3)是8。
// 为了照顾数据对齐,float大小为4,int大小为4,char大小为1,所以sizeof(A4)是12。
// 为了照顾数据对齐,double大小是8,float大小为4,int大小为4,char大小为1,所以sizeof(A5)是24。


//数据对齐,是指数据所在的内存地址必须是该数据长度的整数倍。DWORD数据的内存起始地址能被4除尽,
//WORD数据的内存起始地址能被2除尽。x86 CPU能直接访问对齐的数据,当它试图访问一个未对齐的数据时,
//会在内部进行一系列的调整。
//这些调整对于程序来说是透明的,但是会降低运行速度,所以编译器在编译程序时会尽量保证数据对齐。
//同样一段代码,我们来看看用VC、Dev C++和LCC这3个不同的编译器编译出来的程序的执行结果:
//#include<stdio.h>
//int mainc()
//{
// int a;
// char b;
// int c;
// printf("0x%08x",&a);
// printf("0x%08x",&b);
// printf("0x%08x",&c);
// return 0;
//}
//这是用VC编译后的执行结果:
// 0x0012ff7c
// 0x0012ff7b
// 0x0012ff80
//变量在内存中的顺序:b(1字节)--a(4字节)--c(4字节)。

//这是用Dev C++编译后的执行结果:
// 0x0022ff7c
// 0x0022ff7b
// 0x0012ff74
//变量在内存中的顺序:c(4字节)--中间相隔3字节--b(占1字节)--a(4字节)。

//这是用LCC编译后的执行结果:
// 0x0012ff6c
// 0x0012ff6b
// 0x0012ff64
//变量在内存中的顺序:同上。

//三个编译器都做到了数据对齐,但是后两个编译器显然没VC“聪明”,让一个char占了4字节,浪费内存。




FROM: http://blog.csdn.net/lutongbin/article/details/6083813

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值