首页 > 其他分享 >c语言sizeof与strlen的区别详细解析

c语言sizeof与strlen的区别详细解析

时间:2024-11-15 22:46:41浏览次数:3  
标签:arr 地址 数组 printf sizeof 解析 strlen

char *p = "abcdef";

printf("%d\n", sizeof(p));
p是指针变量(地址),地址就是地址,大小就是4/8字节

printf("%d\n", sizeof(p+1));
p+1是b的地址,还是地址 4/8字节

printf("%d\n", sizeof(*p));
*p是‘a’,sizeof(*p)计算的是字符的大小,是1字节

printf("%d\n", sizeof(p[0]));
p[0]==*(p+0)=*p,跟上面一样

printf("%d\n", sizeof(&p));
&p是二级指针,是指针大小是4/8字节

printf("%d\n", sizeof(&p+1));
&p+1是跳过p变量后的地址,4/8字节

printf("%d\n", sizeof(&p[0]+1));
p[0]是‘a’,&p[0]是a的地址,+1后,就是b的地址,是地址就是4/8


printf("%d\n", strlen(p));
6,求字符串的长度

printf("%d\n", strlen(p+1));
p+1就是b的地址,求字符串长度,5

printf("%d\n", strlen(*p));
p本来就是地址,解引用后变成首元素,即‘a’,非法,错误

printf("%d\n", strlen(p[0]));
同上面

printf("%d\n", strlen(&p));
&p拿到的是p这个指针变量的起始地址,也就是说它拿到的并不是“abcdef\0”这个地址,
而是重新创建了一个,从这里开始求字符串长度也是随机值

printf("%d\n", strlen(&p+1));
&p+1跳过p变量的地址,从这里开始求字符串长度也是随机值,原理跟上面差不多

printf("%d\n", strlen(&p[0]+1));
&p[0]+1拿到的是b的地址,从b开始计算,5

首先,在此之前,我们先了解下面的知识:

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

这里说数组名是单独的,什么意思呢,看下面:

int arr[10]={1,2,3,4,5,6,7,8,9,10};
printf("%d",sizeof(arr));   //这样子是数组名是表示单独的
printf("%d",sizeof(arr+1);   //这样子是不单独的


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

int arr[10]={1,2,3,4,5,6,7,8,9,10};
printf("%d",sizeof(&arr));


3.除此之外,所以的数组名都是数组首元素的地址

注意:是地址就是4/8字节,下面慢慢就理解这句话了。

了解了上面的认识后,下面开始我们的正文:

int a[] = {1,2,3,4};  //大小:4*4=16--四个元素*一个int类型为4字节

printf("%d\n",sizeof(a));  //这是不是符合我们上面所说的数组单独放在sizeof里面,so:4*4=16

printf("%d\n",sizeof(a+0)); //a+0 其实是数组第一个元素的地址,是地址就是4/8字节

printf("%d\n",sizeof(*a)); //这里是不是属于第三种情况,所以*a是数组首元素,计算的是数组首元素的大小,单位字节,4

printf("%d\n",sizeof(a+1)); //这里是不是也是第三种,a+1,是第二个元素的地址,是地址大小就是4/8

printf("%d\n",sizeof(a[1])); //这是数组中第二个元素“2”吧,计算的是数组首元素的大小,单位字节,4

printf("%d\n",sizeof(&a));&a是整个元素的地址,但是整个元素的地址也是地址,地址的大小就是4/8字节
//这里可以仔细想一想开始时我说注意的那句话。

printf("%d\n",sizeof(*&a)); //&a是数组的地址,*&a就是拿到了数组,*&a--》a,a就是地址名,
sizeof(*&a)-->sizeof(a),计算的是整个数组的大小,单位是字节16

printf("%d\n",sizeof(&a+1)); //&a是数组的地址,&a+,跳过整个数组,指向数组后面的空间,是一个地址,大小是4/8字节
//开始时我说注意的那句话

printf("%d\n",sizeof(&a[0])); //首元素的地址,计算的是首元素地址的大小,4/8字节

printf("%d\n",sizeof(&a[0]+1)) //&a[0]+1是第二个元素得到地址,地址的大小就是4/8字节

1.sizeof是根据类型来推断它的大小的,即只关注占用内存空间的大小,单位是字节,不关心内存中存放的是什么
2.strlen是根据\0标志点,是求字符串的长度,统计的是\0之前出现的字符个数,一定要找到\0才算结束,所以可能存在越界访问
3.sizeof是操作符,strlen是库函数

//char arr[] = "abcdef";
这个有\0,本质上:abcdef\0,注意这个\0也要算上去sizeof

//printf("%d\n", sizeof(arr));
结果7,数组名单独放在sizeof内部,计算的是数组的总大小,单位是字节

//printf("%d\n", sizeof(arr+0));
arr+0是数组首元素的地址,大小是4/8

//printf("%d\n", sizeof(*arr));
*arr是首个元素,大小为1字节

//printf("%d\n", sizeof(arr[1]));
arr[1]是第二个元素,大小为1字节

//printf("%d\n", sizeof(&arr));
&arr是数组的地址,数组的地址也是地址,是4/8字节

//printf("%d\n", sizeof(&arr+1));
跳过一个数组的地址,同上

//printf("%d\n", sizeof(&arr[0]+1));
&arr[0]+1是第二个元素的地址,是4/4字节

//printf("%d\n", strlen(arr));
6,arr是数组首位元素的地址,strlen从首元素的地址开始统计\0之前出现的字符串个数

//printf("%d\n", strlen(arr+0));
6同上面
//printf("%d\n", strlen(*arr));
*arr是'a'是97,传给strlen是一个非法地址,造成非法访问

//printf("%d\n", strlen(arr[1]));
非法,同上面

//printf("%d\n", strlen(&arr));
结果6

//printf("%d\n", strlen(&arr+1));
随机值,跳过整个数组,也跳过了\0的地方,于是在后面找不到\0了,结果就成了随机值

//printf("%d\n", strlen(&arr[0]+1));
&arr[0]+1,是b的地址,从第二个元素开始统计,结果是5
char arr[] = {'a','b','c','d','e','f'};  //6个元素
//首先我们得分清的是,这种是没有\0的

//printf("%d\n", sizeof(arr)); 
这是数组单独情况,访问是整个数组,对吧。因为char,每个字节为1 所以结果为:1*6=6  

//printf("%d\n", sizeof(arr+0)); 
这是arr+0是数组首元素的地址,地址就是地址,so:4/8字节

//printf("%d\n", sizeof(*arr));
 这是第三种情况,arr是首元素的地址,解引用*arr就是数组的首元素, 结果为1

//printf("%d\n", sizeof(arr[1]));
arr[1]是第二个元素,大小是1字节

//printf("%d\n", sizeof(&arr));
&arr的是数组的地址,数组的地址也是地址,是地址大小就是4/8字节

//printf("%d\n", sizeof(&arr+1));
&arr+1是跳过整个,指向数组后边空间的地址,4/8

//printf("%d\n", sizeof(&arr[0]+1));
&arr[0]+1是数组第二个元素的地址,是地址4/8字节

//printf("%d\n", strlen(arr));  
随机值   因为strlen得找/0,又这个没有/0,不知道在哪停止

//printf("%d\n", strlen(arr+0));
随机值,+0还是从a的地址,但是他求的不是sizeof,同上

//printf("%d\n", strlen(*arr));
 第三种情况,首位元素,解引用后,变成首位元素,是strlen(a)->strlen('98'),非法访问-err

//printf("%d\n", strlen(arr[1])); 
跟上面类似
//printf("%d\n", strlen(&arr));
 &arr虽然是数组的地址,但是也是从数组起始位置开始的,计算的还是随机值

//printf("%d\n", strlen(&arr+1));
 &arr是数组的地址,&arr+1是跳过整个数组的地址,求字符串长度 也是随机值

//printf("%d\n", strlen(&arr[0]+1));
&arr[0]+1是数组第二个元素的地址,是地址4/8字节,从 b开始数


//int a[3][4] = {0};


//printf("%d\n",sizeof(a));
结果 大小:48 =3*4*4

//printf("%d\n",sizeof(a[0][0]));
第一行第一个元素结果为4

//printf("%d\n",sizeof(a[0]));
第一行,有4个元素:结果4*4=16
//printf("%d\n",sizeof(a[0]+1));
a[0]作为第一行的数组名,数组名没有单独放在sizeof内部,不属于第一种情况,
也没有取地址,也不属于第二种,
表示的是数组首元素的地址,那就是a[0][0]的地址,
a[0]+1就是第一行第二个元素的地址,是地址就是4/8字节

//printf("%d\n",sizeof(*(a[0]+1)));
第一行第二个元素,计算的是元素的大小-4字节

//printf("%d\n",sizeof(a+1));
a是二维数组的数组名,数组名表示首元素的地址,,a+1就是第二行的地址,就是地址4/8字节

//printf("%d\n",sizeof(*(a+1)));
结果16

//printf("%d\n",sizeof(&a[0]+1));
&a[0]是第一行的地址,&a[0]+1是第二行的地址,地址的大小就是4/8

//printf("%d\n",sizeof(*(&a[0]+1)));
结果16 

//printf("%d\n",sizeof(*a));
a表示首元素的地址,就是第一行的地址,,*a就是第一行,计算的是第一行的大小,结果16
//printf("%d\n",sizeof(a[3]));
如果a存在第四行,a[3]就是第四行的数组名,数组名单独放在sizeof内部,计算的是第四行的大小
不会造成非法访问的

最后的最后,

又来到我们每次激励鸡汤:

分享高中到至今很喜欢的一句:

我与我,周旋久,宁做我。

希望我们都能够坚持下去自己为了规划的路线,不被周围人的情绪影响了自己的行动。宁做我,活出属于我们每一个人的篇章。

标签:arr,地址,数组,printf,sizeof,解析,strlen
From: https://blog.csdn.net/go_bai/article/details/143749837

相关文章