C++/C#类型大小汇总

基本类型

类型 含义 字节数 最小值 最大值
sbyte(c#) 有符号的8位整数 1 -128 127
byte(c#) 无符号的8位整数 1 0 255
short 有符号的16位整数 2 -32768 32767
ushort 16位无符号整数 2 0 65535
int 有符号32位整数 4 -2147483648 2147483647
uint 无符号32位整数 4 0 4294967295
long 有符号64位整数 8(64位)/4(32位) -9223372036854775808 9223372036854775807
ulong 无符号64位整数 8 0 18446744073709551615
decimal(C#) 128 位精确的十进制值,28-29 有效位数 -7.9 x 10^28 7.9 x 10^28
double 64 位双精度浮点型 8 5.0 x 10^-324 1.7 x 10^308
float 32 位单精度浮点型 4 -3.4 x 10^38 3.4 x 10^38
char 16 位 Unicode 字符 2(C#)/1(C++)
bool 布尔值 1

特殊类型

  • string 占32个字节
  • 指针在32位系统占4字节,在64位占8字节

内存对齐

在存储一个结构体或者类时CPU会进行内存对齐。

内存对齐的原则:按照顺序,把每个数据放在min(当前数据大小,系统对齐值)的整数倍上。系统对齐值在32位上默认为4,64位上默认为8.也可以自己重新定义。

下面为举例,假设系统为32位。

struct asd3{
    char a;
    char b;
    short c;
    int d;
};//8字节
 
struct asd4{
    char a;
    short b;
    char c
    int d;
};//12字节

 asd3对齐过程:

a数据大小为1,放在第0位;

b数据大小为1,1是它的整数倍,放在第1位上;

c数据大小为2,2是它的整数倍,放在第2位上;

d数据大小为4,放在第4位上.

 asd4对齐过程:

a数据大小为1,放在第0位;

b数据大小为2,1不是它的整数倍,2是它的整数倍,放在第2位上;

c数据大小为1,4是它的整数倍,放在第4位上;

d数据大小为4,5,6,7都不是它的整数倍,放在第8位上.


struct asd1{
	char a;
	int b;
	short c;
	double d;
};//20个字节

 asd1对齐过程:

a数据大小为1,放在第0位;

b数据大小为4,1,2,3都不是它的整数倍,放在第4位上;

c数据大小为2,8是它的整数倍,放在第8位上;

d数据大小为8,大于系统对齐值4,10,11,都不是4的整数倍,放在第12位上.

内存对齐的意义在于:不浪费太多内存的情况下,尽可能提高数据访问读取的效率。

类的大小

首先,类的大小与普通数据成员、虚函数、继承关系有关,与普通成员函数,静态成员函数,静态数据成员,静态常量数据成员无关。

存在继承时,内存先加上基类的大小;存在虚函数时,先计算虚函数指针的大小,注意虚函数无论有几个都只算一个指针(包括基类的在内);最后是数据成员本身的大小。以上这些计算都遵循内存对齐的原则。

特殊地,空类本身占一个字节,若被继承时,算作0字节。

class A     
{     
};    

class B     
{  
    char ch;     
    virtual void func0()  {  }   
};   

class C    
{  
    char ch1;  
    char ch2;  
    virtual void func()  {  }    
    virtual void func1()  {  }   
};  

class D: public A, public C  
{     
    int d;     
    virtual void func()  {  }   
    virtual void func1()  {  }  
};     
class E: public B, public C  
{     
    int e;     
    virtual void func0()  {  }   
    virtual void func1()  {  }  
};  

int main(void)  
{  
    cout<<"A="<<sizeof(A)<<endl;    //result=1  
    cout<<"B="<<sizeof(B)<<endl;    //result=16     
    cout<<"C="<<sizeof(C)<<endl;    //result=16 
    cout<<"D="<<sizeof(D)<<endl;    //result=24 
    cout<<"E="<<sizeof(E)<<endl;    //result=40  
    return 0;  
}  

1.A为空类,所以大小为1
2.B的大小为char数据成员大小+vptr指针大小。由于字节对齐,大小为8+8=16
3.C的大小为两个char数据成员大小+vptr指针大小。由于字节对齐,大小为8+8=16
4.D为多继承派生类,由于D有数据成员,所以继承空类A时,空类A的大小1字节并没有计入当中,D继承C,此情况D只需要一个vptr指针,所以大小为数据成员加一个指针大小。由于字节对齐,大小为16+8=24
5.E为多继承派生类,含虚函数覆盖的情况。此时大小计算为基类大小加本地数据。考虑字节对齐,结果为16+16+8=40

猜你喜欢

转载自blog.csdn.net/qq_43533956/article/details/124471822
今日推荐