解释此C代码以反转字符串

Sup*_*ing 3 c string algorithm reverse

我真的不明白最后一个while循环在做什么,有人可以解释一下吗?

void reverse(char *str) { 
    char * end = str; 
    char tmp; 

    if (str) {
        while (*end) { 
            ++end;
        }
        --end; 
        while (str < end) {
            tmp = *str; 
            *str++ = *end;
            *end-- = tmp;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

有人可以通过示例"你好"来引导我吗?

tem*_*def 11

这段代码背后的基本思想是两遍:

  1. 在第一遍中,我们最终得到一个指向字符串最后一个字符的指针.
  2. 在第二遍中,我们转动弦,在弦的结束处知道的帮助下.

第一遍由以下逻辑给出:

char *end = str;
while (*end) { 
    ++end;
}
--end; 
Run Code Online (Sandbox Code Playgroud)

while循环以end指向字符串开头的指针开始.然后它继续向前推进end指针一步,直到循环条件*end不再评估为真.因为C字符串是以空值终止的,所以只要end指针指向字符串中间的某处而不是字符串末尾的空终止符,循环条件就会计算为true .因此,当此循环结束时,end指针将一直走到字符串的末尾并停在空终止符处.然后我们执行--end以将指针备份一步.此时,end指针指向字符串中的最后一个字符.以下是"Hello:"的示例

 H e l l o
 ^       ^
 |       |
str     end
Run Code Online (Sandbox Code Playgroud)

现在我们有了这个end指针,我们实际上运行逻辑来反转字符串.这是由以下代码给出的:

while (str < end) {
    tmp = *str; 
    *str++ = *end;
    *end-- = tmp;
}
Run Code Online (Sandbox Code Playgroud)

这段代码背后的想法是,直到字符串的开始和结束指针相互交叉,我们交换它们指向的值,然后将两个指针向内推向另一个.如果我们通过稍微冗长的重写将其重写为等价物

while (str < end) {
    tmp = *str; 
    *str = *end;
    *end = tmp;

    ++str;
    --end;
}
Run Code Online (Sandbox Code Playgroud)

然后可能会更容易看出它是如何工作的.此修改循环的前三行交换起始和结束指针指向的值,接下来的两行将指针向内移动.这是一个例子:

 H e l l o
 ^       ^
 |       |
str     end

 o e l l H
   ^   ^
   |   |
  str end

 o l l e H
     ^
     |
  str end
Run Code Online (Sandbox Code Playgroud)

此时,两个指针相遇,我们正确地反转了字符串.

请注意,我们必须在这里考虑一个不寻常的边缘情况,这就是当字符串是空字符串时会发生什么.如果发生这种情况,那么第一个循环将表现得有些奇怪.特别是,这段代码:

char *end = str;
while (*end) { 
    ++end;
}
--end; 
Run Code Online (Sandbox Code Playgroud)

永远不会执行循环体,因为end指针将从指向空终止符开始.因此循环什么都不做,我们最终end 在字符串开始之前备份一步! 这是一个无效指针,取消引用它将有不确定的结果.但幸运的是,在这种情况下,没有任何反应,因为反转字符串的循环具有以下条件:

while (str < end)
Run Code Online (Sandbox Code Playgroud)

如果end在字符串开始之前是一步,则立即返回false ,因此没有任何反应.

希望这可以帮助!