C++面试题6:sizeof 使用规则及陷阱

C++面试题6:sizeof 使用规则及陷阱

cout << sizeof(int) << endl; //32位机上int长度是4cout << sizeof(1==2) << endl; //bool类型,相当于cout << sizeof(bool) << endl;1

陷阱:
int a=0;
cout << sizeof(a=3) << endl; //sizeof作用范围内,也就是括号里面的内容不能被编译,而是被替换成类型,=操作符返回左操作数的类型,所以a=3相当于int   4cout << a << endl;    //输出0

结论:不要把sizeof当成函数,也不要看作一元操作符,把他当成一个特殊的编译预处理。

sizeof两种用法:

  • sizeof(object) 对对象使用
  • sizeof(typename) 对类型使用,这里要注意一定要使用括号。
cout << sizeof int << endl;  错误,要加上()
cout << sizeof 2 << endl; 正确

结论:无论sizeof要对谁取值,最好加上()

数据类型的sizeof

32位C++中的基本数据类型,也就是char,short int(short), int, long int(long),
float, double, long double
大小分别为1,2,4,4,8,10

cout<<sizeof(unsigned int) == sizeof(int)<<endl; // 相等,输出 1

结论:unsigned不影响sizeof的取值

int f1(){return 0;};
double f2(){return 0.0;}
void f3(){} 

cout<<sizeof(f1())<<endl; // f1()返回值为int,因此被认为是intcout<<sizeof(f2())<<endl; // f2()返回值为double,因此被认为是doublecout<<sizeof(f3())<<endl; // 错误!无法对void类型使用sizeofcout<<sizeof(f1)<<endl; // 错误!无法对函数指针使用sizeof cout<<sizeof*f2<<endl; // *f2,和f2()等价,因为可以看作object,所以括号不是必要的。被认为是double

结论:对函数使用sizeof,在编译阶段会被函数返回值的类型取代

指针问题:

结论:主要是指针,大小就是4

数组问题:

char a[] = "abcdef";
int b[20] = {3, 4};
char c[2][3] = {"aa", "bb"};

cout<<sizeof(a)<<endl; // 7cout<<sizeof(b)<<endl; // 20*4cout<<sizeof(c)<<endl; // 6

结论:数组的大小是各维数的乘积*数组元素的大小。

陷阱:

int *d = new int[10];
cout<<sizeof(d)<<endl; // 4
这里一定要注意d是我们常说的动态数组,但是他实质上还是一个指针,所以sizeof(d)的值时4

指针数组问题:

double* (*a)[3][6];     //a是执行double*[3][6]类型数组的指针
cout<<sizeof(a)<<endl; // 4     a是执行double*[3][6]类型数组的指针
cout<<sizeof(*a)<<endl; // 72   *a是一个double*[3][6]多维数组类型3*6*sizeof(double*)=72cout<<sizeof(**a)<<endl; // 24  **a表示一个double*[6]类型数组 6*sizeof(double*)=24cout<<sizeof(***a)<<endl; // 4  ***a表示一个元素,也就是double*,4cout<<sizeof(****a)<<endl; // 8 ****ad表示一个double 所以大小为4

字符串的sizeof和strlen

char a[] = "abcdef";
char b[20] = "abcdef";
string s = "abcdef"; 

cout<<strlen(a)<<endl; // 6,字符串长度cout<<sizeof(a)<<endl; // 7,字符串容量cout<<strlen(b)<<endl; // 6,字符串长度cout<<sizeof(b)<<endl; // 20,字符串容量cout<<sizeof(s)<<endl; // 12, 这里不代表字符串的长度,而是string类的大小cout<<strlen(s)<<endl; // 错误!s不是一个字符指针。 

a[1] = ‘\0‘;
cout<<strlen(a)<<endl; // 1cout<<sizeof(a)<<endl; // 7,sizeof是恒定的

总结:strlen是寻找从指定地址开始,到出现的第一个0之间的字符个数,在运行阶段执行的,而sizeof是得到数据的大小,在这里得到是字符串的容量。所以对于同一个对象而已,sizeof的值时恒定的,string是C++类型的字符串,它是一个类,strlen(s)是错误的,应该使用strlen(s.c_str())因为string的成员函数c_str()返回的是字符串的首地址;实际上string封装了常用的字符串操作,Capacity()和Length()。所以在开发过程中最好使用string代替C类型的字符串。

从union的sizeof问题看cpu的对界

union u
{
 double a;
 int b;
}; 

union u2
{
 char a[13];
 int b;
}; 

union u3
{
 char a[13];
 char b;
}; 

cout<<sizeof(u)<<endl; // 8cout<<sizeof(u2)<<endl; // 16cout<<sizeof(u3)<<endl; // 13

结论:复合数据类型,如union,struct,class的对齐方式为成员中对齐方式最大的成员的对齐方式。

struct的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; // 24cout<<sizeof(s2)<<endl; // 16

这里有一个陷阱:

对于结构体中的结构体成员,不要认为它的对齐方式就是他的大小,看下面的例子:

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; // 8cout<<sizeof(s2)<<endl; // 8cout<<sizeof(s3)<<endl; // 9cout<<sizeof(s4)<<endl; // 16;
s1和s2大小虽然都是8,但是s1的对齐方式是1,s2是8(double),所以在s3和s4中才有这样的差异

结论:在自己定义结构体的时候,如果空间紧张的话,最好考虑对齐因素来排列结构体里的元素。

不要让double干扰你的位域

在结构体和类中,可以使用位域来规定某个成员所能占用的空间,所以使用位域能在一定程度上节省结构体占用的空间。不过考虑下面的代码:

struct s1
{
 int i: 8;
 int j: 4;
 double b;
 int a:3;
}; 

struct s2
{
 int i;
 int j;
 double b;
 int a;
}; 

struct s3
{
 int i;
 int j;
 int a;
 double b;
}; 

struct s4
{
 int i: 8;
 int j: 4;
 int a:3;
 double b;
}; 

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

结论:有double存在会干涉到位域(sizeof的算法参考上一节),所以使用位域的的时候,最好把float类型和double类型放在程序的开始或者最后。

时间: 2024-08-26 03:18:51

C++面试题6:sizeof 使用规则及陷阱的相关文章

【转】【C++专题】C++ sizeof 使用规则及陷阱分析

提示:下文例子都经过Visual C++ 6.0验证,平台为win32 Windows. 一.什么是sizeof 首先看一下sizeof在msdn上的定义: The sizeof keyword gives the amount of storage, in bytes, associated with a variable or a type (including aggregate types). This keyword returns a value of type size_t. 看到

C/C++ 知识点---sizeof使用规则及陷阱分析

原文:http://blog.csdn.net/chenqi514/article/details/7245273 1.什么是sizeof 首先看一下sizeof在msdn上的定义:     The sizeof keyword gives the amount of storage, in bytes, associated with a variable or a type (including aggregate types). This keyword returns a value o

c语言面试题之sizeof

*/--> c语言面试题之sizeof Table of Contents 1. sizeof 1 sizeof sizeof是c语言中判断数据类型或者表达式的长度符,它不是函数,,字节数的计算在程序编译 时进行,而不是在程序执行的过程中才计算出来!(文采不行,我就废话下了,接下来上重点)! #include int main(int argc, char* argv[]) { char str[]="123"; char *p=str; printf("%d\n&qu

指针的大小--sizeof问题和sizeof使用规则

 1.什么是sizeof 首先看一下sizeof在msdn上的定义: The sizeof keyword gives the amount of storage, in bytes, associated with a variable or a type (including aggregate types). This keyword returns a value of type size_t. 看到return这个字眼,是不是想到了函数?错了,sizeof不是一个函数,你见过给一个

完美C++(第5版)(双色)

完美C++(第5版)(双色) 薛正华 沈庚 韦远科 译 ISBN 978-7-121-23198-8 2014年6月出版 定价:148.00元 788页 16开 内容提要 <完美C++(第5版)>为读者提供了一个学习.理解和掌握 C++编程语言的全面视图,覆盖面广.实用性强.书中介绍了 C++的基本数据类型,如字符串.数组.指针.结构体.类等,同时也详细描述了面向对象编程语言的特性:封装.继承和多态,以及这些特性在 C++语言中的具体使用方式.本书的后面章节还重点介绍了模板.链式数据结构.标准

C++面试题5:建议在函数里面不要用sizeof算数组的大小

C++面试题5:建议在函数里面不要用sizeof算数组的大小 #include <iostream>using namespace::std; void foo(const int[]); int main() { int arr[3] = {1,2,3}; cout<<"in main array size: "<<sizeof(arr)/sizeof(int)<<endl; foo(arr); } void foo(const int

常问面试题:C++中sizeof的陷阱及应答

C++中sizeof是经常被问到的一个概念,比如,下面的几个关于sizeof的面试题反复出现在各大IT公司的技术面试当中,我们有必要完全理解并掌握.注:在曾经面试大公司时,我的确被问到过这样的问题. 面试题:定义一个空的数据类型,里面没有任何成员变量和成员函数,对该类型求sizeof,得到的结果是多少? 答案:是1,为什么不是0?空类型的实例中不包含任何信息,本来求sizeof应该是0,但是当我们声明该类型的实例时,它必须在内存中占有一定的空间,否则无法使用这些实例(也就不能求sizeof了),

[笔试题]sizeof系列面试题中的易错之处

sizeof系列笔试题看似简单,其实如果不深入探究,很容易出错,本人就有时败在了这,特写篇博客总结一番,引以为戒. V1.0 32位和64位编译器的区别 测试代码如下: #include "stdafx.h" #include <iostream> using namespace std; int main() { //32和64位编译器区别: 除了*与long随操作系统子长变化而变化外,其他的都固定不变(32位和64相比) //32: sizeof(*)=4 sizeof

[C++常见面试笔试题汇总] 程序设计基础 - 内存分配、sizeof、指针篇

2 内存分配 系统蓝屏,很大原因都是系统自身代码有缺陷引起的,而系统代码缺陷很大程度上与内存分配不当有关.由于内存分配不当引起的堆栈溢出.缓冲区溢出等问题,常常会导致系统瘫痪甚至崩溃,所以理解内存分配对于一名合格的程序员而言非常有必要. 2.1 内存分配的形式有哪些? 一个C/C++编译的程序所占用的系统内存一般分为以下几个部分的内容: (1) 由符号起始的区块(Block Started by Symbol, BSS)段:BSS段通常是指用来存放程序中未初始化的全局数据和静态数据的一块内存区域