sizeof简单总结

对于sizeof,作个简单的总结:

在一个struct或者class里面定义的一些变量,如果是static类型的,则不算入sizeof计算范围(可能是因为创建对象时,static类型不属于某个特定的对象,而是属于这个类所有的对象,它在内存中不是和对象的变量一起存放的),一般的函数也不算入sizeof计算范围,虚函数则放到一个虚函数表中,有一个虚函数表指针指向这个表格。如果是单继承,则子类的大小是父类的大小加上自己的大小。

在一个struct或者class里面定义的变量,如果要计算其大小,那么首先应该找出类型最大的那个,然后以那个大小来进行“内存对齐”,最后就可以得到真实的大小了。

具体举例如下(部分测试代码来源于:http://blog.youkuaiyun.com/fanfanK/article/details/12175585)

#include<iostream>
#include<stdio.h>
using namespace std;

class TwoIntNoVirtual
{
	int a;
	int b;
	void function()
	{
		cout << "Hello" << endl;
	}
};
class TwoIntOneVirtual
{
	int a;
	int b;
	virtual void function()
	{
	}
};
class TwoIntTwoVirtual
{
	int a;
	int b;
	virtual void function()
	{
	}
	virtual void function2()
	{
	}
};
class TwoIntOneVirtualDerived : public TwoIntOneVirtual
{
	void function2()
	{
	}
};
class TwoIntTwoVirtualDerived : public TwoIntTwoVirtual
{
	void function()
	{
	}
	void function2()
	{
	}
};
class OtherTest
{
	char e, f, g, h, i, j, k;
	int a;
	int b;
	int c;
	long long d;
	virtual void function() {}
	virtual void function2() {}
};

class node0
{
public:
	int a;
	char b;
	short c;
	char d;
	double e;
};

int main()
{
	cout << "TwoIntNoVirtual: " << sizeof(TwoIntNoVirtual) << endl; // 8
	cout << "TwoIntOneVirtual: " << sizeof(TwoIntOneVirtual) << endl; // 12
	cout << "TwoIntTwoVirtual: " << sizeof(TwoIntTwoVirtual) << endl; // 12
	cout << "TwoIntOneVirtualDerived: " << sizeof(TwoIntOneVirtualDerived) << endl; // 12
	cout << "TwoIntTwoVirtualDerived: " << sizeof(TwoIntTwoVirtualDerived) << endl; // 12
	cout << "OtherTest: " << sizeof(OtherTest) << endl; // 40
	cout << "Long long: " << sizeof(short) << endl; // 2
	cout << "Long long: " << sizeof(long long) << endl; // 8
	cout << "node0: " << sizeof(node0) << endl; // 24


	cout << "---------------------" << endl;
	node0 no;
	cout << "&a = " << (void*)&no.a << endl;
	cout << "&b = " << (void*)&no.b << endl;
	cout << "&c = " << (void*)&no.c << endl;
	cout << "&d = " << (void*)&no.d << endl;
	cout << "&e = " << (void*)&no.e << endl;

	return 0;
}

在这个例子中,下面这个比较有代表性:

class node0
{
public:
	int a;
	char b;
	short c;
	char d;
	double e;
};

这里,首先找到大小最大的类型为double,占8个字节,所以应该以8字节的大小来对齐,最后的大小应该是8的整数倍。

现在已经找到最大的为8了,下面就来模拟对上面结构来开内存(以下表格表示内存,地址从上到下、从左到右的方向增加),表格里的字母表示该地址被字母所表示的变量占据着,空格是为了要对齐才这样的。




再分析一个:

class OtherTest
{
	char e, f, g, h, i, j, k;
	int a;
	int b;
	int c;
	long long d;
	virtual void function() {}
	virtual void function2() {}
};

这里,也是首先找到大小最大的类型,为long long,在Windows7 32位的VS2013上占8个字节,所以应该以8字节的大小来对齐,最后的大小应该是8的整数倍。

现在已经找到最大的为8了,下面就来模拟对上面结构来开内存(以下表格表示内存,地址从上到下、从左到右的方向增加),表格里的字母表示该地址被字母所表示的变量占据着,空格是为了要对齐才这样的。其中vptr是虚函数表指针,一般占4个字节。

 


如果是在GCC下,那么sizeof的结果是32,内存如下:


本 PPT 介绍了制药厂房中供配电系统的总体概念与设计要点,内容包括: 洁净厂房的特点及其对供配电系统的特殊要求; 供配电设计的一般原则与依据的国家/行业标准; 从上级电网到工厂变电所、终端配电的总体结构与模块化设计思路; 供配电范围:动力配电、照明、通讯、接地、防雷与消防等; 动力配电中电压等级、接地系统形式(如 TN-S)、负荷等级与可靠性、UPS 配置等; 照明的电源方式、光源选择、安装方式、应急与备用照明要求; 通讯系统、监控系统在生产管理与消防中的作用; 接地与等电连接、防雷等级与防雷措施; 消防设施及其专用供电(消防泵、排烟风机、消防控制室、应急照明等); 常见高压柜、动力柜、照明箱等配电设备案例及部分设计图纸示意; 公司已完成的典型项目案例。 1. 工程背景与总体框架 所属领域:制药厂房工程的公用工程系统,其中本 PPT 聚焦于供配电系统。 放在整个公用工程中的置:与给排水、纯化水/注射用水、气体与热力、暖通空调、自动化控制等系统并列。 2. Part 01 供配电概述 2.1 洁净厂房的特点 空间密闭,结构复杂、走向曲折; 单相设备、仪器种类多,工艺设备昂贵、精密; 装修材料与工艺材料种类多,对尘埃、静电等更敏感。 这些特点决定了:供配电系统要安全可靠、减少积尘、便于清洁和维护。 2.2 供配电总则 供配电设计应满足: 可靠、经济、适用; 保障人身与财产安全; 便于安装与维护; 采用技术先进的设备与方案。 2.3 设计依据与规范 引用了大量俄语标准(ГОСТ、СНиП、SanPiN 等)以及国家、行业和地方规范,作为设计的法规基础文件,包括: 电气设备、接线、接地、电气安全; 建筑物电气装置、照明标准; 卫生与安全相关规范等。 3. Part 02 供配电总览 从电源系统整体结构进行总览: 上级:地方电网; 工厂变电所(10kV 配电装置、变压
`sizeof` 和 `strlen` 是 C 语言中两个常用的用于获取数据大小或长度的操作符/函数,但它们的用途、工作方式和适用对象有显著区别。 --- ### 1. `sizeof` - **类型**:操作符(不是函数) - **作用**:计算数据类型或变量在内存中所占的字节数。 - **适用对象**:任何数据类型、变量、数组、结构体等。 - **计算内容**:包括字符串中的 `\0` 结束符以及未使用的空间(如数组定义的全部空间)。 - **计算时机**:编译时确定(大多数情况下),不依赖运行时内容。 #### 示例: ```c #include <stdio.h> int main() { char str[] = "hello"; printf("sizeof(str) = %zu\n", sizeof(str)); // 输出 6('h','e','l','l','o','\0') int arr[5]; printf("sizeof(arr) = %zu\n", sizeof(arr)); // 输出 20(假设int为4字节,5*4=20) return 0; } ``` --- ### 2. `strlen` - **类型**:函数(需包含 `<string.h>`) - **作用**:计算字符串的字符数,**不包括结尾的 `\0`**。 - **适用对象**:以 `\0` 结尾的字符数组(即字符串)。 - **计算内容**:从起始地址开始,逐个字符计数,直到遇到 `\0` 为止。 - **计算时机**:运行时计算。 #### 示例: ```c #include <stdio.h> #include <string.h> int main() { char str[] = "hello"; printf("strlen(str) = %zu\n", strlen(str)); // 输出 5 char *str2 = "C language"; printf("strlen(str2) = %zu\n", strlen(str2)); // 输出 10 return 0; } ``` --- ### 关键区别总结: | 特性 | `sizeof` | `strlen` | |------------------|--------------------------------------|----------------------------------------| | 类型 | 操作符 | 函数 | | 头文件 | 无需头文件 | 需要 `<string.h>` | | 计算内容 | 占用的总字节数 | 字符串有效字符数(不含 `\0`) | | 是否包含 `\0` | 包含 | 不包含 | | 数组 vs 指针 | 对数组能正确返回定义大小 | 对指针只能计算到 `\0` 的实际长度 | | 运行时/编译时 | 编译时(通常) | 运行时 | #### 特殊情况对比: ```c char *p = "hello"; printf("%zu\n", sizeof(p)); // 输出指针大小(64系统通常为8) printf("%zu\n", strlen(p)); // 输出5 ``` 这里 `sizeof(p)` 只是计算指针本身的大小,而不是字符串内容。 ---
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值