Have you traced this by hand? You need to sit down, and go through every line on paper, and keep track of every variable at every step of the code. Yeah, it's a pain, and yeah, it uses a lot of paper, but being able to read through code is an absolute necessity as a programmer. Start by understanding your problem. Read through the following article: Reverse Polish notation - Wikipedia, the free encyclopedia.
I usually used (and reused) a single piece of paper for each function when I did this. I write down the parameters passed into the function and any input from the user at the top of the piece of paper. I then make boxes for each variable, so I can track their values at each point in the code. Basically, you are making yourself a human debugger, allowing yourself to step through each line of code and examine all relevant variables.
You should start with a paper for main, showing boxes for type, op2 and s. You don't need all 100 boxes for s, just 5 is sufficient for your example. The first thing that happens is getop is called, and passed s to store the first operator/operand. Take your "getop" paper, and make 5 boxes for s, and a box for i and c also. They're all uninitialized, so leave them empty. Now, start with the first while loop:
Code:
while ((s[0] = c = getch()) == ' ' || c == '\t')
;
That calls getch, which returns the next character in the input. Since it's our first call, we get the first '2', and assign that to c and to s[0]. Fill in the appropriate boxes. A '2' is not a space or a tab, so we're done with our loop. The next thing to do is
so put a '\0' in the second box for s. Now, on to our if statements:
Code:
if (!isdigit(c) && c != '.')
return c; /* not a number */
c is '2', so isdigit(c) will return true, and we skip the body of that if statement. Next:
Code:
i = 0;
if (isdigit(c)) /* collect integer part */
while (isdigit(s[++i] = c = getch()))
;
Write a 0 in the box for i. c is a digit, so we go into this loop body, and again, get the next character from our input. It's a space. We now put a ' ' in the box for c, and in the box for s[++i]. i was 0, but it gets pre-incremented (the ++ comes before the i), so i becomes 1 (change the box for i), and we put a space in s[1], replacing the '\0'. A space is not a digit however, so the isdigit call fails, and our loop is over. Next check:
Code:
if (c == '.') /* collect fraction part */
while (isdigit(s[++i] = c = getch()))
;
c is a space, not a '.', so skip this if statement. On we go:
Code:
s[i] = '\0';
if (c != EOF)
ungetch(c);
return NUMBER;
i is 1, so make s[1] a '\0', replacing the space we just put in there. c is a space, not EOF, so we put it back by calling ungetch, and return NUMBER.
EDIT: Fixed backwards if statement in previous sentence.
Egads! That was quite a process for just one function. Unfortunately, you need to do this for all the functions that get called, until you finish the program (when you return from main). Fortunately, after doing a few on paper, it becomes fairly easy to do this in your head, and it goes much quicker, especially for small functions like getop().
So we finished our first call to getop(). That takes us back into main, and back to our "main" paper. Put NUMBER in the box for type, then evaluate the switch(type) statement. Keep on until you finish processing the entire input, print an answer and return from main.