目录
前言:?
知识点回顾:
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有不一样的认识,希望对刚刚入门的小白有所帮助,我是陪你们一起成长的编程小高,希望的的分享可以对大家有所帮助,想要学习的同学记得关注小编和小编一起学习吧!如果文章中有任何错误也欢迎各位大佬及时为小编指点迷津(在此小编先谢过各位大佬啦!)
|