910201513 发表于 2019-3-18 19:17:18

strlen函数

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

int main(void)
{
        static char p[] = { 'a','b','c' }, q = { 'a','b','c' };
        printf("%d   %d\n", strlen(p), strlen(q));       
        return 0;
}

Croper 发表于 2019-3-18 19:49:26

你只要数第几个是'\0'就对了,
数组p的长度只有3,直到结束都没有出现'\0'因此长度不能确定;
数组q的长度为0,初始化时会默认将没有出现的部分初始化为'\0',因此q=='\0',长度为3;

ba21 发表于 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, 初始化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。

910201513 发表于 2019-3-18 20:59:49

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

我也觉得应该是A{:10_277:}但是由于不够自信,所以没敢怀疑答案{:10_264:}{:10_264:}{:10_264:}

910201513 发表于 2019-3-18 21:03:59

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

但是我代码运行的结果是3 3,所以是巧合吗还是因为啥

明如月 发表于 2019-3-18 21:17:26

正确答案是A,实践是检验真理的最快办法。

Croper 发表于 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;

Croper 发表于 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模式后,结果就会不一样

//这一条好像我记忆有偏差,暂时不要参考,我找到确切出处再说

Croper 发表于 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

ba21 发表于 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, 初始化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。

Croper 发表于 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

Croper 发表于 2019-3-19 01:45:36

https://xxx.ilovefishc.com/album/201903/19/014332xn4s193gtgkn4bb4.jpg
https://xxx.ilovefishc.com/album/201903/19/014331sda1yzj7h019edjj.jpg
这是测试结果图片,不过最近上传的图片总是会挂掉,不过我相册里面应该有备份

Croper 发表于 2019-3-19 01:56:52

甚至这是原题#include <stdio.h>

int main() {
        static char p[]={'a','b','c'};
        static char q={'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={'a','b','c'};
       
        //===============================
        int i;
        for (i=0;i<16;++i){
                printf("%d ",p%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

Croper 发表于 2019-3-19 02:11:21

所以这个数组后面的零是不稳定的,它只是全局变量域里没有初始化的值而已,而不是编译器在数组后面所添加的'\0';

910201513 发表于 2019-3-19 20:35:52

ba21 发表于 2019-3-19 00:00
听你这么一说,答得确实不到位。

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

谢谢指点

910201513 发表于 2019-3-19 20:36:34

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

谢谢指点

ba21 发表于 2019-3-19 22:29:48

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

受教。
如果考虑全局的话,这题还是B正确。
页: [1]
查看完整版本: strlen函数