使用指针在c中反转字符串
reverse string in c using pointers
我正在尝试使用指针反转字符串,但它似乎不起作用,有什么问题吗?输出是 olllo
但应该是 olleh
.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
void reverse(char *cadena){
size_t len = strlen(cadena);
char *end= cadena;
char *aux = cadena;
while(*++end){}
--end; //end points to a
for(;len;--len){
*aux++ = *end--;
}
}
int main()
{
char buffer[] = "hello";
reverse(buffer);
printf("%s",buffer);
return 0;
}
行:
*aux++ = *end--;
不交换任何东西。它只是 将 左侧赋给右侧的值。你总是会得到一个回文,由字符串的右半部分组成。对于交换逻辑,你应该这样做:
char tmp = *aux;
*aux = *end;
*end = tmp;
此外,您不应该真正遍历整个字符串。实际上,这意味着反转字符串然后 再次反转它 。只需在遍历 字符串的一半 时应用交换逻辑,就可以开始了:
void reverse(char *cadena) {
if(cadena != NULL){ // add some checks...
size_t len = strlen(cadena);
char *end = cadena + (len > 1 ? len - 1 : 0); // ...for safety
char *aux = cadena;
for (len /= 2; len; --len) {
char tmp = *aux;
*aux++ = *end;
*end-- = tmp;
}
}
}
解决你的错误
你的循环的问题是,当你试图反转原地的字符时,你最终交换了已经交换的字符。
我将尝试通过展示每次迭代中发生的情况来进行解释。
您可以在每次迭代中的每次交换后看到 cadena
的初始内容和最终的 (res
)。 |
是指针 aux
和 end
当前指向的位置:
len = 5
aux |
h e l l o
end |
res: o e l l o
len = 4
aux |
h e l l o
end |
res: o l l l o
len = 3
aux |
h e l l o
end |
res: o l l l o
len = 2
aux |
h e l l o
end |
res: o l l l o
len = 1
aux |
h e l l o
end |
res: o l l l o
len = 0
=> break the loop
在解决..
我的 reverse
将是 this one:
void reverse(char *str)
{
if (!str || !(*str)) return;
char *end = str + strlen(str) - 1;
while (str < end) {
char tmp = *str;
*str++ = *end;
*end-- = tmp;
}
}
一些要点:
- 注意使用
strlen
来查找字符串的最后一个字符
- 你应该迭代直到开始和结束指针相遇。否则你重新反转字符串
您的代码中存在三个重要错误:
在此代码段中前进到末尾时,您对空字符串的处理不当:
char *end= cadena;
// Irrelevant: char *aux = cadena;
while(*++end){}
--end; //end points to a
无论如何,您已经有了字符串长度,所以只需添加即可。
修复此错误时,请确保只创建有效的指针,即指向对象或仅在对象后面的指针。
您遍历了整个字符串的长度,而不是一半。如果你真的交换了元素,那么你将交换所有东西两次,这是一个非常昂贵的 nop:
for(;len;--len){
您正在复制而不是交换。您没有保存您覆盖的值,也没有将它存储回它所属的位置。
*aux++ = *end--;
}
固定码:
void reverse_string(char* s) {
char* e = s + strlen(s);
while (s < e) {
char t = *s;
*s++ = *--e;
*e = t;
}
}
我正在尝试使用指针反转字符串,但它似乎不起作用,有什么问题吗?输出是 olllo
但应该是 olleh
.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
void reverse(char *cadena){
size_t len = strlen(cadena);
char *end= cadena;
char *aux = cadena;
while(*++end){}
--end; //end points to a
for(;len;--len){
*aux++ = *end--;
}
}
int main()
{
char buffer[] = "hello";
reverse(buffer);
printf("%s",buffer);
return 0;
}
行:
*aux++ = *end--;
不交换任何东西。它只是 将 左侧赋给右侧的值。你总是会得到一个回文,由字符串的右半部分组成。对于交换逻辑,你应该这样做:
char tmp = *aux;
*aux = *end;
*end = tmp;
此外,您不应该真正遍历整个字符串。实际上,这意味着反转字符串然后 再次反转它 。只需在遍历 字符串的一半 时应用交换逻辑,就可以开始了:
void reverse(char *cadena) {
if(cadena != NULL){ // add some checks...
size_t len = strlen(cadena);
char *end = cadena + (len > 1 ? len - 1 : 0); // ...for safety
char *aux = cadena;
for (len /= 2; len; --len) {
char tmp = *aux;
*aux++ = *end;
*end-- = tmp;
}
}
}
解决你的错误
你的循环的问题是,当你试图反转原地的字符时,你最终交换了已经交换的字符。
我将尝试通过展示每次迭代中发生的情况来进行解释。
您可以在每次迭代中的每次交换后看到 cadena
的初始内容和最终的 (res
)。 |
是指针 aux
和 end
当前指向的位置:
len = 5
aux |
h e l l o
end |
res: o e l l o
len = 4
aux |
h e l l o
end |
res: o l l l o
len = 3
aux |
h e l l o
end |
res: o l l l o
len = 2
aux |
h e l l o
end |
res: o l l l o
len = 1
aux |
h e l l o
end |
res: o l l l o
len = 0
=> break the loop
在解决..
我的 reverse
将是 this one:
void reverse(char *str)
{
if (!str || !(*str)) return;
char *end = str + strlen(str) - 1;
while (str < end) {
char tmp = *str;
*str++ = *end;
*end-- = tmp;
}
}
一些要点:
- 注意使用
strlen
来查找字符串的最后一个字符 - 你应该迭代直到开始和结束指针相遇。否则你重新反转字符串
您的代码中存在三个重要错误:
在此代码段中前进到末尾时,您对空字符串的处理不当:
char *end= cadena; // Irrelevant: char *aux = cadena; while(*++end){} --end; //end points to a
无论如何,您已经有了字符串长度,所以只需添加即可。
修复此错误时,请确保只创建有效的指针,即指向对象或仅在对象后面的指针。
您遍历了整个字符串的长度,而不是一半。如果你真的交换了元素,那么你将交换所有东西两次,这是一个非常昂贵的 nop:
for(;len;--len){
您正在复制而不是交换。您没有保存您覆盖的值,也没有将它存储回它所属的位置。
*aux++ = *end--; }
固定码:
void reverse_string(char* s) {
char* e = s + strlen(s);
while (s < e) {
char t = *s;
*s++ = *--e;
*e = t;
}
}