Welcome toVigges Developer Community-Open, Learning,Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
199 views
in Technique[技术] by (71.8m points)

C语言数组赋值。

image
为什么 r 数组一开始的长度为2?
最后长度又为什么变成了18?
而且值为啥是987654321123456789?


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

这段程序应该每运行一次的结果都不完全一致。具体原因是这样:

这个问题想说明白不太容易,我以下瞎说,你就瞎看吧。

char s[] = "123456789", r[9];
相当于定义了s数组,具体存到内存中占用了10个连续存储单元,其实1-9分别占用一个字节,最后系统还默认添加了00000000到最后一个字节中,为了标识字符串结束。

在进行strlen(s)时,该函数由s的首地址开始查找,查找到00000000的结束符结束,返回长度为9是正确的。

31 32 33 34 35 36 37 38 39 00 内存地址的实际值
1  2  3  4  5  6  7  8  9   转换为ascii后的值 
s                            内存指针

r[9]就比较随机了,该语句代码划分一段长度为9的内存空间,并将此空间的首地址给r。但由于该内存中本来就存在以下值(假设):00001100 00101010 00000000 ....,所以在进行strlen(r)时,同样是由首地址开始找,找到第三个00000000结束符后结束,返回长度为2.

?? ?? 00 ?? ?? ?? ?? ?? ?? 内存地址的实际值
?  ?   ?  ?  ?  ?  ?  ?  转换为ascii后的值 
r                            内存指针

打??代表不知道其具体值,但前两个??的值必然不是00。

由于内存中的值是不固定的,所以这个2必然也是随机的,这次可能为2,下次还可能为3,4,5,这个依赖于当前内存中数据的实际情况。


长度变成18原因,也是根据当前内存情况决定的。由于在运行程序的时候恰恰这样的分配的内存:

?? ?? 00 ?? ?? ?? ?? ?? ?? 31 32 33 34 35 36 37 38 39 00 内存地址的实际值
?  ?   ?  ?  ?  ?  ?  ?  1  2  3  4  5  6  7  8  9  转换为ascii后的值 
r                           s                            内存指针

其中为字符串结束符,在内存中的值为00000000,转成16进制简写为00

然后当执行你上面的程序后,最后变成了这样:

39 38 37 36 35 34 33 32 31 31 32 33 34 35 36 37 38 39 00 内存地址的实际值
9  8  7  6  5  4  3  3  2  1  2  3  4  5  6  7  8  9  转换为ascii后的值
r                           s                            内存指针

此时当我们在执行strlen(r)以及打印其值时,仍然是由r的起始位置开始,一直找到 00 结束符。这也就是你后面两个问题产生的原因。


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to Vigges Developer Community for programmer and developer-Open, Learning and Share
...