今天遇到了一个奇怪的问题,暂时没有解决掉,先记录下来。如果有高手看到,可否告知,感谢~
首先看代码:
- #include <iostream>
- #include <stdio.h>
- #include <string.h>
-
- int main(void)
- {
- char s[] = "123456789";
- char d[] = "123";
- strcpy(d,s);
- printf("%s ,\n %s",d,s);
- return 0;
- }
- #include <iostream>
- #include <stdio.h>
- #include <string.h>
- int main(void)
- {
- char s[] = "123456789";
- char d[] = "123";
- strcpy(d,s);
- printf("%s ,\n %s",d,s);
- return 0;
- }
看一下打印的结果:
这里可以看到 s的地址是在 高地址,d的地址是在低地址上。而且正好相差4个字节,符合下面我的推论。
首先 strcpy中 源字符串的参数 是c
onst char * 类型的,但是这里 发生了变化。
原因个人认为是这样的:(水平有限,有错误请指出,感谢~~)
函数在运行的时候:编译器会自动分配一个 栈区,用来存放函数中用到的参数值以及 局部变量的值。操作方式类似数据结构中的栈。而栈的 内存空间是从高地址向低地址扩展的。
这里 会首先给 s数组 分配 10个字节的内存空间(包括结束符) ,然后会给 d数组 分配4个字节的 内存空间,不过 这 两个 数组的内存空间是紧挨着的 。栈的 内存空间是从高地址向低地址扩展的,那么 :
这两个参数在栈中的排序 是这样的
- 低地址 <<<----------------高地址
- 1 2 3 \0 1 2 3 4 5 6 7 8 9 \0
- | |
- d数组 s数组
我们打印下d和s的验证一下:
可以用下面的函数:
#include <stdio.h>
#include <string.h>
int main(void)
{
char s[] = "123456789";
char d[] = "123";
//strcpy(d,s);
//printf("%s ,\n %s\n",d,s);
int i = 0;
for(i = 0;i < 4;i ++)
{
printf("%x ",&d[i]);
}
for(i = 0;i < 10;i ++)
{
printf("%x ",&s[i]);
}
printf("\n");
printf("%s ,\n %s\n",d,s);
return 0;
}
这里 先打 数组d 的 然后接着 打 s的 ,可以看到 这两个数组的内存地址 是如何分布的。看结果
打印结果:
可以看到 从bff738fe 开始一直增长。基本符合我的想法。然后继续看调用strcpy函数之后的内存变化。
- 低地址 ----------------->>>高地址
- 1 2 3 4 5 6 7 8 9 \0 6 7 8 9 \0
- | |
- d数组 s数组
所以打印d是123456789(低地址到高地址)
打印s是56789 (遇见\0打印结束)
所以我们在使用 strcpy的时候一定要注意 :目标字符串 留足够的空间来复制
这个时候个人认为 基本理解了 函数的 变量是如何 存储的, 可是下面的代码 让我又迷茫了。。。。看代码
代码:
#include <stdio.h>
#include <string.h>
int main(void)
{
char s1[]= {'T','a','o','T','a','o','s' ,'b'};
//这是字符串赋初值的方法
char s2[]= "taotaosb";
//char s1[]= "ljsgjlsgjslgjslgj";
//用printf的%s打印内容
printf("s1=%s\n", s1); //不能正确显示
printf("s2=%s\n", s2); //可以正确显示
printf("Address s1 = %x\n",s1);
printf("Address s2 = %x\n",s2);
return 0;
}
看打印结果:
这里 s1的 地址 竟然 跑到 低地址去了,,,s2的 反而在后面 。。这样打印s1的时候会一直走到s2 字符数组的最后一个 '\0' 元素,出现图中的 结果。
同样是 字符数组,为什么会出现这样的问题。求大神解释。跪谢~