接下来我们来说说sizeof和strlen。
1.sizeof
函数or关键字?
对于sizeof,第一点我们要清楚的是,它是一个关键字,并不是一个函数。正因为sizeof不是函数,因此我们不把它所要求得长度的对象叫做参数,这也是
sizeof不能求得void类型的长度
你无法求出sizeof(void),其实你是无法声明出void的一个变量的,void指的是一个空类型,空类型你是无法知道变量内存空间大小的,所以你用sizeof去求肯定是不行的。sizeof可以求void类型指针的长度
sizeof对于void类型的指针,因为指针,是用来存放地址的变量,在32位平台,所有版本的编译器都把它看作4个字节,所以你后续只要用sizeof求的是指针,就绝对是4。sizeof能求得静态分配内存的数组的长度
这个其实很好解释,例如:
#include<stdio.h>
#include<stdlib.h>
int main()
{
int arr[] = { 1, 2, 3, 4 };
printf("%d", sizeof(arr));
system("pause");
return 0;
}
在这里你可以看到这里的sizeof=类型所占字节大小*元素个数。
- sizeof求数组做形参的情况
sizeof求形参是会有个陷阱,比如:
void lab(int arr[4])
{
int m = sizeof(arr);
printf("%d",m);
}
在这里的m就是一个陷阱的提现,如果你说结果m是16,那么你就错了,当数组做形参时,所传递的并不是数组本身,在这里数组被转化成了指针,因为如果数组太大了,如果你要传数组,那么所需要创建的拷贝就很大,这样会导致效率很低。所以其实你进行的还是对指针的sizeof,结果依然是4。
2.strlen
strlen()函数,它是一个字符串函数,它相当于一个计数器,当它遇到’\0’时就停止计数。
strlen的实现:
int my_strlen(const char *str)
{
int len=0;
assert(str != NULL);
while ((*str++) != '/0')
{
len++;
}
return len;
}
strlen函数是遇到‘/0’就会停止。
3. 关于strlen和sizeof的示例:
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
int main()
{
char *p = "abcdef0\0";//
char arr1[] = "abcdef";
char arr2[] = { 'a', 'b', 'c','d', 'e', 'f' };
int a[] = { 1, 2, 3, 4 };
printf("%d\n",sizeof(p));//4 这里的原因是p是一个指针变量,所有的指针变量都是所占字节数都为4
printf("%d\n",sizeof(arr1));//7 这里是对arr1数组求大小,别忘了‘\0’。
printf("%d\n",sizeof(arr2));//6 这里是对arr2数组求大小。
printf("%d\n",strlen(p));//7 这里对p求大小,遇到‘\0’会终止。
printf("%d\n",strlen(arr1));//6 这是求arr1,这里记得字符串中有‘\0’;
printf("%d\n",strlen(arr2));//比6大的随机值 这里对arr2求时,会发生一个问题,不存在‘\0’,继续向找,直到在内存中找到‘\0’为止
printf("%d\n",sizeof(a));//16 这里是sizeof(int)*元素个数。
printf("%d\n",sizeof(a+0));//4 这里是a[0],就是一个整形元素的大小。
printf("%d\n",sizeof(*a));//4 这里a保存的是首元素的地址,所以解引用出来的就是第一个元素,然后求取大小。
printf("%d\n",sizeof(a+1));//4 这里相当于是对a[1]求取元素大小。
printf("%d\n",sizeof(a[1]));//4 上同
printf("%d\n",sizeof(&a));//4 这求得是整个数组的地址的大小,整个数组的地址就相当于指针变量的大小,都是4个字节。
printf("%d\n",sizeof(&a+1));//4 这里是对整个数组取地址,再加一,这时候指向下一个同等大小的数组的首位置,所以依然是4。
printf("%d\n",sizeof(&a[0]));//4 这里还是个地址。所以是4
printf("%d\n",sizeof(&a[0]+1));//4 就相当于指向第二个元素。还是4
printf("%d\n",sizeof(*&a));//16 先取整个数组的地址,然后解引用,就相当于整个数组的大小,所以是16。
char name[] = "abcdef";
printf("%d\n", sizeof(name[0]));//1 这里说的就是‘a’,一个字节。
printf("%d\n", sizeof(&name));//4 这里说的是整个数组的地址,地址是4个字节
printf("%d\n", sizeof(*name));//1 这里说的是解引用数组的地址,即‘a’,一个字节
printf("%d\n", sizeof(&name + 1));//4 这里说的还是个地址,指向的是name数组之后的位置,即指向‘\0’后的位置
printf("%d\n", sizeof(name + 1));//4 这里就相当于第二个元素的地址,所以还是四个字节。
printf("%d\n", sizeof(name));//7 这里的name求字符串所占大小,记得‘\0’
printf("%d\n", strlen(name));//6 共有6个元素
printf("%d\n", strlen(&name));//6 这里面其实相当于还是传了name,参考strlen的实现,所以还是6
printf("%d\n", strlen(&name + 1));//随机值 在这到下一个数组,知道遇到‘\0’才能停下来。
printf("%d\n", strlen(name + 1));//5 name+1 指向‘b’,然后从‘b’向后一直到‘\0’最终就可以得出是5
char *name = "abcdef";
printf("%d\n", sizeof(name[0]));//1 这里说的就是‘a’,一个字节。
printf("%d\n", sizeof(&name));//4 这里说的是name的地址,地址是4个字节
printf("%d\n", sizeof(*name));//1 这里说的是解引用数组的地址,即‘a’,一个字节
printf("%d\n", sizeof(&name + 1));//4 这里说的还是个地址,指向的是name数组之后的位置,即指向‘\0’后的位置
printf("%d\n", sizeof(name + 1));//4 这里就相当于第二个元素的地址,所以还是四个字节。
printf("%d\n", sizeof(name));//4 name是个指针变量,所以就是4个字节。
printf("%d\n", strlen(name));//6 共有6个元素
printf("%d\n", strlen(&name));//随机值 这里是给name的地址strlen,所以看地址中有没有‘\0’,当遇到‘\0’以后才会停下来
printf("%d\n", strlen(&name + 1));//随机值 这里是给name+1的地址strlen,所以看地址中有没有‘\0’,当遇到‘\0’以后才会停下来
printf("%d\n", strlen(name + 1));//5 指向‘b’,然后从‘b’向后一直到‘\0’最终就可以得出是5
system("pause");
return 0;
}
运行结果:
博客写的不免有缺陷,请大家多多指出,谢谢!!