C语言进阶刷题笔记strlen和sizeof经典笔试题

Posted  Do

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C语言进阶刷题笔记strlen和sizeof经典笔试题相关的知识,希望对你有一定的参考价值。

目录

前言

sizeof与strlen的区别

一、sizeof

二、strlen函数

笔试题

实例1

实例2

实例3

实例4

实例5

总结


前言

        对于 strlen 和 sizeof,相信不少程序员会混淆其功能。虽然从表面上看它们都可以求字符串的长度,但二者却存在着许多不同之处及本质区别。

strlen 是一个函数,它用来计算指定字符串 str 的长度,但不包括结束字符(即 null 字符)。

关键字 sizeof 是一个单目运算符,而不是一个函数。与函数 strlen 不同,它的参数可以是数组、指针、类型、对象、函数等。

sizeof与strlen的区别

一、sizeof

sizeof()是运算符,其值在编译时就已经计算好了,参数可以是数组、指针、类型、对象、函数等。

它的功能是:获得保证能容纳实现所建立的最大对象的字节大小,简单点说就是计算变量或者类型所占的字节大小。

由于在编译时计算,因此sizeof不能用来返回动态分配的内存空间的大小。实际上,用sizeof来返回类型以及静态分配的对象、结构或数组所占的空间,返回值跟对象、结构、数组所存储的内容没有关系。

具体而言,当参数分别如下时,sizeof返回的值表示的含义如下:

  • 数组——编译时分配的数组空间大小;
  • 指针——存储该指针所用的空间大小(在32位机器上是4,64位机器上是8);
  • 类型——该类型所占的空间大小;
  • 对象——对象的实际占用空间大小;
  • 函数——函数的返回类型所占的空间大小。函数的返回类型不能是void。

二、strlen函数

我们知道strlen()是函数,要在运行时才能计算。参数必须是字符型指针(char*)。当数组名作为参数传入时,实际上数组就退化成指针了。

它的功能是:返回字符串的长度。
该字符串可能是自己定义的,也可能是内存中随机的,该函数实际完成的功能是从代表该字符串的第一个地址开始遍历,直到遇到结束符’\\0’停止。返回的长度大小不包括‘\\0’。


笔试题

        虽然我们了解了sizeof和strlen的这些基本概念,但是当他们和指针,一维数组,二维数组结合时,我们往往容易搞混,那么下面通过一些笔试题来彻底搞清楚他们的区别:

实例1

        int a[] = { 1,2,3,4 };
		printf("%d\\n", sizeof(a));//表示整个数组的大小,为16个字节

		printf("%d\\n", sizeof(a + 0));//首元素地址,即求指针大小,4/8个字节

		printf("%d\\n", sizeof(*a));//对首元素地址解引用得到元素大小,为4个字节

		printf("%d\\n", sizeof(a + 1));//2的地址,即指针大小,4/8个字节

		printf("%d\\n", sizeof(a[1]));//元素2的大小,4个字节

		printf("%d\\n", sizeof(&a));//整个数组地址指针的大小,4/8个字节

		printf("%d\\n", sizeof(*&a));//先取整个数组地址,再解引用,得到整个数组,其大小为1个字节

		printf("%d\\n", sizeof(&a + 1));//整个数组的下一个地址,即指针的大小,4/8个字节

		printf("%d\\n", sizeof(&a[0]));//指针大小,4/8个字节

		printf("%d\\n", sizeof(&a[0] + 1));//指针大小,4/8个字节

实例2

        char arr[] = { 'a','b','c','d','e','f' };//没有'\\0'

		printf("%d\\n", sizeof(arr));//计算整个数组大小,为6个字节
		printf("%d\\n", strlen(arr));//没有'\\0',随机值

		printf("%d\\n", sizeof(arr+0));//首元素地址,指针大小,4个字节
		printf("%d\\n", strlen(arr+0));//没有'\\0',就随机值

		printf("%d\\n", sizeof(*arr));//首元素大小,为1
		printf("%d\\n", strlen(*arr));//首元素的ASCII码值97当做地址,出现错误

		printf("%d\\n", sizeof(arr[1]));//b的大小,为1
		printf("%d\\n", strlen(arr[1]));//把值当做地址,出现错误

		printf("%d\\n", sizeof(&arr));//整个数组的地址,指针大小为4/8
		printf("%d\\n", strlen(&arr));//随机值

		printf("%d\\n", sizeof(&arr+1));//指针大小,4/8
		printf("%d\\n", strlen(&arr+1));//随机值

		printf("%d\\n", sizeof(&arr[0]+1));//4/8
		printf("%d\\n", sizeof(&arr[0]+1));//随机值

实例3

        char arr[] = "abcdef";//有'\\0'

		printf("%d\\n", sizeof(arr));//数组大小,7个字节
		printf("%d\\n", strlen(arr));//遇到\\0停止,为6个字节

		printf("%d\\n", sizeof(arr+0));//指针大小,4/8个字节
		printf("%d\\n", strlen(arr+0));//找到\\0停止,为6个字节

		printf("%d\\n", sizeof(*arr));//首元素大小,1个字节
		printf("%d\\n", strlen(*arr));//首元素ASCII码值作为地址,出错

		printf("%d\\n", sizeof(arr[1]));//b的大小为1
		printf("%d\\n", strlen(arr[1]));//把值作为地址,出错

		printf("%d\\n", sizeof(&arr));//整个数组地址即指针大小,4/8
		printf("%d\\n", strlen(&arr));//找\\0为止,大小为6

		printf("%d\\n", sizeof(&arr+1));//整个数组到下一个数组的地址,指针大小为4/8
		printf("%d\\n", strlen(&arr+1));//下一个数组,没有\\0就是随机值

		printf("%d\\n", sizeof(&arr[0]+1));//b的地址,指针大小为4/8
		printf("%d\\n", strlen(&arr[0]+1));//从b开始找到\\0为止,大小是5

实例4

        char* p = "abcdef";//指针p指向字符串的首元素a

		printf("%d\\n", sizeof(p));//存放a的地址,指针大小为4/8
		printf("%d\\n", strlen(p));//p指向a,从后开始找\\0,大小为6

		printf("%d\\n", sizeof(p+1));//b的地址,指针大小为4/8
		printf("%d\\n", strlen(p+1));//从b开始找\\0,大小为5

		printf("%d\\n", sizeof(*p));//解引用得到a,大小为1
		printf("%d\\n", strlen(*p));//将a的ASCII码作为地址,出错

		printf("%d\\n", sizeof(p[0]));//p[0]--->*(p+0),为a的大小,1个字节
		printf("%d\\n", strlen(p[0]));//值作为地址,出现错误

		printf("%d\\n", sizeof(&p));//指针的地址还是指针,大小为4/8
		printf("%d\\n", strlen(&p));//不确定指针是否存放了\\0,为随机值

		printf("%d\\n", sizeof(&p+1));//指针大小,4/8个字节
		printf("%d\\n", strlen(&p+1));//随机值

		printf("%d\\n", sizeof(&p[0]+1));//&(*(p+0)),相当于首元素的地址,为指针大小,4/8个字节
		printf("%d\\n", strlen(&p[0]+1));//从b开始数到\\0为止,为5个字节

实例5

         int  b[3][4] = { {1,2,3,4},{1,1,1,1},{2,2,2,2} };

         printf("%d\\n", sizeof(b));//整个二维数组的大小,即48个字节

         printf("%d\\n", sizeof(b[0][0]));//首元素大小,4个字节

         printf("%d\\n", sizeof(b[0]));//第一行作为数组名,计算一维数组的大小,即16个字节

         printf("%d\\n", sizeof(b[0]+1));//表示第一行第二个地址,大小是4/8个字节
       
         printf("%d\\n", sizeof(*(b[0]+1)));//解引用得到的第一行第二个元素的大小,是4个字节

         printf("%d\\n", sizeof(b+1));//b表示第一行的地址,+1表示第二行的地址,大小是4/8个字节

         printf("%d\\n", sizeof(*(b + 1)));//解引用得到第二行的元素,大小是16个字节

         printf("%d\\n", sizeof(&b[0]+1));//取第二行的地址,大小是4/8个字节

         printf("%d\\n", sizeof(*(&b[0]+1)));//解引用得到第二行的元素,大小是16个字节

         printf("%d\\n", sizeof(b[3]));//不存在第四行元素,但是也能通过类型计算大小,即16个字节

         printf("%d\\n", sizeof(*b));//*b表示对第一行的地址解引用得到第一行的元素,大小是16个字节

总结

        当数组名单独在sizeof内部时,表示计整个数组的空间大小,单位是字节,当&(数组名)时,取的是整个数组的地址,除了这两种情况,所有的数组名都表示的是首元素的地址。

sizeof的参数可以是类型名,数组名,指针名,当然还可以是函数名和对象名,但是strlen的参数必须是字符型指针名。

好了,这就是我要给大家分享的题目,看完这些相信你一定有所收获,希望能帮助到大家,看完别忘记三连哟!

以上是关于C语言进阶刷题笔记strlen和sizeof经典笔试题的主要内容,如果未能解决你的问题,请参考以下文章

C语言进阶刷题笔记strlen和sizeof经典笔试题

指针进阶—指针和数组笔试题解析[建议收藏]

C语言sizeof与strlen详解(附大量笔试题题解过程)

C语言指针进阶(下)

无意中发现一位大佬的 C++ 刷题 pdf 笔记

大厂指针笔试题(1码+1图)详解——程序结果判断题