sizeof()大小总结

sizeof 运算符

查询对象或类型的大小
在需要知道对象的实际大小时使用
语法:

  1. sizeof(类型)
  2. sizeof 表达式

解释

  1. 返回 类型 的对象表示的字节数。
  2. 返回当 表达式 求值时所返回的类型的对象表示的字节数。
#include <iostream>
class A
{
};
int main()
{
	A a;
    std::cout<< sizeof a <<endl; //OK 1
    //std::cout<< sizeof A <<endl; //Error 可以是变量,但是不能是类型或者类,A是类
    int Int1;
    std::cout << sizeof Int1 << endl;
    //std::cout << sizeof int << endl; //Error 可以是变量,但是不能是类型或者类,int是类型
    std::cout << sizeof(float)<<endl; //OK  4,32编译器,float大小是4个字节
    std::cout << sizeof(bool) <<endl;//OK 1,bool虽然只有一位,但是字节对齐,也是1一个字节
    std::cout << sizeof(long) <<endl;//OK 4
    std::cout << sizeof(long long) <<endl;//OK 8
    return 0;
}
int i = 0;
A) sizeof(int); B)sizeof(i); C) sizeof i; D)sizeof int;

通过对比之后,除了D,其他都是正确的。所以如果可以的话,我们最好使用sizeof();

1.基本数据类型的sizeof

基本类型包括:bool ,char, short, int, long ,long long,float,double
32位编译器
指针都是4位

数据类型 大小
bool 1
char 1
short 2
int 4
long 4
long long 8
float 4
double 8

64位编译器
指针都是8位

数据类型 大小
bool 1
char 1
short 2
int 4
long 8
long long 8
float 4
double 8

2.结构体

结构体的sizeof涉及到字节对齐问题
注意:空结构体(不含数据成员)的sizeof值为1。这个和类是一样的。

struct A  
{  
    char a;  
    int b;  
};  
sizeof(A); //值为8,字节对齐,在char之后会填充3个字节。  
  
struct B
{  
    int b;  
    char a;  
};  
sizeof(B); //值为8,字节对齐,在char之后会填充3个字节。  
  
struct C
{  
};  
sizeof(C); //值为1,空结构体也占内存

3.联合体

联合体是共享一段内存,其中最大的变量大小。
因为long long和double都是8个字节。

其中char str[21]本来最大内存是21个字节,但是是4字节对齐,所以需要补齐后面3个字节,所以大小是24字节

union u
{
    bool b;
    short s;
    int i;
    float f;
    double d;
    long l;
    long long ll;
    char str[21];
};
cout <<sizeof(u)<<endl; //值为24

4.数组大小

    char str[]="abcd";//大小是5,因为后面还有一个'\0',所以要+1
    char *pStr="abcd";//大小是4,32系统,这里pStr是指针
void funA(char a[5])
{
	int len = sizeof(a);// len = 4,这函数里面,a不是数组类型,而是指针,所以大小是4
}

void funB(char a[])
{
	int len = sizeof(a);// len = 4,这函数里面,a不是数组类型,而是指针,所以大小是4
}

5.指针

指针是用来记录另一个对象的地址,所以指针的内存大小当然就等于计算机内部地址总线的宽度。
在32位编译器中,一个指针变量的返回值必定是4。
指针变量的sizeof值与指针所指的对象没有任何关系。

char* str="123";
cout<<sizeof(str)<<endl;//4//这里是一个变量的大小
cout<<sizeof(*str)<<endl;//1,这里指的是一个char的大小
char *c[22];
cout<<sizeof(c)<<endl;//88,因为一个指针大小是4,22个指针就是88,所以大小是88
double *d; 
cout<<sizeof(d)<<endl;//4,这里是指针的大小
cout<<sizeof(*d)<<endl;//8,这里是一个double变量的大小
long long **L;
cout<<sizeof(L)<<endl;//4,指针大小
cout<<sizeof(*L)<<endl;//4,指针大小
 cout<<sizeof(**L)<<endl;//8,long long 大小
void (*pf)();//这是一个函数指针
cout<<sizeof(pf)<<endl;//4,指针大小

6.函数

int fun()
{
    return 9;
}
double funD()
{
    return 1.1;
}
void funV()
{

}

int test06()
{
    cout<<sizeof(fun())<<endl; //4,相当于sizeof(int)
    cout<<sizeof(int)<<endl;//4
    cout<<sizeof(funD())<<endl; //8,相当于sizeof(double)
    cout<<sizeof(double)<<endl;//8
    cout<<sizeof(funV())<<endl;//1,相当于sizeof(void)
    cout<<sizeof(void)<<endl;//1
    void (*fv)();
    fv = funV;
    cout<<sizeof(fv)<<endl;//4,指针大小
	double (*df)(double,double);
    df = funD;
    cout<<df(1.3,9.1)<<endl;//10.4
    cout<<sizeof(df)<<endl;//4,指针大小
    return 0;
}

7.类

注意不要说类的大小,是类的对象的大小.

首先,类的大小是什么?确切的说,类只是一个类型定义,它是没有大小可言的。 用sizeof运算符对一个类型名操作,得到的是具有该类型实体的大小。

如果 Class A; A obj; 那么sizeof(A)==sizeof(obj) 那么sizeof(A)的大小和成员的大小总和是什么关系呢,很简单,一个对象的大小大于等于所有非静态成员大小的总和。

空类

#include <iostream>
using namespace std;
class A
{

};
class B
{
public:
    void fun(){}
    B(){}
    ~B(){}
};
class C
{
public:
    C(){}
    virtual ~C(){}
    virtual void fun(){}
};


int main()
{
    cout<<sizeof(A)<<endl;//1,类的大小不为0,空类大小为1
    cout<<sizeof(B)<<endl;//1,类中普通函数没有大小
    cout<<sizeof(C)<<endl;//4,类C中包含虚函数,编译器会在给类中生成一个虚函数表,
    					//并在该类型的每一个实例中添加一个指向虚函数表的指针。
  						  //在32位的机器上,一个指针占4个字节的空间,因此sizeof(C)是4,
  						  //而且不论有多少个虚函数,都是一个指针大小


    return 0;
}

struct S
{
    char c;
};

class C
{
public:
    C(){}
    virtual ~C(){}
    virtual void fun(){}
};
class D {

    char ch;

    void func() { }

};

class E {

    char ch1; //占用1字节

    char ch2; //占用1字节

    virtual void func() { }

};
class E_2 {

    char ch1; //占用1字节

    int i1; //4

    char ch2; //占用1字节

    virtual void func() { }

};
class F {

     float f;

    virtual void func() { }

};

int test02()
{
    cout<<sizeof(D)<<endl;//1
    cout<<sizeof(E)<<endl;//8
    cout<<sizeof(E_2)<<endl;//16
    cout<<sizeof(F)<<endl;//8
    cout<<sizeof(S)<<endl;//1
    return 0;
}

这里我们发现,如果只有一个字节,那么就不用对齐什么的了,如果大小不是1,那么我们就要注意字节对齐,如类E,和类E_2,在两个char型之间,加了一个int型,就导致大小变成了16,因为第一个char型虽然只有1位,但是为了字节对齐,就变成了4字节,同样的是后面一个char型,也是一样,所以就变成了4+4+4+4 = 16.

求含有静态数据成员的类的大小

class T {
private:
    int data = 2;
    static char c;
};
cout<<sizeof(T)<<endl; //4

求继承类的大小

#include <iostream>
using namespace std;
class A {};
class B {};
class C {char c;};
class D {int c;};
class C_1{char c;};
class E:public A{};
class F:public A,public B,public C{};
class G:public A,public B,public D{};
class H:public C,public D,public C_1{};
class H_1:public C,public C_1,public D{};
class H_2:public C,public C_1,public D,public B,public A{};
int main()
{
    cout<<sizeof(E)<<endl; //1
    cout<<sizeof(F)<<endl; //1//继承一个或者多个空类,派生类还是空类,大小还是为1
    cout<<sizeof(G)<<endl; //4
    cout<<sizeof(H)<<endl; //12,按照父类的顺序来字节对齐,
    cout<<sizeof(H_1)<<endl; //8,按照父类的顺序来字节对齐
    cout<<sizeof(H_2)<<endl;//8,最后B,A两个父类是空类,但是H_2类前面几个父类不是空类,所以就大小还是8
    return 0;
}

小结类的大小

1.为类的非静态成员数据的类型大小之和.

2.由编译器额外加入的成员变量的大小,用来支持语言的某些特性(如:指向虚函数的指针).

3.为了优化存取效率,进行的边缘调整(对齐).

4 与类中的构造函数,析构函数以及其他的成员函数无关.

猜你喜欢

转载自blog.csdn.net/zqw_yaomin/article/details/82778604