2

自从我看 C(仍在学习)以来已经有一段时间了,我刚刚回到了 K&R 书。

我刚刚参加了练习 5-3 (p107)。

编写我们在第 2 章中展示的函数 strcat 的指针版本:strcat(s,t) 将字符串 t 复制到 s 的末尾。

我想出了这个...

void strcat(char *s, char *t);

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

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

    *--t = '\0';

}

int main() {
   char str[] = "Hey, hello";
   char str2[] = " are you?";

   strcat(str, str2);

   printf("%s\n", str);

   return 0;

}

它似乎工作。

我想知道的是,K&R 书经常用尽可能少的行编写练习——我希望如果他们为上面提供了自己的代码示例,你会得到这样的东西......

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

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

}

对我来说,这不太可读(也许这个例子不是那么好,但我经常看他们的代码并认为如果将其分成几行,我会更好地理解它)。书中提供的示例似乎提倡在循环的条件部分进行这种赋值,实际上每行都塞满了尽可能多的代码。

即使可读性受到影响,这本书是否尽可能地尽力而为?

这只是C 方式吗?

4

3 回答 3

13

K&R 在书中解释了成语的重要性。是的,C 程序员很看重代码的简洁性,但它并不是故意简洁来惩罚初学者。在阅读和编写 C 语言一段时间后,您开始识别模式,因此当您在别人的代码中看到它们时,您就知道自己在看什么。

在 K&R 中以给出的示例为例进行迭代strcpy()——他们解释了简洁与清晰的哲学,并谈论成语。

于 2010-10-16T10:45:31.200 回答
5

您不应该期望您的程序能够工作,因为您正在调用未定义的行为

您定义了两个一定大小的缓冲区(str长 11 个字节,长str210 个字节)。然后,在 期间strcat,您尝试写入str[11]不存在的 。从此时起,您的程序的执行没有任何保证。它可能会崩溃,它可能会按照您的预期运行,或者它可能只是打印“42”并让您想知道为什么。

此外,您不应更改*tin strcat,因为在较新版本的 Ct中具有 type const char *

第三,在重新实现同样由您的环境提供的功能时,给它另一个名称。否则,您的编译器可能会将其替换为与函数调用等效的一些内置代码。例如 GCC__builtin_strlen有时会替换对strlen.

代码的固定版本如下所示:

#include <stdio.h>

/* renamed strcat to str_cat to avoid confusing the compiler */
void str_cat(char *s, const char *t) { /* added the const qualifier to t */

    while (*s++ != '\0');
    s--;
    while (*t != '\0') {
        *s++ = *t++;
    }
    /* removed the needless modification of *t */
    *s = '\0'; /* edit: added this line after the comment from Jonathan Leffler */
}

int main() {
   char str[80] = "Hey, hello"; /* note the large array size here */
   char str2[] = " are you?";

   str_cat(str, str2);
   printf("%s\n", str);

   return 0;

}
于 2010-10-16T11:05:57.827 回答
0

使用Google Codesearch可以找到其他更易读、更有效的示例

将 Android 和 BSD 的源代码视为更现代的 C 实现strcat.

而不是strcat您应该编写一个实现,strlcat并且还可以找到该源的许多示例。

于 2010-10-16T21:09:57.040 回答