Marko Nesovic
Marko Nesovic

Reputation: 31

Beginner C arrays and incrementation

Excuse the amateurism but I'm really struggling to understand the basic incrementing mechanisms. Are the comments correct?

#include <stdio.h>

main()
{
int a[5]={1,2,3,4,5};
int i,j,m;
i = ++a[1]; // the value of a[1] is 3. i=3
j = ++a[1]; /* because of the previous line a[1]=3 
and now a[1]=4? but not in the line defining i? */
m = a[i++];  /* i retained the value of 3 even though the value of a[1] has changed
so finally i++ which is incremented in printf()? */
printf("%d, %d, %d", i,j,m);    
}

I could be answering my own question but I have fooled myself quite a few times learning C so far.

Upvotes: 1

Views: 74

Answers (2)

John Bode
John Bode

Reputation: 123448

The thing to remember with the ++ and -- operators is that the expression has a result and a side effect. The result of ++i is the original value of i plus 1. The side effect of ++i is to add 1 to the value stored in i.

So, if i is originally 0, then in the expression

j = ++i

j gets the result of 0 + 1 (the original value of i plus 1). As a side effect, 1 is added to the value currently stored in i. So after this expression is evaluated, both i and j contain 1.

The postfix version of ++ is slightly different; the result of i++ is the original value of i, but the side effect is the same - 1 is added to the value stored in i. So, if i is originally 0, then

j = i++;

j gets the original value of i (0), and 1 is added to the value stored in i. After this expression, j is 0 and i is 1.

Important - the exact order in which the assignment to j and the side effect to i are executed is not specified. i does not have to be updated before j is assigned, and vice versa. Because of this, certain combinations of ++ and -- (including but not limited to i = i++, i++ * i++, a[i++] = i, and a[i] = i++) will result in undefined behavior; the result will vary, unpredictably, depending on platform, optimization, and surrounding code.

So, let's imagine your objects are laid out in memory like so:

   +---+
a: | 1 | a[0]
   +---+
   | 2 | a[1]
   +---+
   | 3 | a[2]
   +---+
   | 4 | a[3]
   +---+
   | 5 | a[4]
   +---+
i: | ? |
   +---+
j: | ? |
   +---+
m: | ? |
   +---+

First we evaluate

i = ++a[1];

The result of ++a[1] is the original value of a[1] plus 1 - in this case, 3. The side effect is to update the value in a[1]. After this statement, your objects now look like this:

   +---+
a: | 1 | a[0]
   +---+
   | 3 | a[1]
   +---+
   | 3 | a[2]
   +---+
   | 4 | a[3]
   +---+
   | 5 | a[4]
   +---+
i: | 3 |
   +---+
j: | ? |
   +---+
m: | ? |
   +---+

Now we execute

j = ++a[1];

Same deal - j gets the value of a[1] plus 1, and the side effect is to update a[1]. After evaluation, we have

   +---+
a: | 1 | a[0]
   +---+
   | 4 | a[1]
   +---+
   | 3 | a[2]
   +---+
   | 4 | a[3]
   +---+
   | 5 | a[4]
   +---+
i: | 3 |
   +---+
j: | 4 |
   +---+
m: | ? |
   +---+

Finally, we have

m = a[i++];

The result of i++ is 3, so m gets the value stored in a[3]. The side effect is to add 1 to the value stored in i. Now, our objects look like

   +---+
a: | 1 | a[0]
   +---+
   | 4 | a[1]
   +---+
   | 3 | a[2]
   +---+
   | 4 | a[3]
   +---+
   | 5 | a[4]
   +---+
i: | 4 |
   +---+
j: | 4 |
   +---+
m: | 4 |
   +---+

Upvotes: 3

haccks
haccks

Reputation: 106012

i = ++a[1] will increment the value of a[1] to 3 and the result of ++a[1] which is 3 will be assigned to i.

j = ++a[1]; will increment the value of a[1] to 4 and the result of ++a[1] which is 4 will be assigned to j.

m = a[i++];, will assign the value of a[3] (as i is 3 b now) to m which is 4 and i will be incremented by 1. Now i becomes 4.

Upvotes: 3

Related Questions