Head First C反向字符串示例

时间:2019-02-19 07:16:51

标签: c

我一直在经历'Head First 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 + len - 1;

    while (t >= s) {
     printf("%c", *t);
     t = t - 1;
    }

    puts("");
}

我从书中理解了解决方案,但是我的看起来更干净。后一种解决方案是否可取,如果可以,为什么?

3 个答案:

答案 0 :(得分:4)

总结评论:

首先,函数名称reverse_string()具有误导性,因为它不会反转字符串,而只会以相反的顺序打印它。

该函数应采用指向const char的指针,而不是指向char的指针。有些人可能会争辩说,在参数列表中使用[]有点误导,因为它可能会使对C不太熟悉的人相信数组被传递而不是指向其第一个元素的指针。

两个函数都使用printf()打印单个字符。这涉及解析格式字符串以仅一次输出单个字符的不必要工作。改用´putchar()or fputc()`。

这两个功能之间的功能差异:您的版本在反向字符串后不显示换行符。本书的版本可以做到这一点,但是就像对单个字符使用printf()一样,它以伪装的方式使用puts("")而不是putchar('\n')

当将空字符串传递给函数时,本书的版本可能具有未定义的行为,因为在这种情况下,t会指向s所指向的数组的第一个元素之前的'不能保证工作。

您的版本使用int eger存储strlen()类型为size_t的结果。 int可能会在很长的字符串中溢出。

两种可能的解决方案:

#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');
}

或使用索引:

#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');
}

答案 1 :(得分:3)

本书中的解决方案具有未定义的行为,因为它使<ObjectIdentifier title="{users>Email}" text="last: {path: 'users>LastLoggedOnUtcDate', formatter: '.formatDateTime'}"/> 减至字符串开头之外。比较t指向数组外部和t具有不确定的行为。在具有分段指针的体系结构中,s仅测试指针的偏移量部分会失败。出于相同的原因,它也会因为空字符串而失败。

带有指针的便携式解决方案如下所示:

>=

您的版本使用的索引不错,但是存在一个小问题:它不处理长度超过void reverse_string(const char *s) { const char *t = s + strlen(s); while (t > s) { t--; putchar(*t); } putchar('\n'); } 的字符串。字符串的长度为INT_MAX类型,可能大于size_t,甚至在intint具有相同大小(size_t为无符号的值可能大于size_t

更改类型INT_MAX是不够的,因为您依靠i变成负数。这是减少索引之前进行测试的一种优雅方法:

i

一些滑稽的程序员编写此比较void reverse_string(char s[]) { for (size_t i = strlen(s); i-- > 0;) { putchar(s[i]); } putchar('\n'); } 并将i --> 0称为 downto 运算符...这是一个笑话,该表达式被解析为--> { {1}} i --,中间的空格无关紧要。

答案 2 :(得分:1)

首先,没有一种解决方案可以反转字符串。他们以相反的顺序打印它,但这与反向打印不同。

您的解决方案看起来更好,更简洁,而且不会降低可读性,这很好。

我不会说书中的解决方案是可取的。