c - 为什么仅分配指针的字符串复制函数不起作用?

标签 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;
}

这行不通,这让我质疑我对 C 中字符串和数组的理解。

这是我的推理:targetsource实际上只是指向数组第一个元素的指针,即。 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/

相关文章:

c++ - 输入之前声明的 char* 会使程序崩溃,而将其输入 'just-declared' char* 则不会。为什么?

c++ - c++ 中 strcpy 的替代方案

c - 如何使用 execlp() 查找 pid?

c - 为什么我的二维数组带有 malloc int segfault?

c - 为什么下面的程序输出是 5,而不是 4?谁能解释一下?

c - 如何通过malloc分配并打印字符数组?

c - 如何对结构数组中的字符串进行冒泡排序

C strtok 和 strcpy

c - 使用 Fscanf 解析特定的输入文件

构造一个循环来检查一个数字的数字之和是否能被 3 整除