C语言使用sizeof和strlen计算数组和指针大小

 更新时间:2023年11月10日 15:08:46   作者:威震江湖梦  
sizeof()一般是用来求取 变量 或者 类型 所占内存空间的大小,strlen()是一个库函数是专门用来计算 字符串 长度的,下面我们就来看看C语言如何使用sizeof和strlen计算数组和指针大小吧

一、知识回顾

1、回顾sizeof()、strlen的作用

  • sizeof()是用来求取 变量 或者 类型 所占内存空间的大小(单位:字节)。
  • sizeof计算的是占用内存空间的大小,单位是字节,不关注内存中到底存放的是什么。sizeof不是函数,是操作符
  • strlen()是一个库函数是专门用来计算 字符串 长度的,在对其进行调用前是需要包含头文件<string.h>。
  • strlen()函数是通过字符串结束标志 \0 来计算字符串长度的,但计算出来的字符串长度是不包括 \0 的,也就是说所谓的长度就是 \0 前字符的个数。strlen是函数

sizeof是一个运算符,用于计算一个变量或数据类型所占的字节数,不论变量中存储的数据是否为空。而strlen是一个函数,用于计算一个字符串中的字符数,不包括字符串末尾的空字符'\0'。 另外,sizeof可以用于计算任意数据类型的大小,包括基本数据类型和自定义数据类型。 而strlen只能用于计算字符串的长度。 因此,sizeof通常用于确定数组所占的存储空间,而strlen用于确定字符串的长度。

2、数组和指针

  • 数组 - 能够存放一组相同类型的元素,数组的大小取决于数组的元素个数和元素类型。
  • 指针就是地址,大小都是4/8。(32位机器是4字节,64位机器是8字节)

3、数组名

大部分情况下数组名是首元素地址。

2个例外 sizeof(数组名) —— 数组名表示整个数组,计算的是整个数组的大小。(看数组名是否是单独放在sizeof()里面) &数组名 ————-数组名表示整个数组,取出的是数组的地址

二、sizeof()、strlen()的对比

1、注意区别

  • 字符数组 - char arr1[]={'a','b','c','d','e','f'} ->[a,b,c,d,e,f]
  • 字符串数组 - char arr2[]="abcdef" ->[a,b,c,d,e,f,/0]
  • sizeof()计算的是占用内存空间的大小,单位是字节,不关注内存中到底存放的是什么。
  • strlen()是针对字符串的,求的是字符串的长度,本质上统计的是/0之前出现的字符个数。

2、一维数组与一级指针

整型数组

	int a[] = { 1,2,3,4 };
	
	printf("%d\n", sizeof(a[1]));//4
	
	printf("%d\n", sizeof(a));//16 
	//sizeof(a) 就是数组名单独放在sizeof内部 计算的是整个数组的大小。

	printf("%d\n", sizeof(a + 0));// 4/8
	//a + 0   a不是单独放在sizeof()里面,则是数组首元素的地址,sizeof则是计算数组首元素地址的大小
	
	printf("%d\n", sizeof(*a));//4
	//a不是单独放在sizeof()里面,则是数组首元素的地址 *a == a[0],sizeof()则是计算首元素的大小。
	//*a -> *&a[0] -> a[0]

	printf("%d\n", sizeof(a + 1));// 4/8
	//a不是单独放在sizeof()里面,则是数组首元素的地址 -- int*
	//a+1 跳过1个整型,是第二个元素的地址 sizeof()是计算第二个元素地址的大小。

	printf("%d\n", sizeof(&a));/ /4/8
	//&a - 取出的是数组的地址,但是数组的地址也是地址,地址的的大小就是4/8。
	//int (*pa)[4] = &a;

	printf("%d\n", sizeof(*&a));//16
	//等于sizeof(a)

	printf("%d\n", sizeof(&a+1));// 4/8
	//&a --> int (*)[4],取出的是数组的地址。
	//&a + 1 则要跳过一个数组。

	printf("%d\n", sizeof(&a[0]));
	//取出首元素地址,sizeof计算的是元素的地址4/8
	
	printf("%d\n", sizeof(&a[0]+1));//4/8
	//取出的是第二个元素的地址,sizeof()计算的是地址的大小。

字符数组

	char arr[] = {'a','b','c','d','e','f'};
	
	printf("%d\n", sizeof(arr));//6
	
	printf("%d\n", sizeof(arr + 0));// 4/8
	//arr不单独放在sizeof里面,是数组首元素的地址 ,计算的大小为4/8
	
	printf("%d\n", sizeof(*arr));//1
	//arr不单独放在sizeof里面,arr是首元素地址,*arr 是首元素,大小为1
	
	printf("%d\n", sizeof(arr[1]));//元素'b'
	
	printf("%d\n", sizeof(&arr));// 4/8
	//&arr 是数组的地址,地址的大小的都是 4/8
	
	printf("%d\n", sizeof(&arr + 1));//4/8
	printf("%d\n", sizeof(&arr[0] + 1));//4/8
	
	//*****************************************
	
	printf("%d\n", strlen(arr));//随机值
	//arr数组首元素地址,找不到‘\0',所以是计算的大小是随机值
	printf("%d\n", strlen(arr + 0));//随机值,同上
	
	printf("%d\n", strlen(*arr));//非法访问
	//strlen传入char*(地址)
	//*arr = 'a'——>(97)被当成地址,非法访问
	
	printf("%d\n", strlen(arr[1]));//非法访问,同上
	
	printf("%d\n", strlen(&arr));//随机值
	//找不到/0
		
	printf("%d\n", strlen(&arr + 1));//随机值 - 6
	printf("%d\n", strlen(&arr[0] + 0));//随机值 - 1

字符串数组

	char arr[]="abcdef";//[a b c d e f /0]
	
	printf("%d\n",sizeof(arr));//整个数组大小 7
	printf("%d\n",sizeof(arr+0));//首元素地址大小 4/8
	
	printf("%d\n",sizeof(*arr));//首元素大小 1
	//*arr = arr[0] = *(arr+0)
	
	printf("%d\n",sizeof(arr[1]));//1
	
	printf("%d\n",sizeof(&arr));//数组的地址,大小 4/8
	printf("%d\n",sizeof(&arr+1));//+1 跳过一个数组的地址,大小 4/8
	printf("%d\n",sizeof(&arr[0]+1));//+1 跳过一个元素的地址,大小 4/8
	
	//******************************************************************

	printf("%d\n",strlen(arr));//arr表示首元素地址,计算得到数组大小为 6
	printf("%d\n",strlen(arr+0));//6,同上
	
	printf("%d\n",strlen(*arr));//非法访问
	printf("%d\n",strlen(arr[1]));//非法访问
	//strlen是传入char*地址,*arr和arr[1]是数组的元素,传给strlen会被当做地址,造成非法访问
	
	printf("%d\n",strlen(&arr));//&arr表示整个数组的大小,6
	printf("%d\n",strlen(&arr+1));//数组的地址 +1后就找不到 /0 ,大小为随机值
	printf("%d\n",strlen(&arr[0]+1));//从第二个元素开始算,大小为5

指针

	char* p="abcdef";
	printf("%d\n",sizeof(p));//4/8
	//指针变量p 存放着的是地址,所以大小为4/8
	
	printf("%d\n",sizeof(p+1));//字符'b‘的地址,大小为4/8
	
	printf("%d\n",sizeof(*p));
	//解引用的一个char类型元素,大小为1
	
	printf("%d\n",sizeof(p[0]));//1
	//p[0] = *(p+0)
	printf("%d\n",sizeof(&p));//4/8
	
	printf("%d\n",sizeof(&p+1));
	//+1跳过一个char*地址,还是地址,大小还是4/8

	//********************************************

	printf("%d\n",strlen(p));//大小为 6
	printf("%d\n",strlen(p+1));//p+1是'b'的地址,从'b'开始算,大小为5
	printf("%d\n",strlen(*p));//*p为'a',不是地址,非法访问
	
	printf("%d\n",strlen(&p));//随机值
	//&p取的是变量p的地址,不是p里面存放的地址,所以无法找打字符串
	printf("%d\n",strlen(&p+1));//随机值,同上
	
	printf("%d\n",strlen(&p[0]+1));//大小为 5
	//p[0]是'a‘,&p[0]去'a'的地址,+1的'b'的地址,从'b'开始计算
	

3、二维数组与二级指针

整型数组

	int a[3][4]={0};//三行四列的数组
	printf("%d\n",sizeof(a));//4*3*4=48
	//a这个数组名单独放在sizeof里面,表示整个数组,计算的是整个数组的大小
	
	printf("%d\n",sizeof(a[0][0]));//第一行第一个元素,大小4字节
	
	printf("%d\n",sizeof(a[0]));//16
	//a[0] 是第一行的数组名,这是数组名单独放在sizeof内部,计算的是第一行数组的大小
	
	printf("%d\n",sizeof(a[0]+1));//4/8
	//a[0]不是单独放在sizeof内部,表示的是首元素的地址。即第一行第一个元素的地址,相当于&a[0][0]
	//a[0]+1 是第一行第二个元素的地址,相当于&a[0][1]
	
	printf("%d\n",sizeof(a+1));//4/8
	//a作为二维数组的数组名,并非单独放在sizeof内部,所以表示首元素是地址
	//二维数组的首元素是第一行,这里的a就是第一行的地址
	//a+1是跳过第一行,指向第二行
	
	printf("%d\n",sizeof(*(a+1)));//16
	//*(a+1) -> a[1],计算的是第二行的大小
	
	printf("%d\n",sizeof(&a[0]+1));//4/8
	//&a[0]是第一行的地址
	//&a[0]+1是第二行的地址
	
	printf("%d\n",sizeof(*(&a[0]+1)));//表示第二行,大小为16
	printf("%d\n",sizeof(*a));//16
	//*a --> *(a+0)表示第一行,大小为16

三、总结回顾

sizeof(数组名),这里的数组名表示整个数组,计算的是数组的大小。

&数组名,这里的数组名表示整数数组,取出的是整个数组的地址。

除此之外所有的数组名都表示首元素的地址。

到此这篇关于C语言使用sizeof和strlen计算数组和指针大小的文章就介绍到这了,更多相关C语言sizeof strlen内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • C++ MiniZip实现目录压缩与解压的示例详解

    C++ MiniZip实现目录压缩与解压的示例详解

    Zlib是一个开源的数据压缩库,提供了一种通用的数据压缩和解压缩算法,本文主要为大家详细介绍了如何利用Zlib实现目录压缩与解压,需要的小伙伴可以参考下
    2023-11-11
  • C语言关键字union的定义和使用详解

    C语言关键字union的定义和使用详解

    这篇文章主要介绍了C语言关键字union的定义和使用详解,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2021-02-02
  • C语言变量类型与输出控制用法实例教程

    C语言变量类型与输出控制用法实例教程

    这篇文章主要介绍了C语言变量类型与输出控制用法,是C语言程序设计中比较基础也是比较重要的用法,需要的朋友可以参考下
    2014-08-08
  • C++中Copy-Swap实现拷贝交换

    C++中Copy-Swap实现拷贝交换

    本文主要介绍了C++中Copy-Swap实现拷贝交换,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2023-07-07
  • C++ 实现桶排序的示例代码

    C++ 实现桶排序的示例代码

    桶排序或所谓的箱排序,是一个排序算法,工作的原理是将数组分到有限数量的桶子,本文详细的介绍了如何实现,感兴趣的可以了解一下
    2021-07-07
  • C++使用jsoncpp库解析Json

    C++使用jsoncpp库解析Json

    对json的解析操作是我们日常开发中经常会遇到的一个需求,下面这篇文章主要给大家介绍了关于C++使用jsoncpp库解析Json的相关资料,需要的朋友可以参考下
    2021-06-06
  • C++中继承基类与派生类的区别

    C++中继承基类与派生类的区别

    这篇文章主要介绍了C++中继承基类与派生类的区别,面向对象程序设计中最重要的一个概念是继承。继承允许我们依据另一个类来定义一个类,这使得创建和维护一个应用程序变得更容易,需要的朋友可以参考下
    2023-05-05
  • C++使用ImGUI框架开发一个简单程序

    C++使用ImGUI框架开发一个简单程序

    ImGui 是一个用于C++的用户界面库,跨平台、无依赖,支持OpenGL、DirectX等多种渲染API,下面就跟随小编一起学习一下如何使用ImGUI框架开发一个简单程序吧
    2023-08-08
  • C语言 智能指针 shared_ptr 和 weak_ptr

    C语言 智能指针 shared_ptr 和 weak_ptr

    这篇文章主要介绍了C语言 智能指针 shared_ptr 和 weak_ptr,weak_ptr引入可以解决shared_ptr交叉引用时无法释放资源的问题,下面来学习具体相关内容吧,需要的朋友可以参考一下
    2022-04-04
  • 自己实现strcpy函数的实现方法

    自己实现strcpy函数的实现方法

    本篇文章介绍了,自己实现strcpy函数的实现方法。需要的朋友参考下
    2013-05-05

最新评论