想破脑袋也不知道这句为什么会被爆出'char类型作为下标'的警告
展开全部
C语言的局部变量默认为自动变量。
而自动变量默认是在“栈”上。之所以出现"123456789,56789"这样的输出,是
因为在你的系统下“栈”是由高地址向低地址增长的。所以d的地址比s的地址要低,在自负串拷贝超出d范围时,就会覆盖位于高地址的s. 因为d还有一个字符串标志"\0", 所以d的地址比s地址低4个字节。所以超出4个字节的部分(56789)会覆盖d.
把代码改成这样,看得会更清楚:
int main(void)
{
char s[] = "123456789";
char d[] = "123";
printf("%p %s\n", s, s);
printf("%p %s\n", d, d);
strcpy(d, s);
printf("%s,%s\n",d,s);
return 0;
}
0022FF40 123456789
0022FF3C 123
123456789,56789
这里地址在不同的系统下可能不同,但一般32位win下相对地址是一样的,地址差是4。以这里的输出为例子,
可见栈的结构是:
...
0022FF48 9
0022FF47 8
0022FF46 7
0022FF45 6
0022FF44 5
0022FF43 4
0022FF42 3
0022FF41 2
0022FF40 1 /* s开始 */
0022FF3F \0
0022FF3E 3
0022FF3D 2
0022FF3C 1 /* d开始 */
拷贝发生时,从0022FF3C开始覆盖123456789, 可见1234覆盖了0022FF3C- 0022FF3F四个字节, 这四个字节属于d的范围. 56789\0覆盖了 0022FF40 - 0022FF45 六个字节,这六个字节属于s的范围。 这样内存变为:
0022FF48 9
0022FF47 8
0022FF46 7
0022FF45 \0
0022FF44 9
0022FF43 8
0022FF42 7
0022FF41 6
0022FF40 5 /* s开始 */
0022FF3F 4
0022FF3E 3
0022FF3D 2
0022FF3C 1 /* d开始 */
可见, d的'\0'被覆盖,从0022FF3C开始,第一个字符串结束标志位于0022FF45, printf("%s\n", d)会输出完整的字符串"123456789"。而printf("%s\n", s);则会从0022FF40开始输出直到在0022FF45遇到'\0', 于是会输出s被覆盖的六个字节"56789".这就解释了为何printf("%s, %s\n", d, s)会输出123456789,56789,
而自动变量默认是在“栈”上。之所以出现"123456789,56789"这样的输出,是
因为在你的系统下“栈”是由高地址向低地址增长的。所以d的地址比s的地址要低,在自负串拷贝超出d范围时,就会覆盖位于高地址的s. 因为d还有一个字符串标志"\0", 所以d的地址比s地址低4个字节。所以超出4个字节的部分(56789)会覆盖d.
把代码改成这样,看得会更清楚:
int main(void)
{
char s[] = "123456789";
char d[] = "123";
printf("%p %s\n", s, s);
printf("%p %s\n", d, d);
strcpy(d, s);
printf("%s,%s\n",d,s);
return 0;
}
0022FF40 123456789
0022FF3C 123
123456789,56789
这里地址在不同的系统下可能不同,但一般32位win下相对地址是一样的,地址差是4。以这里的输出为例子,
可见栈的结构是:
...
0022FF48 9
0022FF47 8
0022FF46 7
0022FF45 6
0022FF44 5
0022FF43 4
0022FF42 3
0022FF41 2
0022FF40 1 /* s开始 */
0022FF3F \0
0022FF3E 3
0022FF3D 2
0022FF3C 1 /* d开始 */
拷贝发生时,从0022FF3C开始覆盖123456789, 可见1234覆盖了0022FF3C- 0022FF3F四个字节, 这四个字节属于d的范围. 56789\0覆盖了 0022FF40 - 0022FF45 六个字节,这六个字节属于s的范围。 这样内存变为:
0022FF48 9
0022FF47 8
0022FF46 7
0022FF45 \0
0022FF44 9
0022FF43 8
0022FF42 7
0022FF41 6
0022FF40 5 /* s开始 */
0022FF3F 4
0022FF3E 3
0022FF3D 2
0022FF3C 1 /* d开始 */
可见, d的'\0'被覆盖,从0022FF3C开始,第一个字符串结束标志位于0022FF45, printf("%s\n", d)会输出完整的字符串"123456789"。而printf("%s\n", s);则会从0022FF40开始输出直到在0022FF45遇到'\0', 于是会输出s被覆盖的六个字节"56789".这就解释了为何printf("%s, %s\n", d, s)会输出123456789,56789,
推荐律师服务:
若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询