我有用于反转字符串的代码.假设我键入'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的输出是什么?
发布的代码使用以下算法:
t字符串中的最后一个字符(注意:如果用户输入的字符串少于99个字符,它将是换行符).的-1是从终端零炭移回一个字符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的地址.t不等于基地址,条件就会继续s.
t,然后取消引用结果地址以获取当前字符,将结果发送到printf.