ale*_*lex 2 c readability kernighan-and-ritchie
我看了C(还在学习)已经有一段时间了,我刚回到K&R书中.
我刚开始练习5-3(第107页).
编写我们在第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;
}
Run Code Online (Sandbox Code Playgroud)
它似乎工作.
我想知道,就是K&R的书经常写尽可能少的线尽可能的练习-我期望有他们上面提供了自己的代码示例,你会得到像这样 ...
void strcat(char *s, char *t) {
while (*s++ != '\0');
s--;
while ((*s++ = *t++) != '\0');
*--t = '\0';
}
Run Code Online (Sandbox Code Playgroud)
对我来说,这是不太可读(也许这个例子不是很好,但我经常看看他们的代码,并认为如果将它分成几行,我会更好地理解它).本书中提供的示例似乎主张在循环的条件部分中进行这种赋值,实际上每行尽可能多地填充代码.
即使可读性受到影响,这本书是否正确地尽可能地尽可能地做到了?
这只是The C Way吗?
gre*_*jor 13
K&R在书中解释了习语的重要性.是的,代码的简洁性受到C程序员的重视,但是并不是故意用来惩罚初学者.经过一段时间阅读和编写C,你开始识别模式,所以当你在别人的代码中看到它们时,你就会知道你在看什么.
strcpy()
在K&R中作为一个例子进行迭代- 他们解释了他们的简洁与清晰的哲学,并谈论成语.
您不应该期望您的程序工作,因为您正在调用未定义的行为.
您定义了两个特定大小的缓冲区(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;
}
Run Code Online (Sandbox Code Playgroud)