源地址:http://hi.baidu.com/qingb087/blog/item/53a42baeecb383c47dd92a6e.html
sizeof 是C的一个运算符,它用来计算数据类型或对象的大小(占内存空间的字节数)它的值在编译时就决定,因此由它计算的变量或类型所占内存空间的大小在编译时就应当是确定的(静态的)
strlen 是C的一个标准库函数,用来计算字符串的长度,它的值在运行是确定,因此由它计算的字符串长度可以是动态的也可以是静态的。
strlen的参数是char *类型,它计算字符串的长度直到遇到\0为止,且长度不包含\0。当用一个字符数组做位strlen参数时,数组名会隐式的转化为char *.
sizeof是计算的变量,类型所占空间的大小,当然包含\0.
sizeof例题
char *str1="absde";
char str2[]="absde";
char str3[8]={'a',};
char str4[] = "0123456789";
sizeof(str1)=4
sizeof(str2)=6;
sizeof(str3)=8;
sizeof(str4)=11
首先说明一点,char类型占一个字节,所以sizeof(char)是1,这点要理解
str1是一个指针,只是指向了字符串"absde"而已。所以sizeof(str1)不是字符串占的空间也不是字符数组占的空间,而是一个字符型指针占的空间。所以sizeof(str1)=sizeof(char*)=4,在32位体系结构的计算机中,一个指针占4个字节
str2是一个字符型数组。C/C++规定,对于一个数组,返回这个数组占的总空间,所以sizeof(str2)取得的是字符串"absde"占的总空间。"absde"中,共有a b s d e \0六个字符,所以str2数组的长度是6,所以sizeof(str2)=6*sizeof(char)=6
str3已经定义成了长度是8的数组,所以sizeof(str3)为8
str4和str2类似,'0' '1' ... '9'加上'\0'共11个字符,所以str4占的空间是11
总之,对于指针,sizeof操作符返回这个指针占的空间,一般是4个字节;而对于一个数组,sizeof返回这个数组所有元素占的总空间。char*与char[]容易混淆,一定要分清,而且char*="aaa"的写法现在不被提倡,应予以避免
而strlen不区分是数组还是指针,就读到\0为止返回长度。而且strlen是不把\0计入字符串的长度的。
char * p="aaa"这种写法很具有迷惑行,p只是一个字符串指针而已,他没有分配什么装"aaa"内存,只是指向装有“aaa”的内存而已。char p[]="aaa"则分配了内存,所以说字符串指针跟数组名是不一样的,数组名可以隐式的转化位字符串指针,但是反过来是不行的。
看下面的程序 :
#include<iostream.h>
char* name()
{
char name[8]="windows";
return name;
}
void main()
{
cout<<name()<<endl;
}
但是这样就能够正常输出 :
#include<iostream.h>
char* name()
{
char *name="windows";
return name;
}
void main()
{
cout<<name()<<endl;
}
为什么,谢谢!!
char name[8] 是字符数组,是一个局部变量,“windows”这个字符常量初始化了它。局部变量是分配在栈上的,当函数退出时,它就被释放了。当return name,返回数组的指针(第一个元素的指针,是一个常量)时,此时name所指的空间已经释放了,name是无效的,这样也是危险的。
char *name是一个字符串指针,也是一个局部变量,“windows”这个字符常量用它的指针初始化了它。关键就在字符常量的空间是分配在全局数据区的,也就是说它用一个指向全局数据区的指针初始化了name,所以即使函数退出,那么所指向的空间还是有效的。
如果要想返回一个字符串的指针,一种办法就是动态的分配一个内存,然后把要返回的字符串拷贝到这块内存上即可。
补充,来源:http://topic.youkuaiyun.com/u/20120213/21/ddff5845-8af5-4e97-9380-4e36ce55ddff.html 8楼
sizeof Operator
sizeof expression
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.
The expression is either an identifier or a type-cast expression (a type specifier enclosed in
parentheses).
When applied to a structure type or variable, sizeof returns the actual size, which may include
padding bytes inserted for alignment. When applied to a statically dimensioned array, sizeof
returns the size of the entire array. The sizeof operator cannot return the size of dynamically
allocated arrays or external arrays.
1.sizeof操作符的结果类型是size_t,它在头文件中typedef为unsigned int类型。该类型保证能容纳实现所建立的最大对象的字节大小。
2.sizeof是运算符
3.sizeof可以用类型做参数,还可以用函数做参数
4.数组做sizeof的参数不退化
5.sizeof在编译期已经确定大小,这就是sizeof(x)可以用来定义数组维数的原因
6.sizeof后如果是类型必须加括弧,如果是变量名可以不加括弧。这是因为sizeof是个操作符不是个函数
7..当适用了于一个结构类型时或变量, sizeof 返回实际的大小, 当适用一静态地空间数组, sizeof 归还全部数组的尺 寸。 sizeof 操作符不能返回动态地被分派了的数组或外部的数组的尺寸
8..计算结构变量的大小就必须讨论数据对齐问题。为了CPU存取的速度最快(这同CPU取数操作有关,详细的介绍可以参考一些计算机原理方面的书),C++在处理数据时经常把结构变量中的成员的大小按照4或8的倍数计算,这就叫数据对齐(data alignment)。这样做可能会浪费一些内存,但理论上速度快了。当然这样的设置会在读写一些别的应用程序生成的数据文件或交换数据时带来不便。MS VC++中的对齐设定,有时候sizeof得到的与实际不等。一般在VC++中加上#pragma pack(n)的设定即可.或者如果要按字节存储,而不进行数据对齐,可以在Options对话框中修改Advanced compiler页中的Data alignment为按字节对齐。
9..sizeof操作符不能用于函数类型,不完全类型或位字段。不完全类型指具有未知存储大小的数据类型,如未知存储大小的数组类型、未知内容的结构或联合类型、void类型等。如sizeof(max)若此时变量max定义为int max(),sizeof(char_v) 若此时char_v定义为char char_v [MAX]且MAX未知,sizeof(void)都不是正确形式
【sizeof使用场合】
1.sizeof操作符的一个主要用途是与存储分配和I/O系统那样的例程进行通信
2.用它可以看看一类型的对象在内存中所占的单元字节。
3.在动态分配一对象时,可以让系统知道要分配多少内存。
4.便于一些类型的扩充,在windows中就有很多结构内型就有一个专用的字段是用来放该类型的字节大小。
5.由于操作数的字节数在实现时可能出现变化,建议在涉及到操作数字节大小时用sizeof来代替常量计算。
6.如果操作数是函数中的数组形参或函数类型的形参,sizeof给出其指针的大小。