C++之sizeof与strlen

开发板推荐:天空星STM32F407VET6开发板

超高性价比 STM32主控 | 超高主频 | 一板兼容百芯 | 比赛神器 | 沉金彩色丝印

title: C/C++之sizeof与strlen
author: Qian Jipeng
tags:

  • sizeof
  • strlen
  • 内存对齐
  • C++成员布局
    categories:
  • C++
  • C
    date: 2019-09-12 21:47:00

C/C++中的sizeof与strlen

很久之前的C课程上面老师就提到过sizeof,当时也不知道是怎么一回事,后来在读代码的过程中经常遇到sizeof,索性就来好好了解一下吧。

区别

sizeof

首先要知道一点,sizeof是C/C++中的一个运算符,我们通常的用法是sizeof(foo)在编译时才会计算foo的大小并返回,它的值不受foo里面所存储的内容影响,只会和foo的数据类型(char还是int还是指针…)和计算机平台(32位还是64位)有关。

举个例子:
Test1.cpp

#include <iostream>
using namespace std;
int main() {
	int a;
	char b;
	int *c;
	cout << sizeof(a) << endl;	// int 类型占4个字节
	cout << sizeof(b) << endl;	// char 类型占1个字节
	cout << sizeof(c) << endl;	// 64位系统指针占8个字节,32位一个指针占4个字节
	return 0;
}

测试输出:

4
1
8
**Test2.cpp** ``` #include using namespace std; int main() { int a = 1; int d = 10; char b; int *c; double *e;
cout << sizeof(a) << endl;		// 4
cout << sizeof(b) << endl;
cout << sizeof(c) << endl;
cout << sizeof(d) << endl;		// 4
cout << sizeof(e) << endl;
return 0;

}

测试输出:</br>

4
1
8
4
8

</br>
sizeof(a)和sizeof(d)相等,这就说明了sizeof(foo)与foo里面存取的内容无关。</br>
好接下来,如果<font color=green>遇到C++中的类怎么办?</font></br>
**Test3.cpp**

#include
using namespace std;

class Foo {
int a; // 4
char b; // 1
int *c; // 8
};

int main() {
Foo foo;
cout << sizeof(foo) << endl;
return 0;
}

测试结果:</br>

16

啥?输出是16,为什么是16呢?4+1+8不应该是13吗?</br>
一开始我也是这么认为的,知道看了***inside the C++ object module***一书时才醒悟,我们的编译器一般都会对我们的代码做出优化,一个专业名词叫做**<font color=red>内存对齐</font>**,**<font color=hotpink>编译器在编译程序时,会检测一个类的数据成员,是否sizeof(foo)的值是4的整数倍,如果不是,就会自动扩张成4的整数倍(距离当期sizeof最小的),具体为什么,要说到C++中的成员数据的内部布局,这个我们在这先不做讨论。大家记着就好,后面我会详细介绍。</font>**</br>
所以说,上面的答案就合乎逻辑了,16 = 4 + 1 + 8 + 3,这个3叫做**padding size**。</br>

不妨再来一波?</br>
**Test4.cpp**

#include
using namespace std;

class Foo {
int a; // 4
char b; // 1
int *c; // 8
};

class Bar:public Foo { // 加上继承试试
char d; // 1
};

int main() {
Foo foo;
Bar bar;
cout << "sizeof foo is: " << sizeof(foo) << endl; // 16
cout << "sizeof bar is: " << sizeof(bar) << endl; // 24
return 0;
}

测试结果:</br>

sizeof foo is: 16
sizeof bar is: 24 //why???

是不是又蒙了?加上继承之后,sizeof(bar)为什么是24呢?先抛砖引玉,后面的文章再详细解释。

## strlen
strlen()是C的一个库函数,注意它是函数,一般用于计算字符串的长度,遇到`'\0'`就停止计算。我们来测试一下:</br>
**Test5.cpp**

#include
#include
using namespace std;

int main() {
char *a = “Hello World”;
char b[100] = “Hello World”;
char c[] = “Hello World”;
cout << "sizeof a is: " << sizeof(a) << endl;
cout << "strlen a is: " << strlen(a) << endl;
cout << "sizeof b is: " << sizeof(b) << endl;
cout << "strlen b is: " << strlen(b) << endl;
cout << "sizeof c is: " << sizeof© << endl;
cout << "strlen c is: " << strlen© << endl;
return 0;
}

测试结果:</br>

sizeof a is: 8 // 一个指针大小
strlen a is: 11 // 字符串长度,不带’\0’
sizeof b is: 100 // 数组大小
strlen b is: 11 // 字符串长度,不带’\0’
sizeof c is: 12 // 字符串长度,加上一个’\0’
strlen c is: 11 // 字符串长度,不带’\0’


## 补充说明
**<font color=red>
讲到这里,二者之间的区别想必大家也都明白了,strlen 的结果要在运行的时候才能计算出来,而sizeof的值是在编译时就确定的,所以不能用sizeof来计算动态分配的类型大小。
</font>**

**Test6.cpp**

#include
#include
using namespace std;

int main() {
char *a = new char[20];
cout << "sizeof a is: " << sizeof(a) << endl; // 8
cout << "strlen a is: " << strlen(a) << endl; // 0
cout << "sizeof *a is: " << sizeof(*a) << endl; // 1

*a = 'a';

cout << "now sizeof a is: " << sizeof(a) << endl;	// 8
cout << "now strlen a is: " << strlen(a) << endl;	// 1
cout << "now sizeof *a is: " << sizeof(*a) << endl;	// 1

delete[] a;
a = NULL;
return 0;

}

测试结果:</br>

sizeof a is: 8
strlen a is: 0
sizeof *a is: 1
now sizeof a is: 8
now strlen a is: 1
now sizeof *a is: 1 // sizeof(*a)没变化??



开发板推荐:天空星STM32F407VET6开发板

超高性价比 STM32主控 | 超高主频 | 一板兼容百芯 | 比赛神器 | 沉金彩色丝印

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值