Sizeof与strlen区别以及用法
Sizeof
Sizeof是函数还是关键字呢?
答:关键字,它是一个“披着函数皮的关键字”。做我的关键字,让人家认为是函数去吧。
为什么说是关键字呢?看看下面分析:我们借助编译器确认它的身份。
看下面的例子。示例选择题如下:
int i = 10;
A:sizeof(int)
B:sizeof(i)
C:sizeof int
D:sizeof i
A,B不用说,32位系统下值为4。而D也通过编译,并且值也是4,没有括号竟然都可以通过?充分说明sizeof不是函数。
那C呢?编译器报错误了!!如果按关键字理解的话,后面的括号是可以省略的呀?
printf("%d\n",sizeof(short));
输出的结果为短整型的长度2。用结构类型或变量做参数时,sizeof 返回实际的大小,当用于静态数组时,sizeof 返回全部数组的尺寸。
charstr[20]="0123456789";
int a=strlen(str); // a=10; strlen 计算字符串的长度,以\0'为字符串结束标记。
int b=sizeof(str); // b=20; sizeof 计算的则是分配的数组str[20] 所占的内存空间的大小,不受里面存储的内容影响。
总结如下:
1.sizeof是一个关键字。
2.计算变量空间大小时括号可以省略。
3.计算类型(模子)空间大小时括号不可以省略。
4.一般情况下,都写上括号。
5.sizeof其实就是用于告诉我们编译器在为某一特定数据或者某种数据类型的数据在存储空间中开辟空间时,开辟的空间大小,以字节为单位。
6.sizeof(类型),或者sizeof(变量)都可以,得到的就是类型或者变量的存储空间
7.用结构类型或变量做参数时,sizeof 返回实际的大小,当用于静态数组时,sizeof 返回全部数组的尺寸。
8.sizeof返回的占用空间大小是为这个变量开辟的大小,而不只是它用到的空间。
9.对位域成员等连编译器都无法确定存储空间的东西不能用。这个应该比较好理解,因为sizeof返回的都是以字节为单位的数据,你让它去求那些以位为单位的大小,这不是存心难为编译器嘛。所以编译器采用的方案是统一不受理,即使你说你刚好是8位,占一个字节,编译器也不理你。
10.要注意数组名和指针变量的区别。通常情况下,我们总觉得数组名和指针变量差不多,但是在用sizeof的时候差别很大,对数组名用sizeof返回的是整个数组的大小,而对指针变量进行操作的时候返回的则是指针变量本身所占得空间,在32位机的条件下一般都是4。而且当数组名作为函数参数时,在函数内部,形参也就是个指针,所以不再返回数组的大小。
Strlen
原型:extern intstrlen(char *str);
用法:#include<string.h>
功能:计算字符串str的(unsignedint型)长度
说明: Stelen是计算字符串长度的,并不包含字符串最后的”\0”,判断一个字符串是否结束的标志就是看是否遇到”\0”,若遇到”\0”,则认为字符串结束。
//函数实现1
int my_strlen(const char*str)
{
int len = 0;
assert(NULL != str);
while ((*str++) != '\0')
len++;
return len;
}
//函数实现2
typedef unsigned int u_int;
u_int Mystrlen(const char *str)
{
u_int i;
assert(str != NULL);
for (i = 0; str != '/0'; i++);
return i;
}
//函数实现3
int strlen(const char *str)
{
assert(str);
const char *p = str;
while (*p++);
return p - str - 1;
}
//主函数调用
int main()
{
char*p = "abcdefg";
int len = 0;
len=my_strlen(p);
printf("%d\n", len);//运行结果为7;不包含'\0'
return 0;
}
sizeof与strlen的用法区别
1. sizeof操作符的结果类型是size_t,它在头文件中typedef为unsigned int类型。该类型保证能容纳实现所建立的最大对象的字节大小。
2. sizeof是运算符,strlen是函数。
3. sizeof可以用类型做参数,strlen只能用char*做参数,且必须是以”\0”结尾的。sizeof还可以用函数做参数,比如:
Short fun ();
printf("%d\n",sizeof( fun() ) );
输出的结果是返回值的类型的大小, 即sizeof(short)=2。
4.数组做sizeof的参数不退化,传递给strlen就退化为指针了。大部分编译程序在编译的时候就把sizeof计算过了,是类型或是变量的长度,这就是sizeof(x)可以用来定义数组维数的原因。
charstr[20]="0123456789";
inta=strlen(str); //a=10;
intb=sizeof(str); //b=20;
而strlen的结果要在运行的时候才能计算出来,是用来计算字符串的长度,不是类型占内存的大小。
5. sizeof后如果是类型必须加括弧,如果是变量名可以不加括弧。这是因为sizeof是个操作符不是个函数。
6. 当适用了于一个结构类型时或变量, sizeof 返回实际的大小,当适用一静态地空间数组, sizeof 得到全部数组的尺寸。sizeof 操作符不能返回动态地被分派了的数组或外部的数组的尺寸。
7. 数组作为参数传给函数时传的是指针而不是数组,传递的是数组的首地址,如:
fun(char [8])
fun(char [])
都等价于 fun(char *)。
在C里参数传递数组永远都是传递指向数组首元素的指针,编译器不知道数组的大小。
sizeof对指针的话,结果是相应的类型:
char* str ="0123456789";
sizeof(str);
结果是4 => str是指向字符串常量的字符指针,sizeof 获得的是一个指针所占的空间,32位系统下值为4。 sizeof(*str) 结果 1, => * str是第一个字符,其实就是获得了字符串的第一位“0”所占的内存空间,是char类型的,占了1个字节。如果要获得这个字符串的长度,则一定要使用 strlen,既strlen(str)为10。