类型及字节长度

1.不同系统下基本类型的长度

  各个类型的变量长度由编译器来决定(实际上与操作系统位数和编译器都有关)使用时可用sizeof()得到,当前主流编译器一般是32位或64位。

基本类型 16位 32位 64位
bool 1 1 1
char 1 1 1
char* 代表指针大小,与操作相关 2 4 8
short (int) 2 2 2
int 2 4 4
unsigned int 2 4 4
long (int) 4 4 8
unsigned long 4 4 8
long long (int) 8 8 8
float 4 4
double 8 8 8

  注:指针类型存储是指所指向变量的地址,32位机只需32 bit,64位机需要64 bit。

2.sizeof和strlen的区别

  1. 例子1:char* ss = "0123456789";
      1、sizeof(ss)的结果是4,ss是指向字符串常量的字符指针
      2、sizeof(*ss)的结果是1,*ss是第一个字符
  2. 例子2:char ss[] = "01233456789";
      1、sizeof(ss)结果是11,ss是数组,计算到'/0'的位置,因此是10+1
      2、sizeof(*ss)结果是1,*ss是第一个字符
  3. 例子3:char ss[100] = "0123456789";
      1、sizeof(ss)的结果是100,ss表示在内存中预分配的大小:100*1
      2、strlen(ss)的结果是10,它的内部实现是用一个循环计算字符串的长度,直到'/0'为止。不包含\0
  4. 例子4:int ss[100] = "0123456789";
      1、sizeof(ss)的结果是400,ss表示在内存中的大小,为1004
      2、strlen(ss)错误,strlen的参数只能是char
    ,且必须是以'/0'结尾的。

3.C++类长度

 #include <iostream>
 using namespace std;
 class A{};
 class B
 {
     int b;
     char c;
 };
 class C
 {
     int c1;
     static int c2;
 };
 int C::c2 = 1;
 class D:public C,public B{
     int d;
 };
 int main()
 {
     cout<<"sizeof(A)="<<sizeof(A)<<endl;
     cout<<"sizeof(B)="<<sizeof(B)<<endl;
     cout<<"sizeof(C)="<<sizeof(C)<<endl;
     cout<<"sizeof(D)="<<sizeof(D)<<endl;
     return 0;
 }

///运行结果为:
sizeof(A)=1
sizeof(B)=8
sizeof(C)=4
sizeof(D)=16

  对于类A来说,虽然A是一个空类,但为了便于空类进行实例化,编译器往往会给它分配一个字节,这样A实例化后便在内存中有了一个独一无二的地址.对于类B,B的大小应为sizeof(int)+sizeof(char)=5,但是考虑内存对齐,B的大小应为8.对于类C,类的静态成员变量被放在全局区,和类的普通成员并没有放在一块。类的静态成员被声明后就已存在,而非静态成员只有类被实例化后才存在。所以C的大小为sizeof(int)=4。D的大小为B+C的大小+自身数据成员的大小,一共为16。

4.含虚函数的C++类长度

 #include <iostream>
 using namespace std;
 class A
 {
 public:
     void virtual aa(){};
 };
 class B:public A
 {
     void virtual bb(){};
 };
 class C:virtual A
 {
 public:
     void virtual aa(){};
     void cc(){};
 };
 class D:virtual A
 {
 public:
     void virtual dd(){};
 };
 int main()
 {
     cout<<"sizeof(A)="<<sizeof(A)<<endl;
     cout<<"sizeof(B)="<<sizeof(B)<<endl;
     cout<<"sizeof(C)="<<sizeof(C)<<endl;
     cout<<"sizeof(D)="<<sizeof(D)<<endl;
     return 0;
 }
运行结果为:
sizeof(A)=4
sizeof(B)=4
sizeof(C)=8
sizeof(D)=12

  对于class A,它含有一个虚函数,编译器会为虚函数生成一张虚函数表,来记录对应的函数地址,为此,在class A的内存地址中要有一个vfptr_A指针指向这个虚表,所以class A的大小为指针大小,即4.(注意,无论类中有多少个虚函数,它们的大小都是4,因为内存中只需要保存这个指针即可)。
  对于class B,它是public继承A,虽然它也有一个虚函数,但是从结果看,B应该和A都在B的vtable(虚表中),所以class B的大小为4。
  对于class C,它是vitual 继承A,所以要有一个指向父类A的指针,占有4字节大小aa()是继承自class A的虚函数,从结果来看,它没有在内存中占有空间,所以C的大小为sizeof(A)+4=8。
  对于class D,它是虚继承class A,同上,要有一个指向父类A的指针,同时,class D中有虚函数,所以要有一个指向虚表的指针,所以sizeof(D)=sizeof(A)+4+4=12。

发表评论

邮箱地址不会被公开。 必填项已用*标注