分类: C/C++
2008-11-29 00:23:25
请写出下面一个简单程序的输出结果。
#include
#include
int main()
{
char
array1[7] = {'a', 'b',
'c'};
char
array2[3] = {'e', 'f',
'g'};
printf( "strlen(array1)=%d\n",
strlen( array1 ) );
printf( "strlen(array2)=%d\n",
strlen( array2 ) );
return
0;
}
关键问题就是弄懂字符串数组的初始化和strlen函数的计算过程。
首先,strlen函数在计算字符数组长度时,它会遍历待检测字符数组的所有字符,直到遇到一个null字符,才会停止,而字符串数组在初始化过程中会在结尾加上一个'\0'字符,即null字符,当然前提是字符串数组有多余的位置留给null字符。
让我们再看array1和array2,array1定义的长度为7,初始化时只赋了3个值,故有空余的空间留给null字符,故初始化时会在字符串末尾添加null终结字符,对于array2 来说,定义的长度为3,赋了3个值,没有空余的空间留给null字符,所有strlen在检查完array2后,继续检查array2所在内存地址后的内存,直到遇到一个null字符才停止,所以几乎不可能会得出3。
局部变量在内存中的存储是以压栈的方式存储的(这是众所周知的,局部变量是存储在栈中),栈地址是由高到低方向增长,即先定义的变量在高地址,后定义的变量在低地址.
array2的首地址接着array1的尾地址,但从VC的编译器的角度来看,操作系统是32位的,内存地址是四字节对齐的。
array2占了3字节的内存空间,给array1分配时本应从array2+3处分配,但array+3不是4的整数倍地址,要对齐内存,就要往后移动一个字节分配了,注意,这个字节的值是随机的。所以array1的开始地址为array2+4,初始化array1[0]~ array1[2]三个值后,在array1[3]~ array1[6]处填入0(数组的初始化为0)。至此可以分析出这两个字符串的内存分布图,从而很容易得出字符串的长度。
内存分布图:
低
| 0013FF74 65 66 67 CC efg. <-- array2
| 0013FF78 61 62 63 00 abc. <-- array1
V 0013FF
高
正确的结果就是3,7。