0

I see a very interesting code to reverse a string, but I don't understand here:

#include <stdlib.h>
#include <stdio.h>
#include <string.h>

void Reverse(char *s);

int main()
{
    char *s=NULL;
    s=(char *)malloc(sizeof(char *));
    gets(s);
    Reverse(s);
    puts(s);
    return 0;
}

void Reverse(char *s)
{
    char *end=s;
    char tmp;
    if (s)
    {
        while (*end)   
        {
            ++end;
        }
        --end;
        while (s<end)  ??
        {
            tmp=*s;
            *s++=*end;
            *end--=tmp;
        }
    }
}

I see the this program tries to work on the same string by using end=s to change both string at the same time, but what does '*' line : while(s<end) here mean?

I use gdb and find that when we input asdfgh, when *s is fdsa and *end is fds, this is no longer true, how this line controls the program?

I just want to know what '??' line mean..

Thanks a lot !

user1209200
  • 13
  • 1
  • 5

2 Answers2

2

Strings in C are terminated by the \0 character, which has the integer value 0. As such it is a false value.

By using while(*end) you check whether end is pointing on the termination character of the given string. If it isn't pointing on the end, you move it further (++end). To ensure that the pointer is valid you move the "cursor" backward after this.

while(s < end) will now move check whether s is further forwarded than end. If not, then you'll swap the value of both "cursor". end will move toward s and vice versa. This way you're going to reverse the string.

You're debugging output is a result of gdbs interpretation. It interpreds end as a string, not a single character. Have a look at *end while debugging.

Note that your malloc is completely wrong. You have to allocate enough memory for the string, for example s = malloc(500*sizeof(char));. Use fgets instead, where you can specify the maximum number of characters to be read. Don't forget to free all memory you allocate:

#include <stdlib.h>
#include <stdio.h>
#include <string.h>

#define BUFFER_SIZE 500

void Reverse(char *s);

int main()
{
    char* s = malloc(BUFFER_SIZE * sizeof(char));
    fgets(s,BUFFER_SIZE,stdin);
    Reverse(s);
    puts(s);
    free(s);
    return 0;
}

void Reverse(char *s)
{
    char* end=s;
    char tmp;
    if(s)
    {
        while (*end)
        {
            ++end;
        }
        --end;
        while (s<end)
        {
            tmp=*s;
            *s++=*end;
            *end--=tmp;
        }
    }
}
Zeta
  • 103,620
  • 13
  • 194
  • 236
  • OK I see, but what actually compares s and end here? I mean compare them as they are string or their position value or sth else? – user1209200 Mar 28 '12 at 21:52
  • They compare... well, you could interpret this as "position". You could access the second character of a string by using `s[1]` or `*(s+1)`. Pointer which operate on the same object are comparable, as `end>s` is equivalent to `end-s>0` and well defined for such pointers. Pointers are basically adresses (`0x0000300`,`0x0000304`,...). `malloc` will return a block of continuous memory starting at `s = 0x10`. `end` could be something like `end = 0x80`. `s – Zeta Mar 28 '12 at 22:00
0

s and end are char pointer so the test (s < end) is true until the s pointer doesn't become greater than then end pointer.

Example

Assume that you want to reverse the string "hello" stored at the address 0x0000, ad the start of the function you have:

s = 0x0000 end = 0x003

now the while loop:

  1. s=0x0000 e=0x0003 *s=o *e=h
  2. s=0x0001 e=0x0002 *s=l *e=e
  3. s=0x0002 e=0x0003 << while exit >>
dvd
  • 1,014
  • 6
  • 12