考虑 strcpy
的这个实现:
void my_strcpy(char target[], char source[])
{
target = source;
}
int main(void)
{
char target[20];
char source[] = "Source String";
my_strcpy(target, source);
printf("Target: %s", target);
return 0;
}
这行不通,这让我质疑我对 C 中字符串和数组的理解。
这是我的推理:target
和 source
实际上只是指向数组第一个元素的指针,即。 target == &target[0]
和 source == &source[0]
.当我设置 target = source
,我指着指针target
在与指针 source
相同的内存地址被指出。
现在当我printf
target
, 它也应该打印 "Source String"
.但事实并非如此。
谁能解释一下为什么?
最佳答案
void my_strcpy(char target[], char source[])
{
target = source;
}
正如您所写,您在这里所做的是将指针传递给函数。但是指针本身是按值传递的,因此函数具有这些指针的本地副本。函数退出后,函数内的 target
就会停止存在。
要实际修改函数中的指针,您必须传递一个指向此指针的指针,例如像这样:
void my_strcpy(char *target[], char source[])
{
*target = source;
}
请注意,这仍然不适用于您的程序,因为在 main()
中您声明了一个数组。已声明数组的地址不能更改。这是因为数组不与指针相同(您经常可以在写得不好的 C 教程中读到这一点),只是在将数组传递给函数时隐式转换为指向其第一个元素的指针.因此,在 main()
中写入 char *target
,这会 起作用,调用函数如 my_strcpy(&target, source) ;
。
另请注意,这绝不是副本,因此函数的命名在语义上是错误的。一个真正的复制函数看起来像这样:
void my_strcpy(char *target, const char *source)
{
while (*target++ = *source++);
}
复制单个字符直到遇到 \0
字符(然后表达式将计算为 0
并且 while 循环将停止)。这个 super 简单的实现留下了为 target
提供足够存储空间并确保 source
实际上是 0-terminated 给调用者的负担,但是这确实或多或少是标准 C 库的 strcpy()
所做的。
编辑:我只是稍微更改了您的函数签名——第一个更改是个人喜好问题,将 identifier[]
替换为 *identifier
。我喜欢这样做,因为无论如何这都是内部发生的事情,所以它使函数实际采用的内容更加清晰。第二个是在适当的地方添加一个 const
:你的函数永远不会改变 source
指向的内容,所以你应该明确这一点——这样编译器可以捕获更多错误。
关于c - 为什么仅分配指针的字符串复制函数不起作用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32547413/