C++ sizeof和数据对齐,变量,结构体,类,静态成员函数,共用体,带位域,指定对齐字节数以及sizeof和strlen的区别

目录

 

1.sizeof是C语言保留关键字,也可以认为是一种运算符,单目运算符。

2.对于一个结构体进行sizeof运算

3.类的sizeof运算

3.1 空类的大小

3.2 类中的成员函数与非虚成员函数

3.3 派生类与基类

3.4 虚表与类数据成员

3.5 类的数据成员

3.6 static 数据成员不占用类的空间,对其派生类亦是如此

3.7 让类和数据成员一字节对齐:#pragma pack(n) //n即为对齐的字节数

4 联合体:最长成员的大小对齐

5 带位域:

 6.sizeof和strlen的区别


1.sizeof是C语言保留关键字,也可以认为是一种运算符,单目运算符。

例1:

编译器pack指令 #pragma pack(n)——定义n字节对齐
C++固有类型的对齐取编译器对齐与自身大小中较小的一个
32位C++默认8字节对齐。gcc编译器默认4字节对齐
static变量在静态区,sizeof均不纳入计算
在编译阶段处理,sizeof作用范围内的内容不能被编译,所以sizeof()内的运算不被执行
sizeof(函数)=sizeof(返回值类型)
sizeof和strlen:sizeof计算字符串容量,算’\0’,strlen计算字符串长度,到’\0’截止

#include <stdio.h>
#include <stdlib.h>
int main()
{	
	int a = 10;
	int arr[3] = { 1, 2, 3 };
	char str[] = "hello";
	int len_a = sizeof(a);
	int len_arr = sizeof(arr);
	int len_str = sizeof(str);
	printf("len_a=%d,len_arr=%d,len_str=%d\n", len_a, len_arr, len_str);
	system("pause");
    return 0;
}

执行结果:

sizeof实际上是获取了数据在内存中所占用的存储空间,以字节为单位来计数。

C语言会自动在在双引号""括起来的内容的末尾补上"\0"代表结束,ASCII中的0号位也占用一个字符。

2.对于一个结构体进行sizeof运算

#include "stdafx.h"
#include <stdio.h>
#include <stdlib.h>
struct student
{
	double d;
	int id;
	char digit;
};
int main()
{
	printf("sizeof(student)=%d\n", sizeof(student));
	system("pause");
	return 0;
}

 运算结果:

结构体的总大小为结构体最宽基本类型成员大小的整数倍

3.类的sizeof运算

3.1 空类的大小

class student1
{};

int main()
{	
	printf("sizeof(student1)=%d\n", sizeof(student1));
	system("pause");
    return 0;
}

输出结果:

C++中空类的大小是1,这是因为空类也可以被实例化,为了确保每一个实例在内存中都有一个独一无二的地址,编译器往往隐含给一个空类加一个字节。

3.2 类中的成员函数与非虚成员函数

类中的非虚成员函数不占用空间,虚函数表占用四个字节,只要有虚函数(无论有几个)都只占用四个字节。

class student
{
	int id;
	char ch;
private:
	void add() {};
	void del() {};
	/*virtual int get() { return id; }*/
};

int main()
{	
	printf("sizeof(student)=%d\n", sizeof(student));
	system("pause");
    return 0;
}

运行结果:

 

类成员函数具有虚函数

class student
{
	int id;
	char ch;
private:
	void add() {};
	void del() {};
	virtual int get() { return id; }
	virtual int print() { printf("Hello world!"); }
};

int main()
{	
	printf("sizeof(student)=%d\n", sizeof(student));
	system("pause");
    return 0;
}

运行结果:

 

3.3 派生类与基类

派生类继承基类的所有成员(包括私有数据成员),派生类的大小是在基类的大小的基础上再增加自己数据成员的空间。

class student
{
	int id;
	char ch;
private:
	void add() {};
	void del() {};
	virtual int get() { return id; }
	virtual int print() { printf("Hello world!"); }
};

class StudentScore :public student
{
private:
	int scores;
	char ch2;
};

int main()
{	
	printf("sizeof(student)=%d\n", sizeof(student));
	printf("sizeof(StudentScore)=%d\n", sizeof(StudentScore));
	system("pause");
    return 0;
}

 运行结果:

3.4 虚表与类数据成员

虚函数表首先存入内存中,然后是数据成员。

3.5 类的数据成员

类的数据成员按其声明顺序加入内存,(与其访问权限无关,即无论public,private,protected的数据成员,只看其声明顺序)

3.6 static 数据成员不占用类的空间,对其派生类亦是如此

  • static变量在静态区,sizeof均不纳入计算
class student
{
	int id;
	char ch;
	static int count;
private:
	void add() {};
	void del() {};
	virtual int get() { return id; }
	virtual int print() { printf("Hello world!"); }
};

class StudentScore :public student
{
private:
	int scores;
	char ch2;
};
int student::count = 0;
int main()
{	
	printf("sizeof(student)=%d\n", sizeof(student));
	printf("sizeof(StudentScore)=%d\n", sizeof(StudentScore));
	system("pause");
    return 0;
}

运行结果:

3.7 让类和数据成员一字节对齐:#pragma pack(n) //n即为对齐的字节数

#include <stdio.h>
#include <stdlib.h>
#pragma pack(1)
class student1
{};

class student
{
	int id;
	char ch;
	static int count;
private:
	void add() {};
	void del() {};
	virtual int get() { return id; }
	virtual int print() { printf("Hello world!"); }
};

class StudentScore :public student
{
private:
	int scores;
	char ch2;
};
int student::count = 0;
int main()
{	
	printf("sizeof(student)=%d\n", sizeof(student));
	printf("sizeof(StudentScore)=%d\n", sizeof(StudentScore));
	system("pause");
    return 0;
}

运行结果:

4 联合体:最长成员的大小对齐

union MyUnion
{
	double d;
	int id;
	char digit;
};
struct student
{
	double d;
	int id;
	char digit;
};
int main()
{
	printf("sizeof(student)=%d\n", sizeof(student));
	printf("sizeof(MyUnion)=%d\n)", sizeof(MyUnion));
	system("pause");
	return 0;
}

运行结果:

5 带位域:

相邻位域字段的两个变量若类型相同,当两个字段位宽和小于此类型大小时,二者紧邻存储;若二者位宽和大于本类型大小,则第二个字段从新存储单元开始,偏移量为其类型大小整数倍。若相邻位域字段类型不同,则视编译器决定是否压缩存储,VC6不压缩,Dec-C++压缩。如果位域字段间穿插着非位域字段,不压缩。

#include "stdafx.h"
#include <stdio.h>
#include <stdlib.h>
struct BitField
{
	unsigned char a : 2;  //最低位;
	unsigned char b : 3;
	unsigned char c : 3;  //最高位;
};
int main()
{
	printf("sizeof(BitField)=%d\n", sizeof(BitField));
	system("pause");
	return 0;
}

 运行结果:


 6.sizeof和strlen的区别

sizeof计算字符串容量,算’\0’,strlen计算字符串长度,到’\0’截止

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值