【问题标题】:Why isn't this pointing to the null character in array? ('\0')为什么 this 不指向数组中的空字符? ('\0')
【发布时间】:2014-01-04 18:56:54
【问题描述】:

很抱歉这个措辞不好的问题,我想不出更好的名字。

我正在学习 C,刚刚移到指针上并编写了一个函数 strcat(char *s, char *t),它将 t 添加到 s 的末尾:

void strcat(char *s, char *t) //add t to the end of s
{
    while(*s++)                //get to the end of s
        ;
    *s--;                      //unsure why I need this
    while(*s++ = *t++)         //copy t to the end of s
        ;
    return;
}

现在我的问题是为什么我需要这条线:

*s--;

当我最初添加它时,我认为它是有意义的,直到我完成了代码。

我会认为以下是正确的:

1) 第一个循环不断递增,当 *s 为 0(或空字符)时,它继续前进,所以现在 *s 指向数组的空字符。

2) 所以我要做的就是实现第二个循环。 s 的原始空字符将被 t 的第一个字符替换,直到我们到达 t 的空字符,此时我们退出第二个循环并返回。

显然我遗漏了一些东西,因为没有它,代码就无法工作!!

在第一个循环之后 *s 指向 '\0' 之外的一个位置,但我的问题是为什么?

提前致谢:)

【问题讨论】:

    标签: c arrays pointers char


    【解决方案1】:

    首先评估*s,然后增加s

    因此,当到达s0-terminator 时,循环结束,但s 仍会再增加一次。


    也不需要这样做:

      *s--;
    

    在做

      --s;
    

      s--;
    

    就够了。此处无需取消引用s

    或者干脆做

    while (*s)
      ++s;
    

    完全摆脱--s;的需要。

    【讨论】:

      【解决方案2】:

      您在检查指针指向的位置的值后增加了指针。从功能上讲,这发生在 while(*s++):

      while( *s )
      ++s;
      

      【讨论】:

      • 从技术上讲,这并不是他循环中代码的完美替代品,因为直到s 溢出或程序出现段错误,此循环才会结束。
      • 是的,我后来意识到了这一点。很好的收获。
      【解决方案3】:

      将您的第一个 while 更改为:

      if (*s) {
          while(*(++s))                //get to the end of s
                  ;
      }
      

      在您的代码中,您总是会检查它是否指向 '\0' 然后递增,因此当您到达 '\0' 时,您只会在下一次迭代时检查它,然后再递增它.注意改成pre-increment不会检查指针当前是否指向'\0',所以需要在while之前检查一下。

      请注意,您的代码(后增量和一段时间后的减量)在大多数平台上可能更快(通常分支比减量慢),我在此答案中的代码只是为了让您了解问题。

      【讨论】:

      • while(*s) ++s; 呢?
      • @alk 那会更好。正如我所说,我的例子只是为了让他了解正在发生的事情。
      【解决方案4】:

      ++操作符之后变量名是后自增的,即加一,但操作符的结果是自增前的值。如果你用++s,那就不一样了。

      如果 s 是 4 ,那么在 x=++s 和 x=s++ 之后 s 将是 5。但是第一种情况的结果(x 的值)是 5,而第二种情况是 4。

      所以在你的while *s++ 中,当 s 指向 '\0' 时,你递增它,然后取旧的、未递增的指针,取消引用它,查看 \0,然后停止循环。

      顺便说一句,你的 '*s--' 应该是 s--,因为你不需要指针“后面”的字符。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2020-04-07
        • 2022-10-20
        • 1970-01-01
        • 2019-03-10
        • 2016-04-06
        • 1970-01-01
        • 1970-01-01
        • 2021-12-05
        相关资源
        最近更新 更多