1)基本概念
sizeof是C/C++中的一个操作符,而它的作用则是返回一个对象或者类型在内存中所占的字节数。另外sizeof()的操作数可以是一个自定义的表达式也可以是一个自定义的数据类型或者是int、long int、char等一些常用的内置数据类型,而且操作数的大小不仅与操作数的类型有关还与所使用的编译环境有关。
2)语法
1)sizeof(对象) 2)sizeof 对象 3)sizeof(类型)
例如: int a = 10;
sizeof(int); //ok
sizeof(a); //ok
sizeof a; //ok
sizeof int; //error
除此之外当我们对一个函数求其大小时会发现对函数求大小就是对函数的返回值类型求大小,例如:
#include <iostream>
using namespace std;
char f1()
{
return 11;
}
int f2()
{
return 14;
}
int main()
{
cout<<sizeof(f2())<<endl;
cout << sizeof(f1()) << endl;
}
有心的人一定会发现如果按照上面所说的对任意一个函数求其大小有时候不一定能求出甚至还会出错,例如:
void f3()
{}
cout<<sizeof(f3())<<endl; //error
所以对于一个函数求其大小也是有一定的限制的--->一定要明确函数的返回值类型,否则是不能进行求大小。
3)指针变量的sizeof
对于指针和它的作用我们并不陌生,它是用来存地址的,所以指针的大小就是计算机内部总线的大小,在32位机
下不论什么类型的指针大小都是4字节,而在64位机下则是8字节。例如:下面的32位机的一个测试程序
#include <iostream>
using namespace std;
int main()
{
char *p = "abdc";
cout << "p--->" << sizeof(p) << endl;
int a = 12;
int *p1 = &a;
cout << "p--->" << sizeof(p1) << endl;
return 0;
}
4)数组的sizeof就是整个数组在内存所占的字节数。
数组大小=sizeof(数组名)/sizeof(数组首元素)
5)结构体的sizeof
typedef struct _STR
{
int c;
char a;
} STR;
STR s1;
cout<<sizeof(s1)<<endl; //8
//sizeof(s1) = sizeof(c)+sizeof(a)=4+1=5 != 8
也许你会很奇怪为什么不等于5而等于8呢?这是因为在编译器对结构体进行了处理----字节填充。所谓的字节填充类似于“凑数”和“对齐”。例如,一个结构体,它的成员变量所需内存18个字节,那么,实际分配时,给这个结构 凑成 4的倍数,分配给 20个字节。
字节对齐原则:
1.数据成员对齐规则:结构(struct或联合union)的数据成员,第一个数据成员放在offset为0的地方,以后每个数据成员存储的起始位置要从该成员大小的整数倍开始(比如int在32位机为4字节,则要从4的整数倍地址开始存储)。2、结构体作为成员:如果一个结构里有某些结构体成员,则结构体成员要从其内部最大元素大小的整数倍地址开始存储。(struct a里存有struct b,b里有char,int,double等元素,那b应该从8的整数倍开始存储。)3、结构体的总大小,也就是sizeof的结果,必须是其内部最大成员的整数倍,不足的要补齐。例如:typedef struct _STR
{
char c;
double d;
int v;
}STR;
int main()
{
STR s1;
cout << sizeof(s1) << endl;
return 0;
}
strlen()从内存的某个位置(可以是字符串开头,中间某个位置,甚至是某个不确定的内存区域)开始扫描,直到碰到第一个字符串结束符'\0'为止,然后返回计数器值(长度不包含"\0")。
strlen()与sizeof()的区别:
1)sizeof是运算符,strlen是函数。
2)sizeof()的结果类型是size_t,他在头文件中的定义是typedef unsigned int,该类型保证能容纳所实现建立的最大对象的字节数。
3)sizeof()可以用类型或者函数作为参数,strlen()只能用char *作为类型参数,且必须是以"\0"结尾。
4)把数组传给sizoef()后不会产生退化,传给strlen()会退化为指针。另外如下面的程序:
int arr[10] = {0,12,43,56};
int c = sizeof(arr); //结果是40
当sizeof()中传入的参数是一个静态数组,返回的则是整个数组的大小
5)sizeof(参数)是在编译时就已经计算出结果,而strlen(char *)则是在程序运行时才会进行计算并且计算出的结果不是该类型所占内存的大小。
6)sizeof后面如果是类型则必须要加上括号,若是变量则可以不用加。这是因为sizeof是一个运算符。