我真的不明白最后一个循环正在做什么,有人可以解释一下吗?
void reverse(char *str) {
char * end = str;
char tmp;
if (str) {
while (*end) {
++end;
}
--end;
while (str < end) {
tmp = *str;
*str++ = *end;
*end-- = tmp;
}
}
}
有人可以通过示例“你好”吗?
答案 0 :(得分:11)
此代码背后的基本思想是两次通过:
第一遍由以下逻辑给出:
char *end = str;
while (*end) {
++end;
}
--end;
此while
循环以指向字符串开头的end
指针开始。然后它继续向前推进end
指针一步,直到循环条件*end
不再评估为真。因为C字符串是以空值终止的,所以只要end
指针指向字符串中间的某处而不是字符串末尾的空终止符,循环条件就会计算为true。因此,当此循环结束时,end
指针将一直走到字符串的末尾并停在空终止符处。然后我们执行--end
以将指针备份一步。此时,end
指针指向字符串中的最后一个字符。以下是“Hello:”
H e l l o
^ ^
| |
str end
现在我们有了这个end
指针,我们实际上运行逻辑来反转字符串。这由以下代码给出:
while (str < end) {
tmp = *str;
*str++ = *end;
*end-- = tmp;
}
这段代码背后的想法是,直到字符串的开始和结束指针相互交叉,我们交换它们指向的值,然后将两个指针向内推向另一个。如果我们通过略微更详细的
重写这个等价物while (str < end) {
tmp = *str;
*str = *end;
*end = tmp;
++str;
--end;
}
然后可能会更容易看出它是如何工作的。此修改循环的前三行交换起始和结束指针指向的值,接下来的两行将指针向内移动。这是一个例子:
H e l l o
^ ^
| |
str end
o e l l H
^ ^
| |
str end
o l l e H
^
|
str end
此时,两个指针相遇,我们正确地反转了字符串。
请注意,我们必须在这里考虑一个不寻常的边缘情况,这就是当字符串是空字符串时会发生什么。如果发生这种情况,那么第一个循环将表现得有些奇怪。特别是,这段代码:
char *end = str;
while (*end) {
++end;
}
--end;
永远不会执行循环体,因为end
指针将从指向空终止符开始。因此循环不执行任何操作,我们最终在字符串开始之前备份end
一步!这是一个无效指针,取消引用它将有未定义的结果。但幸运的是,在这种情况下,没有任何反应,因为反转字符串的循环具有以下条件:
while (str < end)
如果end
在字符串开始之前是一步,则立即返回false,因此没有任何反应。
希望这有帮助!
答案 1 :(得分:4)
在最里面的while循环中基本上发生的是,在每次迭代中,str
和end
指向的字符交换,str
递增以指向下一个字符,并且end
递减以指向前一个。
以“你好”为例:
v v
hello
v v
oellh
v
olleh
然后循环结束,str
= end
。
答案 2 :(得分:0)
第一个找到最后一个字符;所以,在它之后,end
将指向它。
第二个时间将str
指向的字符与end
指向的字符交换,并将str
向前移动1个字符,向end
向后移动1个字符。这样,字符就会从字符串的extern转换到内部。
当end
开始指向str
之前的字符时,外观结束,这意味着我们到达字符串的中心并且所有字符都已经被交换。
“你好”的例子:
S E S E
V V V V
Hello >>swap>> oellH
>>pointer increment/decrement>>
S E S E
V V V V
oellH >>swap>> olleH
>>pointer increment/decrement>>
it would result in
E
S
V
olleH
but now str is no longer before end, so the loop terminates
答案 3 :(得分:0)
好的,它的作用是什么。
void reverse(char *str) {
char * end = str; // copy the pointer
char tmp;
if (str) {
// Now step through the string until you get to the last character.
// which will be the null terminator \0
while (*end) {
++end;
}
// One step back, and we're pointing at the last actual character.
--end;
// Now. Move the start at either end and work your way inwards until
// they meet in the middle.
while (str < end) {
// take copy of left character into tmp
tmp = *str;
// copy right character into left position and move left pointer right
*str++ = *end;
// copy tmp character into right position and move right pointer left
*end-- = tmp;
}
}
}
答案 4 :(得分:-1)
#include<stdio.h>
#include<string.h>
main()
{
int i=0,lenght,j;
char str[100],st[100];
printf("\nEnter a string");
scanf("%s",str);
lenght=strlen(str);
for(i=0,j=(lenght-1);str[i]!='\0',j>=0;i++,j--)
{
st[j]=str[i];
}
st[i]='\0';
printf("\nThe reversed string is %s\n",st);
}