C中的字符串反转

Cho*_*hai 1 c string reverse

我有用于反转字符串的代码.假设我键入'ABC',输出将为'CBA'.但是,有些代码行我完全不明白.

1    #include <stdio.h>
2    #include <string.h>
3
4    void print_reverse(char *s) {
5   size_t len = strlen(s);
6
7   char *t = s + len-1;
8   while(t >= s) {
9       printf("%c", *t);
10      t = t-1;
11  }
12  puts("");
13  }
14
15    int main()
16    {
17  char charinput[100];
18  printf("Enter character you want to reverse:");
19  fgets(charinput, 100, stdin);
20  print_reverse(charinput);
21  getchar();
22    }
Run Code Online (Sandbox Code Playgroud)

第7行和第8行有什么作用?指针t的输出是什么?

Who*_*aig 8

发布的代码使用以下算法:

  • 第7行:将指针设置为t字符串中的最后一个字符(注意:如果用户输入的字符串少于99个字符,它将是换行符).的-1是从终端零炭移回一个字符
  • 第8-10行:这是逆转报告循环的核心.t针对字符串开头的地址重复测试指针.条件子句检查t值(地址)是否大于或等于字符串的起始地址.只要它是,就进入循环体,当前驻留在地址中的字符t被发送到stdout via printf().然后,地址输入t减少一个类型宽度(大多数所有具有单字节的系统上的一个字节char)并且循环重复.只有当t包含一个地址之前 s,循环中断(并注意:这不在标准范围内;请参阅下面的原因).

你应该知道关于这个循环的东西(如果不是你,应该指出作者).最终的指针比较符合标准.该标准指定非null,like-type之间的比较,指针从有效序列的基地址(charinput在此代码中,参数化的地址s)中有效,直到并包括一个超出分配的内存区域的类型元素.此代码比较t反对s,打破了仅环时t是"少".但是,只要t不到s,它的价值就不再具有法律范围可比性s.根据标准,这是因为t不再包含属于的范围内的有效地址charinput通过1 - 超过charinput内存块的大小.

正确执行此操作的一种方法如下:

t = s + len;
while (t-- > s)
    printf("%c", *t);
Run Code Online (Sandbox Code Playgroud)

编辑:在从Paul Hankin刺激之后进入标准之后,先前的代码已经被重写以解释未被注意的UB条件.更新的代码记录如下:

t = s + len;
while (t != s)
    printf("%c", *--t);
Run Code Online (Sandbox Code Playgroud)

这也适用于零长度字符串.它的工作原理如下:

  • t 设置为字符串的终止nulchar的地址.
  • 输入循环,只要地址in t不等于基地址,条件就会继续s.
    • 递减t,然后取消引用结果地址以获取当前字符,将结果发送到printf.
    • 循环下一次迭代.