sizeof 和 strlen的对比及笔试题目

简介: sizeof 和 strlen的对比及笔试题目

sizeof 和 strlen主要区别如下:

1、sizeof是运算符,strlen是C语言标准库函数。

2、 strlen 测量的是字符串的实际长度,以’\0’ 结束,返回结果不包括’\0’ 。

3、而sizeof 测量的是字符的分配大小,它的参数可以是数组、指针、类型、对象、函数等。

题目1:

int main()
{
   char arr[20] = "abcdef";
   size_t len = strlen(arr);//6
  //统计的是从strlen函数的参数str中这个地址开始向后,\0之前字符串中字符的个数


   printf("len = %zd\n", len);
   size_t sz = sizeof(arr);//20
   printf("sz = %zd\n", sz);

 char arr[] = { 'a','b','c'};//42,随机的,编译器随机

     \0的位置不确定,终的数值也不确定

   printf("%zd\n", strlen(arr));

   

   char arr[6] = "abcdef";//err \0 有7个字符,越界

   return 0;

}

题目2:

int main()
{
   int a[] = { 1,2,3,4 };//a数组有四个元素,每个元素是int类型的数据

   printf("%d\n", sizeof(a));//16 - sizeof(数组名)的情况,计算整个数组的大小,单位是字节 - 4 * 4 = 16
   printf("%d\n", sizeof(a + 0));//4 or 8 取决于是32位还是64位
   //a表示的是数组首元素的地址,a+0还是首元素的地址

   printf("%d\n", sizeof(*a));//4  a表示的是数组首元素的地址,*a就是首元素,大小是4个字节
   printf("%d\n", sizeof(a + 1));//4 or 8

 

//a + 1是第二个元素的地址

   printf("%d\n", sizeof(a[1]));//4  a[1]是数组的第二个元素,大小是4个字节
   printf("%d\n", sizeof(&a));//4 or 8  &a - 取出的是数组的地址,但是数组的地址也是地址,
   //int (*pa)[4] = &a
   //int (*)[4]
   
   printf("%d\n", sizeof(*&a));//16
  //1.抵消  &*  sizeof(*&a) == sizeof(a)
   //2.&a 的类型是数组指针,int(*)[4],*&a就是对数字指针解引用访问一个数组的大小,是16个字节

   printf("%d\n", sizeof(&a + 1));//4 or 8 &a+1是跳过整个数组后的地址,是地址,大小就是4/8个字符
   printf("%d\n", sizeof(&a[0])); //4 or 8 &a[0]是第一个元素的地址,大小就是4/8个字符
   printf("%d\n", sizeof(&a[0] + 1));//4 or 8
   //&a[0]+1是第二个元素的地址,大小就是4/8个字符

   return 0;
}

题目3:

int main()
{
   char arr[] = { 'a','b','c','d','e','f' };//arr数组中有6个元素

   printf("%d\n", sizeof(arr));//6 计算的是整个数组的大小
   printf("%d\n", sizeof(arr + 0));//4 or 8 arr+0是数组的第一个元素的地址
   printf("%d\n", sizeof(*arr));//1  *arr是首元素地址的解引用,就是1个字节
   printf("%d\n", sizeof(arr[1]));//1 - arr[1] = 'b'
   printf("%d\n", sizeof(&arr));//4 or 8
   printf("%d\n", sizeof(&arr + 1));//4 or 8
   printf("%d\n", sizeof(&arr[0] + 1));//4 or 8

   return 0;
}

题目4:

int main()
{
   char arr[] = "abcdef";
   printf("%zd\n", sizeof(arr));
   //sizeof的返回值是size_t,是无符号型,应该用%zd接收

   printf("%zd\n", sizeof(arr + 0));//arr+0是数组首元素的地址,地址大小是4、8个字节
   printf("%zd\n", sizeof(*arr));//*arr是数组首元素,这里计算的是首元素的大小 1
   printf("%zd\n", sizeof(arr[1]));//1
   printf("%zd\n", sizeof(&arr));//&arr - 是数组的地址,数组的地址也是地址 4/8
   printf("%zd\n", sizeof(&arr + 1));&arr+1,跳过整个数组,指向了数组的后边 4/8
   printf("%zd\n", sizeof(&arr[0] + 1));//&arr[0]+1是第二个元素的地址 4/8

   return 0;

}

此时&arr+1跳过整个数组

题目5:

int main()
{
   char arr[] = "abcdef";

   printf("%zd\n", strlen(arr));//arr是数组首元素的地址 6
   printf("%zd\n", strlen(arr + 0));//arr + 0 是数组首元素的地址 6
   printf("%zd\n", strlen(*arr));//  传递的是'a' - 97 //err
   printf("%zd\n", strlen(arr[1]));// 'b' - 98 //err
   printf("%zd\n", strlen(&arr));//6 ,&arr虽然是数组的地址,但是也是指向数组arr的起始位置
   printf("%zd\n", strlen(&arr + 1));//随机值
   printf("%zd\n", strlen(&arr[0] + 1));//&arr[0] + 1是第二个元素的地址 - 5
   
   return 0;
}

这里如果要传参,则用char *p来接收&arr,接收后的类型为char (*)[7],但strlen所需要的形参类型为char *str,编译会警告,但仍然能传递

(补充:因为strlen函数要求传入一个指向字符的指针,而不是一个指向字符数组的指针。而char (*p)[7]是一个指向字符数组的指针,所以当它传入strlen函数时会出现警告。

题目6:

int main()
{
   char* p = "abcdef";
   printf("%d\n", sizeof(p));//4/8 计算的指针变量的大小
   printf("%d\n", sizeof(p + 1));//p + 1是'b'的地址,是地址大小就是4/8个字节
   printf("%d\n", sizeof(*p));//*p就是'a',大小是1个字节
   printf("%d\n", sizeof(p[0]));//p[0]-->*(p+0) - *p//1个字节
   printf("%d\n", sizeof(&p));//&p也是地址,是指针变量p的地址大小是4/8字节
   printf("%d\n", sizeof(&p + 1));//&p+1是指向p指针变量后面的空间,也是地址 - 4/8
   printf("%d\n", sizeof(&p[0] + 1));//&p[0]+1是'b'的地址 - 4/8
   return 0;
}

int main()
{
   char* p = "abcdef";
   printf("%zd\n", strlen(p)); //6
   printf("%zd\n", strlen(p + 1));//5
   printf("%zd\n", strlen(*p));//'a'-97 err
   printf("%zd\n", strlen(p[0]));//p[0]--*(p+0)-->*p //err
   printf("%zd\n", strlen(&p));//随机值 不确定\0的位置
   printf("%zd\n", strlen(&p + 1));//同上
   printf("%zd\n", strlen(&p[0] + 1));//从b的地址往后数 - 5

   return 0;
}

二维数组题(重点):

int main()
{
   //二维数组也是数组,之前对数组名的理解也同样适用
   int a[3][4] = { 0 };
   printf("%zd\n", sizeof(a));

   //12*4 = 48个字节,数组名单独放在sizeof内部
   printf("%zd\n", sizeof(a[0][0]));//4
   printf("%zd\n", sizeof(a[0]));

   //a[0]是第一行这个一维数组的数组名,数组名单独放在了sizeof内部了
   //计算的是第一行的大小,单位是字节,16个字节

   printf("%zd\n", sizeof(a[0] + 1));

   //a[0]是第一行这个一维数组的数组名,这里表示首元素地址
   //也就是a[0][0]的地址,a[0]+1是a[0][1]的地址

   printf("%zd\n", sizeof(*(a[0] + 1)));//a[0][1] - 4个字节
   printf("%zd\n", sizeof(a + 1));

    //a是二维数组的数组名,但是没有&,也没有单独放在sizeof内部
   //所以这里的a是数组首元素的地址,应该是第一行的地址,a+1是第二行的地址
   //大小也是4/8个字节
   printf("%zd\n", sizeof(*(a + 1)));

   //*(a+1)==>a[1] - 第二行的数组名,单独放在sizeof内部,计算的是第二行的大小 - 16个字节
   printf("%zd\n", sizeof(&a[0] + 1));

    //&a[0]是第一行的地址,&a[0]+1就是第二行的地址 4/8

   printf("%zd\n", sizeof(*(&a[0] + 1)));

    //访问第二行,计算的是第二行的大小,16个字节
   //int(*p)[4] = &a[0]+1

   printf("%zd\n", sizeof(*a));

   //这里的a是第一行的地址,*a就是第一行,sizeof(*a)计算的是第一行的大小 - 16
   //*a -->*(a+0)-->a[0]
   printf("%zd\n", sizeof(a[3]));

   //这里不存在越界
   //sizeof内部的表达式不会真实计算的
   //计算的是第四行的大小 - 16

   return 0;
}

上述题目总结:

相关文章
|
2月前
|
C语言
【C语言】指针进阶之sizeof和strlen函数的对比
【C语言】指针进阶之sizeof和strlen函数的对比
|
2月前
|
存储
sizeof和strlen的对⽐及例题
sizeof和strlen的对⽐及例题
17 1
|
3月前
|
C语言 C++
C语言变量、地址、字符及printf()/sizeof()/scanf()函数介绍
C语言变量、地址、字符及printf()/sizeof()/scanf()函数介绍
11 0
|
5月前
|
C++
浅学指针(5)sizeof和strlen的进阶理解
浅学指针(5)sizeof和strlen的进阶理解
|
6月前
sizeof运算和strlen函数的笔试题(三)
sizeof运算和strlen函数的笔试题(三)
|
6月前
sizeof运算与strlen函数笔试题(二)
sizeof运算与strlen函数笔试题(二)
|
7月前
|
存储
指针进阶(3) -- 关于sizeof和strlen的详细总结(下)
指针进阶(3) -- 关于sizeof和strlen的详细总结(下)
|
7月前
|
存储
指针进阶(3) -- 关于sizeof和strlen的详细总结(中)
指针进阶(3) -- 关于sizeof和strlen的详细总结(中)
|
7月前
指针进阶(3) -- 关于sizeof和strlen的详细总结(上)
指针进阶(3) -- 关于sizeof和strlen的详细总结(上)
|
10月前
|
C语言
【C语言】sizeof和strlen的区别【详解】
【C语言】sizeof和strlen的区别【详解】
147 0