sizeof最明显的区别就是一个是运算符而一个是库函数,接下来我讲解两者的用法和两者的区别
sizeof:
sizeof是一个运算符,作用是计算括号内传递的值的类型的大小(单位是字节)
例:
#include<stdio.h>
int main()
{
int a = 1;
char b = 2;
int* pa = &a;
char* pb = &b;
// 括号内是变量
printf("%d\n", sizeof(a)); // 变量a是int类型,所以是四个字节
printf("%d\n",sizeof(b)); // 变量b是char类型,一个字节
printf("%d\n",sizeof(pa)); // 变量pa是地址,而地址的大小是根据环境来定的,我这里是x86环境所以是4个字节
printf("%d\n",sizeof(pb));
// 括号内是类型
printf("%d\n", sizeof(int)); // 4
printf("%d\n", sizeof(int*)); // 8
// 没加括号的情况 (没加括号时,不能够直接写类型)如 sizeof int 这就是错的
printf("%d\n", sizeof a);
return 0;
}
特例:
sizeof() 若放的是数组名返回的值是整个数组的大小,但是在别的情况下 数组名==首元素地址
strlen:
strlen 是一个库函数,使用这个库函数需要引用一个头文件#include<string.h> ,而string中文翻译过来是字符串,所以不难看出这是个针对于字符串的函数。strlen中文翻译是字符长度,那我们就知道了这是个球字符串长度的库函数
strlen 实际上是从字符串首元素开始往后数遇到'\0'停止,若是没有遇到'\0'就会一直找下去,可能会导致越界访问,且strlen只能用于字符串,传递给strlen的参数是字符地址
例:
#include<string.h>
#include<stdio.h>
int main()
{
char arr[] = "abcdef";
char* p = arr;
printf("%d\n", strlen(arr)); // arr == &arr[0] ,那么这个就是从a开始,到'\0'结束有6个元素
printf("%d\n", strlen(&arr[0]));
printf("%d\n", strlen(&arr[1])); // 从arr[1]开始到'\0'结束有5个元素
printf("%d\n", strlen(&arr[6] + 1));
// 这是后面的'\0'后面一个字节的地址,因为找不到'\0'就会一直找,所以会得到随机值
return 0;
}
越界访问情况:
int main()
{
char arr[] = "abcdef";
printf("%d\n", strlen('a'));
// 'a'的ASCII码值是97,而访问97这个地址越界访问了,所以也就报错了
return 0;
}
strlen代码实现:
我们先来看看官网是如何定义strlen的
那么们现在就知道了strlen返回值的是size_t类型,形参是const char* 类型的(const是只读限制符)
size_t strlen_my(const char* str)
{
size_t ret = 0;
int judge = 1;
while (judge)
{
if (*str != '\0')
{
ret++;
str++; // 地址加一
}
else
judge = 0;
}
return ret; // 既然返回值是size_t类型,那么ret应该跟她一样的类型
}
int main()
{
char arr[] = "abcdef";
printf("%d\n",strlen_my(arr));
return 0;
}
区别:
sizeof是运算符不需要头文件,strlen是字符串库函数,需要引用库函数<string.h> ,sizeof可以传类型名也可以传变量名,还可以传数据(其实就是类型,如果传4进去,而4是整形,所以返回值是int类型的字节,大小为4)计算的是字节大小。strlen只能传地址进来,由地址找到指向的内容,从第一个地址往后面数,直到遇到'\0'停止,若是传进去的不是地址而是一个值,很可能会导致越界访问。