这段程序应该每运行一次的结果都不完全一致。具体原因是这样:
这个问题想说明白不太容易,我以下瞎说,你就瞎看吧。
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 结束符。这也就是你后面两个问题产生的原因。
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…