【问题标题】:C syntax. Copying a character stringC 语法。复制字符串
【发布时间】:2011-07-24 12:51:05
【问题描述】:

通过 K&R,我看到了一个函数 strcopy 的以下代码 sn-p,它将一个字符数组复制到另一个。

如果t是指向第一个数组的指针,s是指向t要复制到的数组的指针,代码为:

void strcopy(char *s, char *t){

     while(*s++=*t++)
             ;
}

我对 while 循环感到困惑。我undersatnd内部条件t被复制到s,但我不明白这里正在测试什么条件。 *t++ 什么时候会是假的(或零)?大概,当字符串结束时。我们可以通过检查指向的字符是否为'\0'来测试字符串是否完成。 K&R 说了这么多。但是这本书相当愉快地指出,这个测试是没有必要的。所以我想知道这里正在测试什么?

【问题讨论】:

  • 这样的经典代码。但是如果你写这样的东西,也许你的同事会抱怨......将代码扩展到几行将有助于轻松阅读。编译器会为你做优化。

标签: c string pointers


【解决方案1】:
*s++ = *t++;

等同于:

*s = *t;
t++;
s++;

条件总是评估左值,所以在这种情况下它就像测试

while(*s)

当然,'\0' 的计算结果为 false,所以你不需要while(something!='\0'),因为while(something) 就足够了。

【讨论】:

  • t++s++,在这种情况下不需要*
【解决方案2】:

*s++ = *t++ 将评估为分配的值。在字符串的末尾,*t 将是 '\0',并且在赋值后,表达式将计算为 '\0'(C 将其解释为 false)。

我猜 K&R 是说不需要额外的测试,因为一切都在 while 条件下处理。

【讨论】:

    【解决方案3】:

    你可以显式测试是否到达终止字符

    while ((*s++ = *t++) != '\0')
        ;
    

    如果您在 ascii 表中查找“\0”,您会看到字符“\0”的整数值为 0。编写类似 printf("%d\n", '\0'); 的内容也可以证明这一点。

    所以,上面的while语句也可以写成

    while ((*s++ = *t++) != 0)
        ;
    

    但是,while 循环始终检查条件是否具有非零值,因此以这种方式将 while 循环中的值与零进行比较总是多余的。因此,您可以直接跳过比较。

    【讨论】:

      【解决方案4】:

      C 赋值从右到左流动,while 循环执行隐式“if”测试。所以从测试的角度来看,编译的作用是......

      while(*t != 0) // for the sake off testing if the loop should continue ONLY
      

      另一个例子...

      if (a = b) // note the = vs == so, this will only be true if b != 0
      

      该循环的一种底层伪代码版本...

      loop:
      *s=*t;
      if (*s == 0) should_break=1;
      s++;
      t++;
      if (should_break==1) break;
      goto loop;
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-01-05
        • 2011-08-11
        • 2013-11-14
        • 1970-01-01
        • 2015-03-30
        • 2019-03-18
        相关资源
        最近更新 更多