How to reverse a string using pointers. I don't understand any of the answers online. I need it to be explained really slowly.
For an assignment, I need to use pointers to reverse a string (and to use that to test if something is a palindrome), and I cannot for the life of me understand any of the answers to similar questions online. In this question, for instance, the top answer is:
void rev_string(char *str)
{
char *p = str, *s = str strlen(str) - 1;
while (p < s) {
char tmp = *p;
*p = *s;
*s-- = tmp;
}
}
This barely makes sense to me.
First of all, why is the input a char
when we're looking to reverse a string? The *
marks it as a pointer as well, right? Why is the input a pointer when we're looking to reverse a string?
I understand the first line of code with the variable initialization is meant to set pointer p
equal to the start of the string, and pointer s
to the tail of the string, but why?
I get the feeling that *p
and *s--
are supposed to go to the next letter or the previous letter of the string, respectively, but why does that work?
Please assist.
CodePudding user response:
I think the main problem with your example is that the coding style is bad. Good code is readable (another good lesson to learn today). The use of prefix and postfix , -- in the original code while correct do also not help in making clear what the code is doing. Another lesson is not to sacrifice readability for premature optimization like that. Compilers are smart and can optimize quite a bit of your input.
#include <iostream>
void reverse(char* input)
{
const std::size_t offset_of_last_character = strlen(input) - 1;
char* begin_pointer = &input[0]; // front_pointer now contains address of first character in string
char* end_pointer = &input[offset_of_last_character]; // end_pointer now contains address of last character in the string
while (begin_pointer < end_pointer) // as long as pointers don't cross-over in memory continue
{
// swap the characters pointed to
// first iteration this will be first and last character,
// second iteration this will be the second and the character and last but one character, etc...
std::swap(*begin_pointer, *end_pointer);
begin_pointer; // move one address up in memory, this is where the next character is found
--end_pointer; // move on address down in memory, this is where the previous character is found
}
}
int main()
{
char input[] = "!dlrow olleH";
reverse(input);
std::cout << input;
return 0;
}
CodePudding user response:
First of all, why is the input a
char
when we're looking to reverse a string? The*
marks it as a pointer as well, right? Why is the input a pointer when we're looking to reverse a string?
The code is C. A string in C is a NUL-terminated array of char
s. Thus a "hello" string is indeed a char str[6] = {'h', 'e', 'l', 'l', 'o', (char)0x00};
How do you pass this to a function? You pass the pointer char *
to the very first element of a string.
I understand the first line of code with the variable initialization is meant to set pointer
p
equal to the start of the string, and pointers
to the tail of the string, but why?
Because the function considers the input pointer to point at the start of a char
array with the aforementioned properties. Pointers p
and s
are meant to point inside the array. Pointer p
is initially set at the start of the array, pointer s
is initially set at a strlen(str) - 1
offset into the array. The offset is exactly where the last character in the array is.
I get the feeling that
*p
and*s--
are supposed to go to the next letter or the previous letter of the string, respectively, but why does that work?
The feeling is correct. These two are just pointers inside the array, they just travel along array's elements. This syntax used here says: "dereference the pointer, and right after the expression is done (may think compiler sees ;
) increment/decrement the pointer".
To finish it up. I really recommend the "C Programming Language" book to read. Strings in C, passing arrays to functions, and pointer arithmentics are what the given code is about.