鱼C论坛

 找回密码
 立即注册
查看: 1966|回复: 16

[已解决]strlen函数

[复制链接]
发表于 2019-3-18 19:17:18 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
我看不懂答案,
#include<stdio.h>
#include<string.h>

int main(void)
{
        static char p[] = { 'a','b','c' }, q[10] = { 'a','b','c' };
        printf("%d   %d\n", strlen(p), strlen(q));        
        return 0;
}
最佳答案
2019-3-19 01:39:48
然而这是实际测试结果

代码:
#include <stdio.h>
#ifdef __cplusplus
#include <iostream>
#endif

int main() {
         static char a[]={'a','b','c'};
         printf("sizeof(a)=%d\n",sizeof(a)); 
         printf("strlen(a)=%d\n",strlen(a));
         static char b[]={'a','b','c','d'};
         printf("sizeof(b)=%d\n",sizeof(b)); 
         printf("strlen(b)=%d\n",strlen(b));
         
#ifdef __cplusplus
         system("pause");
#endif
}

Dev-C++ 5.11下使用C语言的测试结果:
sizeof(a)=3
strlen(a)=7
sizeof(b)=4
strlen(b)=4

VS2017下使用C++的测试结果:
sizeof(a)=3
strlen(a)=3
sizeof(b)=4
strlen(b)=4

可以看到,这结果是与编译器相关的,而且在DevC下,字符串a的结束符是一路搜寻到字符串b的结尾了,并不是所有编译器都会在这种声明方法的字符串后加0;
所以结果应该是B

TIM图片20190318191127.jpg
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2019-3-18 19:49:26 | 显示全部楼层
你只要数第几个是'\0'就对了,
数组p的长度只有3,直到结束都没有出现'\0'因此长度不能确定;
数组q的长度为0,初始化时会默认将没有出现的部分初始化为'\0',因此q[3]=='\0',长度为3;
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2019-3-18 20:55:57 | 显示全部楼层
本帖最后由 ba21 于 2019-3-19 00:02 编辑

这题正确的应该是A啊。怎么会是B?
初始化的时候后面都会补'\0'
而strlen是返回除了'\0'的长度,也就是3


问题再次详解如下:



static char p[] 没固定大小,但是初始化值时已知大小是3.所以固定后是3;
static char q[10] 固定大小10, 初始化3个值,后面值全部填'\0'


strlen
主要针对于字符来而言返回除'\0'的长度

sizeof
1.对于数组来说,返回的是数组的长度(以字节为单位
2.假如这是一个字符串的话那么'\0'也算是这个字符串的一个元素。


所以这里
strlen(p) // 实践证明 编译器在 p 后面加了 '\0', 所以得到3
strlen(q) // 由于 初始化3个值,后面值全部填'\0', 所以得到也是3

而 sizeof 返回的是数组的长度
sizeof(p) // 数组长度已固定3,所以是3 (注意,这是数组,不是字符串)
sizeof(q) // 数组长度已固定10, 所以是10 (注意,这是数组,不是字符串)

不信你 static char str1[]="abc"; 然后sizeof(str1) 看看长是不是4。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 1 反对 0

使用道具 举报

 楼主| 发表于 2019-3-18 20:59:49 | 显示全部楼层
ba21 发表于 2019-3-18 20:55
这题正确的应该是A啊。怎么会是B?
初始化的时候后面都会补'\0'
而strlen是返回除了'\0'的长度,也就是3

我也觉得应该是A但是由于不够自信,所以没敢怀疑答案
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2019-3-18 21:03:59 | 显示全部楼层
Croper 发表于 2019-3-18 19:49
你只要数第几个是'\0'就对了,
数组p的长度只有3,直到结束都没有出现'\0'因此长度不能确定;
数组q的长 ...

但是我代码运行的结果是3 3,所以是巧合吗还是因为啥
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2019-3-18 21:17:26 | 显示全部楼层
正确答案是A,实践是检验真理的最快办法。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2019-3-18 21:42:41 | 显示全部楼层
ba21 发表于 2019-3-18 20:55
这题正确的应该是A啊。怎么会是B?
初始化的时候后面都会补'\0'
而strlen是返回除了'\0'的长度,也就是3

怎么会是a,后面补零只有在使用char a[]="abc";这种初始化才会补0,这个时候sizeof(a)==4;
而这种初始化方法,数组长度只有3,这个时候sizeof(a)== 3;
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2019-3-18 21:45:19 | 显示全部楼层
本帖最后由 Croper 于 2019-3-18 22:30 编辑
Croper 发表于 2019-3-18 21:42
怎么会是a,后面补零只有在使用char a[]="abc";这种初始化才会补0,这个时候sizeof(a)==4;
而这种初始化 ...


在某些情况下,编译器在debug模式下会首先把所有可能用到的内存全部初始化为0,这个时候strlen(a)得到的答案是3,是因为后面的内存为零,但是改成release模式后,结果就会不一样

//这一条好像我记忆有偏差,暂时不要参考,我找到确切出处再说
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2019-3-18 22:05:07 | 显示全部楼层
另外还有一个问题是内存对齐机制,
https://blog.csdn.net/weixin_39918693/article/details/80709939
简单地说,就是a本身占用3个字节的空间,当程序为了方便访问,会给他分配4个字节的空间。
所以在本例中,sizeof(a)本身等于3,但程序会给他分配4个字节的空间,第四个字节为零的话,结果为3,
但如果a[]={'a','b','c','d'}那么结果又会不一样

但内存对齐不应该成为这道题的出题目的,另外,内存对齐本身也是设备相关的,因此不应予以考虑
我仍然坚持答案是B
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2019-3-19 00:00:59 | 显示全部楼层
本帖最后由 ba21 于 2019-3-19 00:02 编辑
Croper 发表于 2019-3-18 21:42
怎么会是a,后面补零只有在使用char a[]="abc";这种初始化才会补0,这个时候sizeof(a)==4;
而这种初始化 ...


听你这么一说,答得确实不到位。

static char p[] 没固定大小,但是初始化值时已知大小是3.所以固定后是3;
static char q[10] 固定大小10, 初始化3个值,后面值全部填'\0'


strlen
主要针对于字符来而言返回除'\0'的长度

sizeof
1.对于数组来说,返回的是数组的长度(以字节为单位
2.假如这是一个字符串的话那么'\0'也算是这个字符串的一个元素。


所以这里
strlen(p) // 实践证明 编译器在 p 后面加了 '\0', 所以得到3
strlen(q) // 由于 初始化3个值,后面值全部填'\0', 所以得到也是3

而 sizeof 返回的是数组的长度
sizeof(p) // 数组长度已固定3,所以是3 (注意,这是数组,不是字符串)
sizeof(q) // 数组长度已固定10, 所以是10 (注意,这是数组,不是字符串)

不信你 static char str1[]="abc"; 然后sizeof(str1) 看看长是不是4。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2019-3-19 01:39:48 | 显示全部楼层    本楼为最佳答案   
然而这是实际测试结果

代码:
#include <stdio.h>
#ifdef __cplusplus
#include <iostream>
#endif

int main() {
         static char a[]={'a','b','c'};
         printf("sizeof(a)=%d\n",sizeof(a)); 
         printf("strlen(a)=%d\n",strlen(a));
         static char b[]={'a','b','c','d'};
         printf("sizeof(b)=%d\n",sizeof(b)); 
         printf("strlen(b)=%d\n",strlen(b));
         
#ifdef __cplusplus
         system("pause");
#endif
}

Dev-C++ 5.11下使用C语言的测试结果:
sizeof(a)=3
strlen(a)=7
sizeof(b)=4
strlen(b)=4

VS2017下使用C++的测试结果:
sizeof(a)=3
strlen(a)=3
sizeof(b)=4
strlen(b)=4

可以看到,这结果是与编译器相关的,而且在DevC下,字符串a的结束符是一路搜寻到字符串b的结尾了,并不是所有编译器都会在这种声明方法的字符串后加0;
所以结果应该是B

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2019-3-19 01:45:36 | 显示全部楼层

                               
登录/注册后可看大图


                               
登录/注册后可看大图

这是测试结果图片,不过最近上传的图片总是会挂掉,不过我相册里面应该有备份
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2019-3-19 01:56:52 | 显示全部楼层
甚至这是原题
#include <stdio.h>

int main() {
         static char p[]={'a','b','c'};
        static char q[10]={'a','b','c'};
         printf("%d%d\n",strlen(p),strlen(q));
         return 0;
}
在这里,DevC下运行是3 3;
但添加一段理论上没有任何影响的测试代码,只有几个printf的测试代码
int main() {
         static char p[]={'a','b','c'};
        static char q[10]={'a','b','c'};
        
        //=============================== 
        int i;
        for (i=0;i<16;++i){
                printf("%d ",p[i]%256);
        }
        printf("\n");
        //====================================
        
         printf("%d%d\n",strlen(p),strlen(q));
         return 0;
}

结果就变成了
97 98 99 97 98 99 0 0 0 0 0 0 0 0 0 0 0
6 3
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2019-3-19 02:11:21 | 显示全部楼层
所以这个数组后面的零是不稳定的,它只是全局变量域里没有初始化的值而已,而不是编译器在数组后面所添加的'\0';
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2019-3-19 20:35:52 | 显示全部楼层
ba21 发表于 2019-3-19 00:00
听你这么一说,答得确实不到位。

static char p[] 没固定大小,但是初始化值时已知大小是3.所以固定 ...

谢谢指点
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2019-3-19 20:36:34 | 显示全部楼层
Croper 发表于 2019-3-19 02:11
所以这个数组后面的零是不稳定的,它只是全局变量域里没有初始化的值而已,而不是编译器在数组后面所添加的 ...

谢谢指点
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2019-3-19 22:29:48 | 显示全部楼层
Croper 发表于 2019-3-19 02:11
所以这个数组后面的零是不稳定的,它只是全局变量域里没有初始化的值而已,而不是编译器在数组后面所添加的 ...

受教。
如果考虑全局的话,这题还是B正确。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-10-3 12:31

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表