【C语言】sizeof和strlen区别

首先我们来看一下sizeof和strlen的区别:

sizeof操作符的结果类型为size_t(它在头文件用typedfe定义为unsigned int类型),计算的是分配空间的实际字节数。strlen结果类型也为size_t(size_t strlen( const char *string )),但strlen是计算的空间中字符的个数(不包括‘\0’)。

  • sizeof是运算符,可以以类型、函数、做参数 。strlen是函数,只能以char*(字符串)做参数。而且,要想得到的结果正确必须包含 ‘\0’(通过strlen的实现得知)。

  • sizeof是在编译的时候就将结果计算出来了是类型所占空间的字节数,所以以数组名做参数时计算的是整个数组的大小。而strlen是在运行的时候才开始计算结果,这是计算的结果不再是类型所占内存的大小,数组名就退化为指针了。

  • 另外,sizeof不能计算动态分配空间的大小如:

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
int main()
{
    
    
   char str[20] = "hello world";
   char *s = (char *)malloc(20);
   strcpy(s, str);
   printf("strlen(str)=%d\n",strlen(str));
   printf("sizeof(str)=%d\n",sizeof(str));
   printf("strlen(s)=%d\n",strlen(s));
   printf("sizeof(s)=%d\n",sizeof(s));
   free(s);
   return 0;
}

在这里插入图片描述
最后的sizeof计算的是指针(sizeof(char *)) 的大小,为4。当适用了于一个结构类型时或变量, sizeof 返回实际的大小, 当适用一静态地空间数组, sizeof 归还全部数组的尺寸。 sizeof 操作符不能返回动态地被分派了的数组或外部的数组的尺寸。

下面我们来看一看sizeof和strlen的具体使用:

int a[4]={
    
    1,2,3,4};
printf("%d\n",sizeof(a));  //16  --->在sizeof中a代表整个数组大小
printf("%d\n",sizeof(a+0));//4---->参与运算,一定为地址,指针大小固定为4\8
printf("%d\n",sizeof(*a));//4---->同上
printf("%d\n",sizeof(a+1));//4---->同上
printf("%d\n",sizeof(a[1]));//4---->同上
printf("%d\n",sizeof(&a));//4---->同上
printf("%d\n",sizeof(*&a));//16---->取地址解引用后,还是数组本身,同1
printf("%d\n",sizeof(&a+1));//4---->同上
printf("%d\n",sizeof(&a[0]));//4---->同上
printf("%d\n",sizeof(&a[0]+1));//4---->同上

//字符数组

char arr[] = {
    
    'a','b','c','d','e','f'};
printf("%d\n", sizeof(arr));//6 --->整个数组大小
printf("%d\n", sizeof(arr+0));//4--->指针大小
printf("%d\n", sizeof(*arr));//1--->a的大小
printf("%d\n", sizeof(arr[1]));//1--->b的大小
printf("%d\n", sizeof(&arr));//4--->指针大小
printf("%d\n", sizeof(&arr+1));//4--->指针大小
printf("%d\n", sizeof(&arr[0]+1));//4--->指针大小
printf("%d\n", strlen(arr));//随机值---->没有‘\0’,找不到结尾
printf("%d\n", strlen(arr+0));//随机值---->没有‘\0’,找不到结尾
printf("%d\n", strlen(*arr));//报错
printf("%d\n", strlen(arr[1]));//报错
printf("%d\n", strlen(&arr));//随机值---->没有‘\0’,找不到结尾
printf("%d\n", strlen(&arr+1));//随机值---->没有‘\0’,找不到结尾
printf("%d\n", strlen(&arr[0]+1));//随机值---->没有‘\0’,找不到结尾
char arr[] = "abcdef";
printf("%d\n", sizeof(arr));//7---->包括'\0'计算在内
printf("%d\n", sizeof(arr+0));//4--->参与运算一定为地址
printf("%d\n", sizeof(*arr));//1--->arr为首元素地址,*arr为首元素a
printf("%d\n", sizeof(arr[1]));//1--->arr[1]为元素b
printf("%d\n", sizeof(&arr));//4--->为地址
printf("%d\n", sizeof(&arr+1));//4--->参与运算一定为地址
printf("%d\n", sizeof(&arr[0]+1));//4--->参与运算一定为地址
printf("%d\n", strlen(arr));//6
printf("%d\n", strlen(arr+0));//6
printf("%d\n", strlen(*arr));//报错
printf("%d\n", strlen(arr[1]));//报错
printf("%d\n", strlen(&arr));//6---->&a代表整个数组
printf("%d\n", strlen(&arr+1));//12---->&arr+1,表示跳过整个数组,从末尾开始找‘\0',所以为随机值
printf("%d\n", strlen(&arr[0]+1));//5---->从b开始计算
char *p = "abcdef";
printf("%d\n", sizeof(p));//4--->指针大小
printf("%d\n", sizeof(p+1));//4--->指针大小
printf("%d\n", sizeof(*p));//1--->a的大小
printf("%d\n", sizeof(p[0]));//1--->a的大小
printf("%d\n", sizeof(&p));//4--->指针大小
printf("%d\n", sizeof(&p+1));//4--->指针大小
printf("%d\n", sizeof(&p[0]+1));//4--->指针大小
printf("%d\n", strlen(p));//6--->p代表首元素地址
printf("%d\n", strlen(p+1));//5--->p代表首元素地址,p+1代表从b开始

printf("%d\n", strlen(*p));//报错
printf("%d\n", strlen(p[0]));//报错
printf("%d\n", strlen(&p));//随机值--->p就为地址,&p还是地址,找到'\0'即可
printf("%d\n", strlen(&p+1));//随机值
printf("%d\n", strlen(&p[0]+1));//5

总结: 数组名的意义:

  1. sizeof(数组名),这里的数组名表示整个数组,计算的是整个数组的大小。
  2. &数组名,这里的数组名表示整个数组,取出的是整个数组的地址。
  3. 除此之外所有的数组名都表示首元素的地址。

猜你喜欢

转载自blog.csdn.net/Vcrossover/article/details/112652107