Reversing a '\0' terminated C string in place?
c, dereference, pointers, reverse
Solution
Lots of questions... trying to capture answers to each:
/* does *str = opal or does *str = o since the pointer str is type char? */
`*str` is `'o'` since it points at the first character
/* what is the difference between char* end and char *end? and is *end pointing to opal now? */
There is no difference between `char *end` and `char* end`. It gets trickier when you write
char* a, b;
since this is equivalent to
char *a, b;
and not, as you might think
char *a, *b;
This is why it's cleaner to write `char *end;`.
And `end` is pointing to `opal` now - `*end` is `'o'`.
if (str) { /* if str isn't null? */
Yes - testing that you did not get passed a NULL pointer
To test that you did not get passed a string of length 0, you would have to test `*str` (after testing that `str` is not NULL, otherwise you get a segmentation error for "daring to look at *NULL")
while (str < end) { /* why not *str < *end? is this asking while o < l? */
Testing the pointers - one is moving towards the end, the other is moving back. When you meet in the middle you stop; otherwise you do the swap twice, and there will be no net effect...
*str++ = *end; /* what is the difference between *str++ and ++str? does *str++ = l? */
You first copy the value of `*end` to `*str`, then you increment the `str` pointer. If you put `++str`, you increment first, then use it. And that would mean that you put the `l` in place of the `p` instead of in place of the `o`.
edit one critique on your code (going beyond the questions you asked, and responding to a comment from @chux): when you test for `if(str){}` you really need an `else return;` statement, since you actually do `end--;` and then use `*end`. Pretty sure that `0xFFFFFFFFFFFFFFFF` is almost always an invalid address...
If you in fact were testing for `if(*str!='\0')` then you should still just return (an empty string is "irreversible" - or rather, it doesn't need anything to be considered reversed).
By the way, I much prefer making the condition explicit (like I did just then); not only does it show your intention more clearly, but the compiler might actually complain if you did `if(str!='\0')` or `if(*str != NULL)` since the types you are comparing are incompatible. This means you will have code that is more robust, more readable, and more likely to do what you intended.
Problem
I have some conceptual questions about reversing a null terminated C string, and clarification questions about the nature of pointers. The input might be ``` char arr[] = "opal"; ``` and the code: ``` void reverse(char *str) { /* does *str = opal or does *str = o since the pointer str is type char? */ char* end = str; /* what is the difference between char* end and char *end? and is *end pointing to opal now? */ char tmp; if (str) { /* if str isn't null? */ while (*end) ++end; } --end; /* end pointer points to l now */ while (str < end) { /* why not *str < *end? is this asking while o < l? */ tmp = *str; /* tmp = o */ *str++ = *end; /* what is the difference between *str++ and ++str? does *str++ = l? */ *end-- = tmp; /* *end points to o */ } } } ```