0

This function is reversing the the order of chars in a given string. Its called by inputing its start and end pointers. for example the function called like so

reverse(str, str + strlen(str));

I don't understand why the while condition works, or more precisely what are we comparing by (start<--end).

void reverse(char* start, char* end)
{
while (start < --end)
swap(start++, end);
}
kal_elk122
  • 143
  • 6
  • 1
    It's comparing pointers = the addresses being pointed to. (is it higher or lower in memory) –  Mar 16 '21 at 13:08
  • Thank you! so pointers can be compared using their names like that? how do we know its pointers and not start[a] and end[b] being compared? – kal_elk122 Mar 16 '21 at 13:14
  • 1
    It's not your question, but this program exhibits undefined behavior when asked to reverse the empty string because `end` is decremented off the front end of the string. – Paul Hankin Mar 16 '21 at 13:15
  • 1
    Not sure I understand the point about start[a]... If you want to know more about this part of the language, the key word is [pointer arithmetic](https://www.tutorialspoint.com/cprogramming/c_pointer_arithmetic.htm). –  Mar 16 '21 at 13:17
  • so had I needed to improve upon the program is it better to write with end-- rathar than --end ? – kal_elk122 Mar 16 '21 at 13:17
  • Thank you. I will look it up! – kal_elk122 Mar 16 '21 at 13:18
  • 1
    `a < b` compares `a` and `b`. Here `a` and `b` are pointers, so it compares the pointers. The meaning of operators is defined reasonably clearly in the C standard. See section 6.5.8.5 – Paul Hankin Mar 16 '21 at 13:18
  • 1
    Just replacing --end with end-- would not work properly for various reasons. If you're worried about this case, add an if before the loop. I would avoid the whole thing as "clever but unreadable". Reading code is hard enough without having to wonder "what the hell does this do?". And this is not a usual idiom. –  Mar 16 '21 at 13:23
  • 1
    Calling this function with a single-character string also exhibits undefined behaviour for the same reason as the empty string (`end` gets decremented off the front of the string). That suggests why this kind of clever code (with inline increments and decrements) are avoided by most seasoned C programmers - it's easy to write subtly wrong code. – Paul Hankin Mar 16 '21 at 13:23
  • @3limin4t0r You don't need to dereference the pointer to get undefined behavior. Section 6.5.6.8 of the C standard says of addition of a pointer and an integer value to produce a result: `If both the pointer operand and the result point to elements of the same array object, or one past the last element of the array object, the evaluation shall not produce an overflow; otherwise, the behavior is undefined.` – Paul Hankin Mar 16 '21 at 14:00
  • @3limin4t0r I think you're arguing that "not (A and B)" means"(not A) and (not B)", but here's a Q+A for this: https://stackoverflow.com/questions/30512669/does-applying-post-decrement-on-a-pointer-already-addressing-the-base-of-an-arra – Paul Hankin Mar 16 '21 at 14:29
  • @3limin4t0r My observation of this program is that in the single- and zero- length string case, the `end` pointer is decremented to before the first element of the string. You've switched to talking about the last element of an array (and quoting text about pointers to one after the last element of the array). – Paul Hankin Mar 16 '21 at 14:36
  • @3limin4t0r I quoted that section because if the operand points to the start of the array, and the result points to one before the start of the array then this clause is false: "the pointer operand and the result point to elements of the same array object, or one past the last element of the array object". – Paul Hankin Mar 16 '21 at 14:43

2 Answers2

3

The prefix -- operator subtracts one from the operand and evaluate to the value after subtraction.

Therefore, the condition start<--end is checking if start is less than end - 1 and update the value of end to end - 1.

MikeCAT
  • 73,922
  • 11
  • 45
  • 70
3

start and end are pointers to the start and end of the string. start + strlen(str) is actually one character past the last character to be swapped, so end is decremented before being compared, while start is incremented after. The reverse is done when the two pointers meet in the middle of the string. The null byte at the end of the string is retained.

stark
  • 12,615
  • 3
  • 33
  • 50
  • I see. I didn't notice that, thank you. I am still bothered by what specifically are we comparing - are we comparing indexes? ascii values? I don't think I understand the syntax of the comparison. – kal_elk122 Mar 16 '21 at 13:11
  • As I said, start and end are pointers, so `start < --end` is comparing that `start` and `end` have not met each other at the middle of the string. The values in `start` and `end` are addresses of locations in the string. – stark Mar 16 '21 at 14:10
  • @3limin4t0r Clarified. – stark Mar 16 '21 at 14:16