`i++`and

`++i`

I'm starting to read through Hacking: The Art of Exploitation on my four hours daily commute to work in order to get myself more comfortable working with C. I resolve a puzzle I have about C, as shown in the title.

`i++`means increment the value of`i`by`1`*after*evaluating the arithmetic operation.

```
int a, b;
a = 5;
b = a++ * 6;
```

`b` will contain `30` and `a` will contain `6`, since the shorthand of `b = a++ * 6`;
is the equivalent to the following statements:

```
b = a * 6;
a = a + 1;
```

`++i`means increment the value of`i`by`1`*before*evaluating the arithmetic operation.

```
int a, b;
a = 5;
b = ++a * 6;
```

`b` will contain `36` and `a` wil contain `6`, since the shorthand of `b = ++a * 6`; is the
equivalent to the following statement:

```
a = a + 1;
b = a * 6;
```

In fact, the two principles mentioned above apply more than "evaluating the arithmetic operation".
For example, in the stack `push` operation:

```
/* Push an element on the Stack
*/
void
push (ET elem, Stack S)
{
if (isFull(S))
{
resizeStack(S);
}
S->Array[++S->TopOfStack] = elem;
}
```

we can do `S->Array[++S->TopOfStack] = elem;`, which is equivalent with the following, a nice short verison:

```
S->Array[S->TopOfStack] = elem;
S->TopOfStack = S->TopOfStack + 1;
```

Another example is stack `topAndPop`:

```
/* Check the top element and pop it out of Stack
*/
ET
topAndPop(Stack S)
{
return S->Array[S->TopOfStack--];
}
```

In this case, we essentially do:

```
ET a = S->Array[S->TopOfStack];
S->TopOfStack = S->TopOfStack - 1;
return a;
```

Look how clean I can make my code is if I can understand the difference between `++i` and `i++`.

--- 01/19/2017 UPDATE ---

`++i` and `i++` is really a powerful technique to shorten the C code. However, it can be error-prune
if we are not careful enough.

Let's take a look at the following code snippet, which is adapted from the program on K & R p.117.

```
main(int argc, char* argv[])
{
while (--argc > 0 && (*++argv)[0] == '-')
while (c = *++argv[0])
switch (c)
{
case 'x':
printf ("user invokes the program with -x option\n");
break;
case 'n':
printf ("user invokes the program with -n option\n");
break;
default:
printf("illegal option %c\n", c);
argc = 0;
break;
}
if (argc != 1)
printf("Usage: find -x pattern\n");
}
```

This program itself is straightforward. Let's take a look at `(*++argv)[0]` to see what it means.
Since `argv` is a pointer to the beginning of the array of argument strings, incrementing it by
`1` (i.e. `++argv`) makes it point at the original `argv[1]` instead of `argv[0]`. Then we
dereference it to get the value of the argument string that we are currently looking at (i.e
`*++argv`). Now, we get its first character by adding `[0]`. So, we have `(*++argv)[0]`.
For example, we run our program with `a.out -x -n pattern`. Then our `argv` looks like
`{"-x", "-n", "pattern"}`. Then `argv[0]` is `"-x"`, `argv[1]` is `"-n"`, and so on.

The reason we need parenthesis in `(*++argv)[0]` can be seen in the next line `c = *++argv[0]`.
Since `[]` binds tighter than `*` and `++`, then `*++argv[0]` is equivalent with
`c = *++(argv[0])`. `argv[0]` points to the first char of the argument string that `argv` pointing
at. Then we increment and dereference `argv[0]` to get the next character in the argument string.
For instance, suppose `argv` pointing at `-x`. Then `argv[0]` pointing at `-` and we increment and
dereference `argv[0]` to get `x` and assign to `c`.

We can see that the level of precedence of operators is crtical in this case. This can be seen from table on p.53. in K & R:

Let's see another example from K & R p. 105.

```
void strcpy(char *s, char *t)
{
while ((*s++ = *t++) != '\0')
;
}
```

In this case, the value of `*t++` is the character that `t` pointed to before `t` was incremented; the
postfix `++` doesn't change `t` until after this character has been fetched. This makes sense if we
consider it from precedence of the operators' view. `*` and `++` have the same precedence in our table. Thus,
we evaluate the expression in ordinary order: from left to right. We first evaluate `*s` then we increment `s`.