简体   繁体   English

使用指针在c中反转字符串

[英]reverse string in c using pointers

I am trying to reverse the string using pointers but it seems that it does not work, what's the problem? 我正在尝试使用指针来反转字符串,但似乎不起作用,这是什么问题? the output is olllo but should be olleh . 输出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;
}

The line: 该行:

*aux++ = *end--;

Does not swap anything. 交换任何东西。 It just assigns the left side the value of the right side. 它只是左侧分配右侧的值。 You'll always end up with a palindrome, made from the right half of the string. 您总是会遇到以字符串右半部分为中心的回文。 For swap logic, you should do: 对于交换逻辑,您应该执行以下操作:

char tmp = *aux;
*aux = *end;
*end = tmp;

Also, you shouldn't really iterate through the whole string. 另外,您不应该真正遍历整个字符串。 Actually, it'd mean reversing the string and then reversing it back again . 实际上,这意味着将字符串反转,然后再次将其反转 Just apply the swapping logic while iterating through just half of the string, and you're good to go: 只需遍历字符串的一半就应用交换逻辑,就可以了:

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;
        }
    }
}

Addressing your fault 解决您的错误

The problem with your loop is that while you try to reverse the characters in place you end up swap already swapped characters. 循环的问题是,当您尝试在原处反转字符时,最终交换已交换的字符。

I'll try to explain by showing what happens in each iteration. 我将尝试通过显示每次迭代中发生的事情来进行解释。 You can see the initial contents of cadena and the final ( res ) after each swap in each iteration. 您可以在每次迭代中的每次交换之后看到cadena的初始内容和最终( res )。 The | | are where the pointers aux and end are currently pointing: 指针auxend当前指向的位置:

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

On a solution.. 在解决方案上..

My inplace reverse would be this one : 我的原地reverse将是这个

void reverse(char *str)
{
    if (!str || !(*str)) return;

    char *end = str + strlen(str) - 1;

    while (str < end) {
        char tmp = *str;
        *str++ = *end;
        *end-- = tmp;
    }
}

Some key points: 一些关键点:

  • notice the use of strlen to find the last character of the string 注意使用strlen查找字符串的最后一个字符
  • you should iterate until the starting and ending pointers meet. 您应该进行迭代,直到开始和结束指针相遇为止。 Otherwise you re-reverse the string 否则,您将字符串反向

There are three important errors in your code: 您的代码中存在三个重要错误:

  1. You are mishandling the empty string when advancing to the end in this snippet: 在此代码段中前进时,您对空字符串的处理不正确:

     char *end= cadena; // Irrelevant: char *aux = cadena; while(*++end){} --end; //end points to a 

    Anyway, you already have the string-length, so just add it. 无论如何,您已经有了字符串长度,因此只需添加它即可。

    When fixing this error, make sure you only create valid pointers, meaning to or just behind objects. 解决此错误时,请确保仅创建有效的指针,即指向对象或位于对象之后的指针。

  2. You are going over the length of the whole string, instead of just half of it. 您要遍历整个字符串的长度,而不是一半。 If you actually swapped the elements, you would thus swap everything twice, a quite expensive nop: 如果您实际上交换了元素,那么您将交换所有内容两次,这是非常昂贵的nop:

     for(;len;--len){ 
  3. You are copying instead of swapping. 您正在复制而不是交换。 You didn't save the value you overwrote, and you didn't store it back where it belongs. 您没有保存您覆盖的值,也没有将其存储回它所属的位置。

      *aux++ = *end--; } 

Fixed code: 固定代码:

void reverse_string(char* s) {
    char* e = s + strlen(s);
    while (s < e) {
        char t = *s;
        *s++ = *--e;
        *e = t;
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM