首页 > 解决方案 > 当读取 C 中的字符串时,while 循环何时停止?

问题描述

我正在尝试自己实现该strcpy功能。原件strcpystring.h图书馆的一部分。

char *strcpy(char *dest, const char *src)
{
    assert(dest != NULL && src != NULL);
    char *temp = dest;
    while (*src)    
    {
        *dest = *src;
        src++;
        dest++;
    }
    return temp;
}
            
void strcpyTest()
{
   char source[20] = "aaaaaa";
   char dest1[20] = "bbbbbbbbb";
   char desta[10]="abcd";
   puts(dest1); // bbbbbbbbb
   strcpy(dest1, source);
   puts(dest1); // aaaaaa
   strcpy(desta, source);
   puts(desta); // aaaaaa
   strcpy(desta, dest1);
   puts(desta); // aaaaaa
   strcpy(dest1, desta);
   puts(dest1); // aaaaaa
   strcpy(source, desta); 
   puts(source); // aaaaaa
}

dest正如你所看到的,即使是第一次调用比函数更长的函数也会src给出正确的结果,尽管从逻辑上讲,它应该给出 aaaaaabb而不是aaaaaa

   char source[20] = "aaaaaa";
   char dest1[20] = "bbbbbbbbb";
   strcpy(dest1, source);
   puts(dest1);
   /** aaaaaa **/

为什么我的功能有效?我猜我必须在(*src)` 退出后手动添加/0字符。*dest*while

我的意思while (*src)是,当它到达*src*字符串的最后一个字符的末尾时退出/0。因此,我想我必须自己添加这个字符,*dest*但是代码会以某种方式工作并复制字符串,而无需手动添加/0.

  1. 所以我的问题是它为什么以及如何仍然有效?

  2. 当我创建一个新数组时,假设是 10 的int *arror char *arr,即char arr[10]orint arr[10]并且我只初始化 2 个第一个索引,其余索引内的值会发生什么变化?它们是否会填充零或垃圾值或什么?

也许我的代码有效,因为它充满了零,这就是while循环停止的原因?

标签: cwhile-loopc-stringsstrcpyfunction-definition

解决方案


对于初学者,您应该选择另一个名称而不是 strcpy。

让我们逐步考虑您的函数的所有调用。

变量source声明为

char source[20] = "aaaa";

这个声明等价于下面的声明

char source[20] = 
{ 
    'a', 'a', 'a', 'a', '\0', '\0', '\0', '\0', '\0', '\0', 
    '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0'
};

因为根据 C 标准,未显式初始化的数组元素被隐式初始化为零。

变量desta声明为

char desta[10]="abcd";

这个声明等价于下面的声明

char desta[10]= { 'a', 'b', 'c', 'd', '\0', '\0', '\0', '\0', '\0', '\0' };

所以第一次打电话

strcpy(desta, source);

只需将四个字符替换"abcd"为四个字符"aaaa"。结果数组desta将包含一个字符串,因为下界终止零被覆盖。

在这个电话之后

strcpy(desta, dest1);

数组desta将包含字符串,因为此调用不会覆盖"bbbbbbbbb"数组的最后一个零字符。desta

这个电话

strcpy(dest1, desta);

实际上并不是被改变的数组dest1

在这次通话中

strcpy(source, desta);

由于数组的所有零字符source都没有被覆盖,因此数组将包含一个字符串。

如果你一开始打电话,你可能会得到一个不可预知的结果

strcpy(desta, dest1);

接着

strcpy(desta, source);

因为您的函数不会将终止零附加到目标数组。

这是一个演示程序。

#include <stdio.h>
#include <assert.h>

char * my_strcpy(char *dest, const char *src)
{
    assert(dest != NULL && src != NULL);
    char *temp = dest;
    while (*src)    
    {
        *dest = *src;
        src++;
        dest++;
    }
    return temp;
}

int main(void) 
{
    char source[20] = "aaaaaa";
    char dest1[20] = "bbbbbbbbb";
    char desta[10]="abcd";
    
    my_strcpy(desta, dest1);
    my_strcpy(desta, source);
    
    puts( desta );

    return 0;
}

程序输出为

aaaaaabbb

那就是desta包含字符串"aaaaaabbb"而不是字符串aaaaaa

更新后的功能可能如下所示

char * strcpy(char *dest, const char *src)
{
    assert(dest != NULL && src != NULL);
    char *temp = dest;

    while ( ( *dest++ = *src++ ) );    

    return temp;
}

推荐阅读