我代码:
#include<stdio.h>
#include<conio.h>
#include<string.h>
void main()
{
char string[]="stackflow";
strcpy(&string[0],&string[1]);
puts(string);
getch();
}
结果是“潮流”。我不明白。你能解释一下谁?提前谢谢。
答案 0 :(得分:7)
调用strcpy(&string[0],&string[1]);
表示:将从字符串[1]的地址开始的以NULL结尾的字符串复制到字符串[0] 的地址。这意味着您将从偏移量1(tackflow
)开始的字符串复制到偏移量0的地址。或者换句话说:您将字符串向左移动一个字符,覆盖s
。
strcpy
用于复制由一个地址(第二个参数)到另一个地址(第一个参数)的NULL字节(C字符串)终止的字节数组。通常,它用于将字符串从一个内存位置复制到完全不同的内存位置:
char string[] = "stackflow";
char copied_string[10]; // length of "stackflow" + NULL byte
strcpy(copied_string, string);
puts(copied_string);
正如@PascalCuoq正确指出的那样,您的调用是未定义的行为,这意味着可能发生任何。 standard says:
如果在重叠的对象之间进行复制,则行为未定义。
所以你很幸运,你得到了一个理智的#34;完全输出。
答案 1 :(得分:2)
需要注意的一点是:strcpy
的行为在overlapping source and destination提供时未定义(参见C99 7.23.2.3:2)。所以无论输出看起来如何,你所做的事情基本上都不能保证工作,除非你的C实现的文档另有说明。
在字符串中移动数据时使用memmove
。
您在声明字符串时也应该非常小心。您提供的代码是正确的:
char string[] = "foo";
string
是一个字符数组,初始化为包含四个元素:'f','o','o','\ 0'。
但是,非常相似的代码是不正确的:
char * string = "foo";
此代码执行的操作是初始化指向常量字符串文字“foo”的地址的char
指针。正确的版本是:
const char * string = "foo";
如果您尝试修改此类字符串,编译器会正确地抱怨。
答案 2 :(得分:1)
strcpy
是(Dest,Src)。您的源从位置1开始并转到字符串的末尾。它将source指向的字符串复制到destination指向的数组中,包括终止空字符(并在该点停止)。