本文最后更新于 532 天前,其中的信息可能已经有所发展或是发生改变。
最近在跟 C 语言基础课程的时候,老师提到了一个字符串的错误定义方法:
char s[] = {'a', 'b', 'c'};
这种方式由于不会自动在末尾补上终止符 \0,这会导致在输出的时候,程序因为不知道字符串什么时候结束,而继续输出变量原本内存空间后面东西。
但我在自己实验的时候,写下如下代码:
#include <stdio.h>
int main() {
char s1[] = {'1', '1', '4'};
char s2[] = "514";
printf("%s\n", s1);
printf("%s\n", s2);
return 0;
}</stdio.h>
最终输出:
/Users/madray/Documents/JetBrains/CLion/CTest/cmake-build-debug/CTest
114
514
Process finished with exit code 0
我原本以为,s1 没有终止符,输出会继续输出 s2,但实际上却没有。
仔细回想视频中的写法,视频中似乎没有终止符的 char 数组是后定义的,于是我将 s1 和 s2 的定义顺序交换了一下:
#include <stdio.h>
int main() {
char s2[] = "514";
char s1[] = {'1', '1', '4'};
printf("%s\n", s1);
printf("%s\n", s2);
return 0;
}</stdio.h>
这下输出就符合我预期了:
/Users/madray/Documents/JetBrains/CLion/CTest/cmake-build-debug/CTest
114514
514
Process finished with exit code 0
也就是说,后定义的变量在内存里反而放在先定义的变量的前面。
请教大佬之后,得知临时变量是存放在“栈”里的,而栈在内存里还真就是,后进的放在前面,达到后进先出的效果。
因此,上述现象就十分合理了,s1 后入栈时,在内存里就会放到 s2 的前面,所以输出 s1 的时候才能实现把 s2 一起输出。