C语言逆波兰计算器中*s++与*++s的运算符优先级及赋值行为差异疑问
*s++ = c and *++s = c in Your RPN Calculator Let’s break this down step by step—your confusion is totally valid, since postfix vs prefix increment combined with pointer dereferencing can be tricky to parse at first.
First: The Core Difference in Expression Execution
Let’s start with the fundamental behavior of these two expressions, since that’s the root of your bug.
1. *s++ = c (Postfix Increment)
This expression executes in three key steps:
- Use the current value of
s: The dereference operator*acts on the current pointer address stored ins. - Assign the value: Write
cto the memory location thatscurrently points to. - Increment the pointer: After the assignment is complete, increment
s(move it to the next memory address).
In plain code terms, this is exactly equivalent to:
// *s++ = c; char *temp = s; // Save the current pointer position *temp = c; // Assign c to the current location s = s + 1; // Move the pointer forward AFTER assignment
2. *++s = c (Prefix Increment)
This expression reverses the order of pointer movement and assignment:
- Increment the pointer first: Move
sto the next memory address immediately. - Assign the value: Write
cto the new memory location thatsnow points to.
Equivalent plain code:
// *++s = c; s = s + 1; // Move the pointer forward FIRST *s = c; // Assign c to the new location
Why This Broke Your RPN Calculator
Now let’s tie this back to your getop function, where the bug occurred. Let’s recap the relevant code flow:
First, you skip whitespace and read the first non-space character into
s[0]:while ((*s = c = getch()) == ' ' || c == '\t') ;At this point, if
cis a digit, it’s already stored in the first position of your buffer (s[0]).Next, you enter the loop to read subsequent digits:
if (isdigit(c)) { // Original (broken) code: while (isdigit(*s++ = c = getch())) ; // Fixed code: // while (isdigit(*++s = c = getch())) ; }
What Went Wrong with *s++ = c
When you used *s++ = c in the loop:
- The first iteration of the loop reads a new character with
getch(), then writes it tos[0](overwriting the first digit you already stored there!), then incrementssto point tos[1]. - By the end of the loop, your buffer has lost the first digit entirely—for example, inputting
123would result in23being stored in the buffer. This corrupted number is why your calculator produced incorrect results.
Why *++s = c Fixed It
With the fixed code:
- The first iteration increments
sto point tos[1]first, then writes the new character tos[1](leaving the original first digit ins[0]intact). - Subsequent iterations continue moving the pointer forward and appending digits to the buffer, so
123is stored correctly ass[0] = '1',s[1] = '2',s[2] = '3'.
Correcting Your Equivalent Logic
Quick note: Your earlier attempt to write equivalent loop logic had a small error. Here’s the accurate breakdown for each loop:
Equivalent for while (isdigit(*s++ = c = getch()))
while (1) { c = getch(); *s = c; // Assign to current s position FIRST s++; // Then move pointer if (!isdigit(c)) { break; } }
Equivalent for while (isdigit(*++s = c = getch()))
while (1) { c = getch(); s++; // Move pointer FIRST *s = c; // Assign to new position if (!isdigit(c)) { break; } }
The key difference here is when the pointer is moved relative to the assignment—this is exactly what caused your calculator to behave incorrectly.
内容的提问来源于stack exchange,提问作者neil guo

