K& R教学的可读性差吗?

时间:2010-10-16 10:22:02

标签: c readability kernighan-and-ritchie

我看了C(还在学习)已经有一段时间了,我刚刚回到K& R书中。

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

  

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

我想出了this ......

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书经常用尽可能少的线条写练习 - 我希望他们为上面提供了自己的代码示例,你会得到类似this的内容...

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

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

}

对我来说,这个可读性较差(也许这个例子不太好,但我经常看看他们的代码并想一想如果将它分成几行,我会更好地理解)。本书中提供的示例似乎主张在循环的条件部分中进行这种赋值,事实上每行尽可能多地编写代码。

即使可读性受到影响,本书是否正确尽可能地尽可能地做到了?

这只是 The C Way 吗?

3 个答案:

答案 0 :(得分:13)

K& R解释了书中习语的重要性。是的,代码的简洁性受到C程序员的重视,但是并不是故意用来惩罚初学者。经过一段时间阅读和写作C,你开始识别模式,所以当你在别人的代码中看到它们时,你知道你在看什么。

通过K& R中作为例子给出的strcpy()的迭代 - 他们解释了他们的简洁与清晰的哲学,并谈论习语。

答案 1 :(得分:5)

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

定义两个特定大小的缓冲区(str长度为11个字节,str2长度为10个字节)。然后,在strcat期间,您尝试写入不存在的str[11]。从这一点开始,无法保证程序的执行。它可能会崩溃,它可能会达到您的预期,或者它可能只是打印“42”并让您想知道原因。

此外,您不应更改*t中的strcat,因为在较新版本的C t中,类型为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;

}

答案 2 :(得分:0)

使用Other more readable, more efficient examples可以找到

Google Codesearch

请特别注意Android和BSD的源代码,作为strcat更现代C实现的好例子。

除了strcat之外,您还应该编写strlcatmany examples的实现,而不是{{1}}。