一、sizeof

sizeof是C/C++中的一个操作符(operator),简单的说其作用就是返回一个对象或者类型所占的内存字节数。

1) sizeof( object ); // sizeof( 对象 );2) sizeof( type_name ); // sizeof( 类型 );3) sizeof object; // sizeof 对象

功能:一个对象或者类型所占的内存字节数;

说明:sizeof操作符的结果类型是size_t,typedef unsigned int size_t;

原型:extern unsigned int strlen(char *s);

MSDN上的解释为:

The sizeof keyword gives the amount of storage, in bytes, associated with a variable or a type(including aggregate types). This keyword returns a value of type size_t.

其返回值类型为size_t,在头文件stddef.h中定义。这是一个依赖于编译系统的值,一般定义为

在C99及以上标准中,sizeof(char)、sizeof(int)、sizeof(long)、sizeof(long long)、sizeof(float)、sizeof(double)、sizeof(long double)的值分别是1,4,4,8,4,8,16。

结构体的总大小为结构体最宽基本类型成员大小的整数倍,这就是结构体的字节对齐。结构体每个成员相对于结构体首地址的偏移量(offset)都是最宽成员大小的整数倍。如:

struct S1{char c;int i;};

printf(sizeof(S1));

char占1个字节,int占4个字节,VC6中按默认设置得到的结果为8。

结构体在内存组织上是顺序式的,联合体则是重叠式,各成员共享一段内存,所以整个联合体的sizeof也就是每个成员sizeof的最大值。结构体的成员也可以是复合类型,这里,复合类型成员是被作为整体考虑的。

以下是一个利用sizeof操作符求数据类型长度的小实例:

#include

void main(void)

{

char x = 'a';

char *p = "abcd";

char y[4] = {'a','b','c','d'};

int a = 10;

int *b = &a;

int c[4] = {1,2,3,4};

printf("%d,%d,%d\n",sizeof(x),sizeof(p),sizeof(y));

printf("%d,%d,%d\n",sizeof(a),sizeof(b),sizeof(c));

system("pause");

}

运行结果(32位机):

1,4,4

4,4,16

字符型数据无论是在16位机上还是32位机上都只占一个字节。而整型却不是这样,在16

位机上整型数据是两个字节,而在32位机上是4个字节。因此要在16位机和32位机上分別求其

结果。

首先要知道指针保存的是一个内存地址,其长度是和整型数据一致的。在上述代码中,x是一个字符型变量,其长度肯定是1,因此sizeof(x)的结果是1。p是一个字符指针,其类型为指针类型,指针类型在16位机上占两个宇节,在32位机上占4个字节。y是一个包含4个字符的数组,每个字符长度是1,因此y的长度是4。a是整型变量,其值和指针一样在16位机上长度是2,在32位机长度是4,b是指针变量,其长度同p。c是包含4个整型变量的数组,在16位机上,其长度是8,在32位机上,其长度是16。

以上变量在内存中的存储结构如下图所示:

二、strlen()

strlen(char*)函数求的是字符串的实际长度(字符个数),直到遇到第一个'\0',然后就返回计数值,且不包括'\0'。

格式:strlen (字符数组名)

功能:计算字符串s的(unsigned int型)长度,不包括'\0'在内

说明:返回s的长度,不包括结束符NULL。

char arr[10];cout<

三、sizeof和strlen()的区别

sizeof用来返回一个数据类型的长度,而strlen用来返回一个字符串的长度。不过除此之外两者还有本质的区别。

(两者的结果类型是size_t,它在头文件中typedef为unsigned int类型。)

1 sizeof是运算符,strlen是函数。

2 sizeof可以用类型做参数,strlen只能用char*做参数,且必须是以''\0''结尾的。

3 sizeof的参数可以是数据的类型,也可以是变量(此时sizeof后面的括号可以不加),而

strlen只能以char*并且结尾为‘\0‘的字符串作参数。

如下所示:

#include

#include

void main()

{

int a = 3;

printf("%d,%d\n",sizeof(int),sizeof(a));

char *p = "hello123";

printf("%d",strlen(p));

system("pause");

}

执行结果:

4,4

8

sizeof还可以用函数做参数,比如:

short f();printf("%d\n",sizeof(f()));输出的结果是sizeof(short),即2。

4 数组做sizeof的参数不退化,传递给strlen就退化为指针了。

5 大部分编译程序在编译时确定sizeof,因此sizeof(x)可以用来定义数组维数;而strlen要在运行时才能计算出来,用来计算字符串的长度,而不是类型占内存的大小;

char str[20]="0123456789";int a=strlen(str);//a=10;int b=sizeof(str);//而b=20;

6 strlen的结果要在运行的时候才能计算出来,是用来计算字符串的长度,不是类型占内存的大小。

7 sizeof后如果是类型必须加括弧,如果是变量名可以不加括弧。这是因为sizeof是个操作符不是个函数。

8 当适用于一个结构类型或变量时, sizeof 返回实际的大小,当适用于静态的空间数组, sizeof 归还全部数组的尺寸;sizeof 操作符不能返回被动态分派的数组或外部数组的尺寸。

9 数组作为参数传给函数时传的是指针而不是数组,传递的是数组的首地址,

char Arr[3]={'0'};sizeof(Arr)结果为3;char *p=Arr;strlen(p)结果为1;//sizeof(p)结果为4

在传递一个数组名到一个函数中时,它会完全退化为一个指针。

如:

fun(char[8])fun(char[])都等价于 fun( char * )

在C++里参数传递数组永远都是传递指向数组首元素的指针,编译器不知道数组的大小,如果想在函数内知道数组的大小, 需要这样做:

进入函数后用memcpy拷贝出来,长度由另一个形参传进去

fun(unsiged char*p1,int len){unsigned char*buf=new unsigned char[len+1];memcpy(buf,p1,len);}

四、实例说明

常在用到 sizeof 和 strlen 的时候,通常是计算字符串数组的长度,如果是对指针,结果则会不一样的:

char str[20]="0123456789";

int a=strlen(str); //a=10;

// strlen 计算字符串的长度,以结束符 0x00 为字符串结束。

int b=sizeof(str); //b=20;

//sizeof 计算的则是分配的数组str[20] 所占的内存空间的大小,不受里面存储的内容改变。

上面是对静态数组处理的结果,如果是对指针,结果就不一样了

char* ss = "0123456789";

sizeof(ss) 结果 4;

ss是指向字符串常量的字符指针,sizeof 获得的是一个指针所占的空间,应该是长整型的,所以是4;

sizeof(*ss) 结果 1;

*ss是第一个字符其实就是获得了字符串的第一位'0' 所占的内存空间,是char类型的,占了 1 个字节;

strlen(ss)结果10。

-End-

查看原文 >>
相关文章