为什么字符串复制功能只是指定指针不起作用?

Use*_*159 1 c pointers strcpy

考虑以下实现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;
}
Run Code Online (Sandbox Code Playgroud)

这不起作用,它让我质疑我对C中的字符串和数组的理解.

这是我的推理:target并且source实际上只是指向数组的第一个元素的指针,即.target == &target[0]source == &source[0].当我设置时target = source,我将指针指向指针所指向target的相同内存地址source.

现在当我printf target,它也应该打印"Source String".但事实并非如此.

有人可以解释原因吗?

小智 8

void my_strcpy(char target[], char source[])
{
   target = source;
}
Run Code Online (Sandbox Code Playgroud)

你在这里做的是,正如你所写,将指针传递给函数.但是指针本身是按值传递,所以函数有它们是这些指针的本地副本.在target内部功能将停止现有尽快上课函数退出.

要实际修改函数中的指针,您必须将指针传递给此指针,例如:

void my_strcpy(char *target[], char source[])
{
   *target = source;
}
Run Code Online (Sandbox Code Playgroud)

请注意,这仍然不适用于您的程序,因为在main()您声明一个数组.无法更改声明的数组的地址.这是因为阵列是一样的指针(你可以经常读取写得不好Ç教程),但是当将它传递给函数只是隐式转换为指针到它的第一个元素.所以,写char *target在你的main(),这工作,调用函数就像my_strcpy(&target, source);.

另请注意,这绝不是副本,因此函数的命名在语义上是错误的.真正的复制功能如下所示:

void my_strcpy(char *target, const char *source)
{
   while (*target++ = *source++);
}
Run Code Online (Sandbox Code Playgroud)

复制单个字符直到命中一个\0字符(然后表达式将评估为0,而while循环将停止).这种超级简单的实现给负载提供了足够的存储空间,target并确保source实际上是0终止给调用者,但它实际上或多或少是标准C库的strcpy()作用.

编辑:我只是改变了你的函数签名位-第一个变化是一个品味的问题,更换identifier[]*identifier.我喜欢这样做,因为无论如何这都是内部发生的事情,所以它使得函数实际需要的更清楚.第二个是const在适当的位置添加一个:您的函数永远不会更改指向的内容source,因此您应该明确这一点 - 这样编译器可以为您捕获更多错误.


Spi*_*rix 5

你需要记住两件事:

现在,

my_strcpy(target, source);
Run Code Online (Sandbox Code Playgroud)

是相同的

my_strcpy(&target[0], &source[0]);
Run Code Online (Sandbox Code Playgroud)

它传递两个数组的第一个元素的地址

void my_strcpy(char target[], char source[])
Run Code Online (Sandbox Code Playgroud)

是相同的

void my_strcpy(char* target, char* source)
Run Code Online (Sandbox Code Playgroud)

其中target点到所述阵列的所述第一元素的地址targetmainsource点到所述阵列的所述第一元素的地址sourcemain.

所以,

target = source;
Run Code Online (Sandbox Code Playgroud)

只需更改target指向的位置即可.现在,这两个targetsource指向同一存储器位置,即,阵列的地址sourcemain.这对mainC中的任何一个数组没有任何影响,因为C使用pass-by-value.函数中的两个指针都具有与数组不同的地址.