头优先C反向字符串示例
我一直在学习“头优先C”,我找到了一个创建字符串反转方法的练习 这就是我的解决方案:头优先C反向字符串示例,c,C,我一直在学习“头优先C”,我找到了一个创建字符串反转方法的练习 这就是我的解决方案: void reverse_string(char s[]) { for (int i = strlen(s) - 1; i > -1; i--) { printf("%c", s[i]); } } 这是书中的解决方案: void reverse_string(char *s) { size_t len = strlen(s); char *t = s + le
void reverse_string(char s[]) {
for (int i = strlen(s) - 1; i > -1; i--) {
printf("%c", s[i]);
}
}
这是书中的解决方案:
void reverse_string(char *s) {
size_t len = strlen(s);
char *t = s + len - 1;
while (t >= s) {
printf("%c", *t);
t = t - 1;
}
puts("");
}
我从书上理解了解决办法,但我的看起来更干净。后一种解决方案更可取吗?如果是,原因是什么?首先,没有任何一种解决方案可以逆转字符串。他们按相反的顺序打印,但这与反转不同 您的解决方案看起来更好、简洁,而且不丧失可读性,这很好
我不认为这本书中的解决方案更可取。总结一下评论: 首先,函数名
reverse\u string()
有误导性,因为它不反转字符串,只按相反顺序打印
函数应该使用指向const char
的指针,而不是指向char
的指针。有些人还可能认为在参数列表中使用[]
有点误导,因为这可能会让不太熟悉C的人相信传递的是数组,而不是指向其第一个元素的指针
这两个函数都使用printf()
打印单个字符。这涉及到不必要的解析格式字符串的工作,一次只输出一个字符。改为使用`putchar()或
fputc()
这两个函数之间的功能差异:您的版本不会在反转的字符串后打印换行符。这本书的版本可以做到这一点,但就像对单个字符使用printf()
一样,它以伪装的方式使用put(“”
)而不是putchar('\n')
当一个空字符串被传递给函数时,本书中的版本可能有未定义的行为,因为在这种情况下,t
将指向s
指向的数组的第一个元素之前,该元素不能保证工作
您的版本使用int
eger来存储strlen()
类型的size\u t
的结果。int
eger可能会溢出很长的字符串
两种可能的解决办法:
#include <string.h> // strlen()
#include <stdio.h> // putchar()
void print_reverse(char const *str)
{
for (char const *p = str + strlen(str); p != str; putchar(*--p));
putchar('\n');
}
#包括//strlen()
#include//putchar()
无效打印(字符常量*str)
{
for(char const*p=str+strlen(str);p!=str;putchar(*--p));
putchar('\n');
}
或使用索引:
#include <string.h> // strlen()
#include <stdio.h> // putchar()
void print_reverse(char const *str)
{
for (size_t i = strlen(str); i; putchar(str[--i]));
putchar('\n');
}
#包括//strlen()
#include//putchar()
无效打印(字符常量*str)
{
for(size_t i=strlen(str);i;putchar(str[--i]);
putchar('\n');
}
本书中的解决方案具有未定义的行为,因为它在字符串开头之后递减t
。比较指向数组外部的t
和s
具有未定义的行为。在具有分段指针的体系结构上,如果=
只测试指针的偏移部分,则它将失败。出于同样的原因,它也会因空字符串而失败
带有指针的便携式解决方案如下所示:
void reverse_string(const char *s) {
const char *t = s + strlen(s);
while (t > s) {
t--;
putchar(*t);
}
putchar('\n');
}
您的版本使用了一个索引,这是可以的,但它有一个小问题:它不处理长度超过INT\u MAX
的字符串。字符串长度的typesize\u t
可能大于int
,事实上,即使在int
和size\u t
大小相同的体系结构上,size\u t
未签名的值也可能大于int\u MAX
更改类型i
是不够的,因为您依赖于i
变为负值。在递减索引之前,这里有一种优雅的测试方法:
void reverse_string(char s[]) {
for (size_t i = strlen(s); i-- > 0;) {
putchar(s[i]);
}
putchar('\n');
}
一些滑稽的程序员编写这个比较
i-->0
并调用-->
downto操作符。。。这是一个笑话,表达式被解析为i
--
0
,中间的空格无关紧要。两者都是正确的,两者都没有错。在本书的上下文中,这本书中的一本可能更可取,但这并不意味着你不能使用你的解决方案。但是,您的解决方案和图书解决方案之间有一点不同:您的解决方案不打印换行符。是的,我更喜欢您的版本。strlen()
的结果是size\u t
,而不是int
。两个版本都不是最优的。。。不需要使用printf()
,它必须解析格式字符串,一次只输出一个字符。使用putchar()
或fputc()
。这本书中的代码可以使用for()
-循环来提高可读性void reverse_string(char const*str){for(char const*p=str+strlen(str)-1;p>=str;--p){putchar(*p);}putchar('\n');}
我担心书本解决方案会尝试递减指针t
,直到它指向数组s
的开始之前。不能保证你能做到这一点。这两个函数都命名错误;两者都不反转字符串,但都以相反的方式打印字符串。如果传递空字符串,则两者都具有未定义的行为。(我看过的“头先”的书不是很好——作者们似乎对当代流行文化的有趣引用比对教学更感兴趣。)两者都不是完全可取的,因为他们使用可变的printf
,其中需要一个简单的putchar()
。