1

我有反转字符串的代码。假设我输入“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    }

第 7 行和第 8 行是做什么的?指针 t 的输出是什么?

4

6 回答 6

8

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

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

关于这个循环,你应该知道一些事情(如果不是你,应该向作者指出)。最后的指针比较符合标准。该标准规定了非空、类似类型的指针之间的比较是有效的,从有效序列的基地址(charinput在此代码中,通过 参数化的地址)直到并包括超过分配的内存区域的s一个类型元素。此代码与 比较,仅在“更少”时才打破循环。但是一旦小于 s,它的值就不再合法地与. 根据标准,这是因为不再包含一个有效地址,该地址范围为tsttstcharinput通过 1-过去的charinput内存块大小。

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

t = s + len;
while (t-- > s)
    printf("%c", *t);

编辑:在Paul Hankin的推动下进入标准之旅后,先前的代码已被重写以解决未被注意到的 UB 条件。更新的代码记录如下:

t = s + len;
while (t != s)
    printf("%c", *--t);

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

  • t设置为字符串的终止 nulchar 的地址。
  • 进入循环,只要 in 的地址t不等于 的基地址,条件就会继续s
    • 递减t,然后取消引用结果地址以获得当前字符,将结果发送到printf
    • 循环进行下一次迭代。
于 2013-10-12T09:45:02.840 回答
3

让我们一步一步来理解它:

  1. len = strlen(s)s将以字节为单位的字符串的大小分配给len(比如说这len是10)。

  2. s 指向字符串的第一个字符。假设这个字符串的第一个元素的地址是100,然后s包含100

  3. 添加len-1s将给出109.

现在,第 7 行

   char *t = s + len-1;

告诉编译器t指向地址的元素109,即字符串的最后一个元素。

8号线

   while(t >= s) {

告诉编译器循环将继续,直到t指向字符串的第一个元素之前的东西。

于 2013-10-12T09:43:10.510 回答
1

第 7 行:指针t指向最后一个字符(s+len-1)
第8行:当t的地址等于或大于s的地址时重复该步骤。假设如果 s 指向第一个输入字符串的地址是 1101,则下一个字符的地址是 1101+1=1102,第三个是 1102+1=1103,以此类推。所以如果你输入有 10 个字符长,那么1101 + len-1第 7 行中的t 将是指向的。 第 9 行:打印由 . 指向的地址所持有的字符。第 10 行:减 1,现在指向最左边的字符。 当地址大于或等于时重复 9 和 10(在我的插图中为 1110)1101+10-1 (1110)
tt

于 2013-10-12T09:45:42.690 回答
0

t 开始指向字符串 s 的最后一个字符,并在接下来的循环中递减,直到它指向第一个字符。对于每个循环迭代,都会打印字符。

于 2013-10-12T09:26:55.080 回答
0

第 7 行将指针设置为指向t字符串的结尾s。第 8 行是一个 while 循环(它将向后遍历字符串,直到开始)。指针 t 是字符串中的当前位置,在第 9 行输出。

于 2013-10-12T09:27:38.320 回答
0

char *t = s + len-1; : 指向字符串 s 的最后一个字符 while(t >= s) : 以相反的顺序扫描字符串 s 的所有字符(因为s指向第一个字符,我们已经t指向最后一个字符line 7)。

希望这可以帮助。

于 2013-10-12T09:31:55.290 回答