IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> 带你一起拿下strlen和sizeof(C语言系列17) -> 正文阅读

[C++知识库]带你一起拿下strlen和sizeof(C语言系列17)

目录

前言:?

知识点回顾:

strlen:

sizeof:

数组名:

实战演练:

一维数组:

1.int a[] = {1,2,3,4}对于sizeof的分析。

2.char arr[] = {'a','b','c','d','e','f'}对于sizeof的分析。

3.char arr[] = {'a','b','c','d','e','f'}对于strlen的分析。

4.char arr[] = "abcdef"对于sizeof的分析。

5.char arr[] = "abcdef"对于strlen的分析。

6.char* p?= "abcdef"对于sizeof的分析。

7.char* p?= "abcdef"对于strlen的分析。

二维数组:?

8.int a[3][4] = {0}对于sizeof的分析。

结束语:


前言:?

你是不是还为区分strlen和sizeof而焦头烂额呢?它两真的有那么难区分吗?接下来就让小编带大家一起来重新认识一下它两吧,带你一起走进指针、数组与它两的“爱恨情仇”吧!

知识点回顾:

strlen:

是函数,返回的是参数的字符串的长度。(它关注的是\0的位置,\0之前出现多少个字符,字符串的长度就是多少)。

sizeof:

是操作符返回的是参数所占的内存数,不在乎\0,遇到也会被计算进去。

数组名:

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

2.&数组名:数组名表示整个数组,取出的是整个数组的地址。

3.除此之外:所有的数组名都是数组首元素的地址。


实战演练:

一维数组:

1.int a[] = {1,2,3,4}对于sizeof的分析。

代码展示:

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
int main()
{
	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));// 4/8
	printf("%d\n", sizeof(a[1]));//4
	printf("%d\n", sizeof(&a));// 4/8
	printf("%d\n", sizeof(*&a));//16
	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
	return 0;
}


代码运行结果:

分析:


2.char arr[] = {'a','b','c','d','e','f'}对于sizeof的分析。

代码展示:

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
int main()
{
	char arr[] = { 'a','b','c','d','e','f' };
	printf("%d\n", sizeof(arr));//6
	printf("%d\n", sizeof(arr + 0));// 4/8
	printf("%d\n", sizeof(*arr));//1
	printf("%d\n", sizeof(arr[1]));//1
	printf("%d\n", sizeof(&arr));// 4/8
	printf("%d\n", sizeof(&arr + 1));// 4/8
	printf("%d\n", sizeof(&arr[0] + 1));// 4/8
	return 0;
}

代码运行结果:

分析如下代码中的注释所示:

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
int main()
{
	char arr[] = { 'a','b','c','d','e','f' };
	printf("%d\n", sizeof(arr));//6
	//当arr单个放置于sizeof时属于第一种情况,计算的是整个数组的大小,故是6。
	printf("%d\n", sizeof(arr + 0));// 4/8
	//arr + 0放置于sizeof中时属于第三种情况,arr是数组名拿到的是数组首元素的地址,再加0则还是表示数组的第一个元素的地址,即是地址那么它的大小就是4/8。
	printf("%d\n", sizeof(*arr));//1
	//*arr此时属于第三种情况,arr是数组首元素的地址,那么*arr拿到的就是数组的第一个元素,因为类型为char类型的,故计算出的大小就是1。
	printf("%d\n", sizeof(arr[1]));//1
	//arr[1]也属于第三种情况,arr[1]就是数组的第一个元素,故大小为1。
	printf("%d\n", sizeof(&arr));// 4/8
	//&arr属于第三种情况,&arr拿到的是整个数组的地址,但是同样也为地址,即是地址则大小就为4/8。
	printf("%d\n", sizeof(&arr + 1));// 4/8
	//&arr + 1 属于第三种情况,&arr拿到的是整个数组的地址,再加1跳过的是整个数组,但是同样也为地址,即是地址那么大小就为4/8。
	printf("%d\n", sizeof(&arr[0] + 1));// 4/8
	//&arr[0] + 1 属于第三种情况&arr[0]找到的是数组第一个元素的地址,再加1则找到的就是数组第二个元素的地址,即是地址那么大小也就为4/8。
	return 0;
}

?

3.char arr[] = {'a','b','c','d','e','f'}对于strlen的分析。

代码展示:

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<string.h>
int main()
{
	char arr[] = { 'a','b','c','d','e','f' };
	printf("%d\n", strlen(arr));//随机值
	printf("%d\n", strlen(arr + 0));//随机值
	printf("%d\n", strlen(*arr));//报错
	printf("%d\n", strlen(arr[1]));//报错
	printf("%d\n", strlen(&arr));//随机值
	printf("%d\n", strlen(&arr + 1));//随机值
	printf("%d\n", strlen(&arr[0] + 1));//随机值
	return 0;
}

运行结果:

注意:下面代码的运行结果是屏蔽了报错的代码行的。

分析:

?具体分析如下代码中的注释所示:

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<string.h>
int main()
{
	char arr[] = { 'a','b','c','d','e','f' };
	printf("%d\n", strlen(arr));//随机值
	//由于在内存中存储的时候没有\0,故是随机值
	printf("%d\n", strlen(arr + 0));//随机值
	//arr找到的是数组首元素的地址,再加0找到的还是首元素的地址,不确定\0的具体位置,故计算出的是随机值
	printf("%d\n", strlen(*arr));//报错
	//*arr是数组第一个元素'a',拿到的就是97,不符合strlen的计算方式。
	printf("%d\n", strlen(arr[1]));//报错
	//arr[1]是数组第一个元素'a',拿到的就是97,不符合strlen的计算方式。
	printf("%d\n", strlen(&arr));//随机值
	//&arr拿到的是数组整个元素的地址,从第一个数组元素往后找\0时,由于不确定\0的具体位置,所以计算出来的是一个随机值
	printf("%d\n", strlen(&arr + 1));//随机值
	//与上面的相类似&arr + 1 是跳过整个数组向后数,由于不确定\0的位置,故计算出来的也是随机值。
	printf("%d\n", strlen(&arr[0] + 1));//随机值
	//&arr[0] + 1是从数组的第二个元素向后数,计算出来的也是随机值。
	return 0;
}

?

4.char arr[] = "abcdef"对于sizeof的分析。

代码展示:

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
int main()
{
	char arr[] = "abcdef";
	printf("%d\n", sizeof(arr));//7
	printf("%d\n", sizeof(arr + 0));//4/8
	printf("%d\n", sizeof(*arr));//1
	printf("%d\n", sizeof(arr[1]));//1
	printf("%d\n", sizeof(&arr));//4/8
	printf("%d\n", sizeof(&arr + 1));//4/8
	printf("%d\n", sizeof(&arr[0] + 1));//4/8
	return 0;
}

运行结果:

分析:

具体分析如下代码注释所示:

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
int main()
{
	char arr[] = "abcdef";
	printf("%d\n", sizeof(arr));//7
	//arr单独放置于sizeof中属于第一种情况,计算出来的是整个数组的大小,由于还存在\0故计算出来的是7。
	printf("%d\n", sizeof(arr + 0));//4/8
	//arr + 0 属于第三种情况,arr + 0拿到的是数组首元素的地址,即是地址那么就是4/8。
	printf("%d\n", sizeof(*arr));//1
	//*arr属于第三种情况,*arr拿到的是数组的第一个元素,由于是char类型的,故计算出来的大小是1。
	printf("%d\n", sizeof(arr[1]));//1
	//arr[1]也属于第三种情况,拿到的是数组的第一个元素,由于是char类型的,故计算出来的大小是1。
	printf("%d\n", sizeof(&arr));//4/8
	//&arr拿到的是整个数组的地址,即是地址那么大小就是4/8。
	printf("%d\n", sizeof(&arr + 1));//4/8
	//&arr + 1是跳过整个数组,拿到的是整个数组后面的地址,即是地址那么大小就是4/8。
	printf("%d\n", sizeof(&arr[0] + 1));//4/8
	//&arr[0] 拿到的是数组首元素的地址,再加1拿到的是第二个元素的地址,即是地址那么大小就是4/8。
	return 0;
}

?

5.char arr[] = "abcdef"对于strlen的分析。

代码展示:

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<string.h>
int main()
{
	char arr[] = "abcdef";
	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
	printf("%d\n", strlen(&arr + 1));//随机值
	printf("%d\n", strlen(&arr[0] + 1));//5
	return 0;
}

运行结果:

注意:下面代码的运行结果是屏蔽了报错的代码行的。

分析:

具体分析如下代码中的注释所示:

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<string.h>
int main()
{
	char arr[] = "abcdef";
	printf("%d\n", strlen(arr));//6
	//arr拿到的是数组首元素的地址,从首地址开始往后找\0停下就可以计算出arr的大小了,6。
	printf("%d\n", strlen(arr + 0));//6
	//arr + 0 也代表的是数组首元素的地址,与上面的相同。
	printf("%d\n", strlen(*arr));//报错
	//*arr找到的是数组的首元素,穿给strlen的是a的ASCII码值97,故会使得计算出错。
	printf("%d\n", strlen(arr[1]));//报错
	//与上面的相同arr[1]找到的也是数组的第一个元素,故也会使得计算出错。
	printf("%d\n", strlen(&arr));//6
	//&arr拿到的是整个数组的地址,故计算出来的就是整个数组的长度6。
	printf("%d\n", strlen(&arr + 1));//随机值
	//&arr + 1是跳过了整个数组,在往后就不能确定\0的具体位置了,故是随机值。
	printf("%d\n", strlen(&arr[0] + 1));//5
	//&arr[0]拿到的是数组的第一个元素的地址,再加1拿到的是第二个元素的地址,从第二个往后找\0那么计算出来的就是5。
	return 0;
}

?

6.char* p?= "abcdef"对于sizeof的分析。

代码展示:

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
int main()
{
	char* p = "abcdef";
	printf("%d\n", sizeof(p));//4/8
	printf("%d\n", sizeof(p + 1));//4/8
	printf("%d\n", sizeof(*p));//1
	printf("%d\n", sizeof(p[0]));//1
	printf("%d\n", sizeof(&p));//4/8
	printf("%d\n", sizeof(&p + 1));//4/8
	printf("%d\n", sizeof(&p[0] + 1));//4/8
	return 0;
}

运行结果:

分析:

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
int main()
{
	char* p = "abcdef";
	printf("%d\n", sizeof(p));//4/8
	//p所指向的是数组首元素的地址,即是地址那么大小就为4/8。
	printf("%d\n", sizeof(p + 1));//4/8
	//p是数组首元素的地址,再加1拿到的就是第二个元素的地址,即是地址那么大小就是4/8。
	printf("%d\n", sizeof(*p));//1
	//p是数组首元素的地址,*p拿到的就是第一个数组,由于它的类型是char*,那么大小就是1。
	printf("%d\n", sizeof(p[0]));//1
	//p[0]找到的就是第一个元素,相当于*(p + 0),故大小就为1。
	printf("%d\n", sizeof(&p));//4/8
	//&p拿到的是整个数组元素的地址,即是地址那么大小就为4/8。
	printf("%d\n", sizeof(&p + 1));//4/8
	//&p + 1是跳过整个数组,拿到数组后面的地址,即是地址那么大小就为4/8。
	printf("%d\n", sizeof(&p[0] + 1));//4/8
	//&p[0]拿到的是数组首元素的地址,再加1拿到的就是数组第二个元素的地址,即是地址那么大小就为4/8。
	return 0;
}

?

7.char* p?= "abcdef"对于strlen的分析。

代码展示:

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<string.h>
int main()
{
	char* p = "abcdef";
	printf("%d\n", strlen(p));//6
	printf("%d\n", strlen(p + 1));//5
	printf("%d\n", strlen(*p));//报错
	printf("%d\n", strlen(p[0]));//报错
	printf("%d\n", strlen(&p));//随机值
	printf("%d\n", strlen(&p + 1));//随机值
	printf("%d\n", strlen(&p[0] + 1));//5
	return 0;
}

运行结果:

注意:下面代码的运行结果是屏蔽了报错的代码行的。


分析:

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<string.h>
int main()
{
	char* p = "abcdef";
	printf("%d\n", strlen(p));//6
	//p是数组首元素的地址,从数组的首元素开始往后数,直到找到\0停止,那么计算出来的大小就是6。
	printf("%d\n", strlen(p + 1));//5
	//p是数组首元素的地址,再加1找到的就是数组第二个元素的地址,从第二个元素开始往后找\0,那么计算出来的大小就是5。
	printf("%d\n", strlen(*p));//报错
	//*p就是数组第一个元素,传给strlen的就是a的ASCII码值,故计算错误。
	printf("%d\n", strlen(p[0]));//报错
	//p[0]找到的也是第一个元素,那么与上面的一样,故会使得计算错误。
	printf("%d\n", strlen(&p));//随机值
	//&p拿到的是整个数组的地址,那么地址是内存随机分配的,所以\0的位置我们是不能确定的,故是随机值。
	printf("%d\n", strlen(&p + 1));//随机值
	//&p + 1跳过的是整个数组,拿到的是数组后面的地址,即是地址,那么它的情况也和上面的一样\0的位置也是不能自己确定的,故是随机值。
	printf("%d\n", strlen(&p[0] + 1));//5
	//&p[0]找到的是第一个元素的地址,在加1找到的就是第二个元素的地址,那么从第二个位置往后找\0,计算出来的就是5。
	return 0;
}

?

二维数组:?

8.int a[3][4] = {0}对于sizeof的分析。

代码展示:

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
int main()
{
	int a[3][4] = { 0 };
	printf("%d\n", sizeof(a));//48
	printf("%d\n", sizeof(a[0][0]));//4
	printf("%d\n", sizeof(a[0]));//16
	printf("%d\n", sizeof(a[0] + 1));//4
	printf("%d\n", sizeof(*(a[0] + 1)));//4
	printf("%d\n", sizeof(a + 1));//4/8
	printf("%d\n", sizeof(*(a + 1)));//16
	printf("%d\n", sizeof(&a[0] + 1));//4/8
	printf("%d\n", sizeof(*(&a[0] + 1)));//16
	printf("%d\n", sizeof(*a));//16
	printf("%d\n", sizeof(a[3]));//16
	return 0;
}


运行结果:

分析:

具体分析如下代码中的注释所示:

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
int main()
{
	int a[3][4] = { 0 };
	printf("%d\n", sizeof(a));//48
	//a单独放在了sizeof中,故计算的是整个数组的大小,类型是int型故计算的大小为12 * 4 = 48。
	printf("%d\n", sizeof(a[0][0]));//4
	//a[0][0]取出的是数组的第一个元素,故大小为4。
	printf("%d\n", sizeof(a[0]));//16
	//a[0]取出的是二维数组第一行的地址,故计算的是第一行整个数组的大小16。
	printf("%d\n", sizeof(a[0] + 1));//4/8
	//a[0]取出的是二维数组第一行的地址,a[0] + 1相当于a[0][1],则a[0] + 1找到的是第一行的第二个元素的地址,即是地址那就是4/8。
	printf("%d\n", sizeof(*(a[0] + 1)));//4
	//a[0] + 1找到的是第二行的地址,*(a[0] + 1)找到的是第一行的第二个元素,则大小为4。
	printf("%d\n", sizeof(a + 1));//4/8
	//a是二维数组首元素的地址值,再加1找到的是第二行的地址,即是地址大小就为4/8。
	printf("%d\n", sizeof(*(a + 1)));//16
	//a + 1是第二行的地址,*(a + 1)找到的就是第二行整个元素,则大小就为16。
	printf("%d\n", sizeof(&a[0] + 1));//4/8
	//&a[0]拿到的是第一行的地址,再加1,找到的就是第二行的地址,即是地址那么大小就为4/8。
	printf("%d\n", sizeof(*(&a[0] + 1)));//16
	//&a[0] + 1找到的是第二行的地址,那么*(&a[0] + 1)拿到的就是第二行的元素,则大小就为4 * 4 = 16。
	printf("%d\n", sizeof(*a));//16
	//a是第一行的地址,相当于a[0],则*a拿到的就是第一行的元素,4 * 4 = 16。
	printf("%d\n", sizeof(a[3]));//16
	//a[3]很多人可能以为a[3]会越界访问,但实际上是不会越界访问的,我们之前学过在sizeof中只看类型,不会计算里面的值,
	//更不会去访问,所以我们就是只看a[3]的类型属性,它的类型与a[0]的一样都是int [4],故计算出来的大小就为16。
	return 0;
}

?

结束语:

好啦这期小编就与大家分享到这里啦,希望通过小编这次的总结大家可以对sizeof和strlen有不一样的认识,希望对刚刚入门的小白有所帮助,我是陪你们一起成长的编程小高,希望的的分享可以对大家有所帮助,想要学习的同学记得关注小编和小编一起学习吧!如果文章中有任何错误也欢迎各位大佬及时为小编指点迷津(在此小编先谢过各位大佬啦!)

  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2022-09-13 10:54:41  更:2022-09-13 10:56:32 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/19 12:10:33-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码