2

I am learning C programming by myself, and stuck with this practice

int a[] = {5,7,9,11,13};
int *p;
int i = 2;
p = a;
*(p++) = ++i;
printf("%d %d %d %d", a[0], a[i++], *p, *(p+2));
// output: 3 11 7 11

My understanding is that

1.define an array a and initialise it with values 5,7,9,11,13

2.define pointer p

3.define i and initialise it with value 2

4.p points to array a

5.p[1] = 3;

  1. a[0] = 5, a[3] = 11, *p = p[0] = 5, *(p+2) = p[2] = 9

//output: 5 11 5 9

But they are totally wrong !

I may need detailed explanation for this.

Please help me and many thanks!

alk
  • 69,737
  • 10
  • 105
  • 255
jetsai
  • 105
  • 6
  • 3
    `p++` is not the same as `++p`. – Ajay Brahmakshatriya Oct 29 '18 at 16:01
  • Could you explain more clearly based on this question? – jetsai Oct 29 '18 at 16:08
  • OT: [In C "declaring" and "defining" not necessarily is the same](https://stackoverflow.com/questions/1410563/what-is-the-difference-between-a-definition-and-a-declaration). All your examples in fact "define" and not just *only* "declare". I adjusted your question accordingly. – alk Dec 08 '18 at 10:45

4 Answers4

3

Your understanding is correct till 3.

4 - p points to the first element of a.

5 - You are using the post increment operator. So p's old value will be used and p will be incremented (meaning p will now point to the second element in a). So this is equivalent to p[0] = i + 1; p = p + 1; i = i + 1; At this point p is pointing to the second element of a and the first element of a is changed to 3. i is also 3 at this point.

  1. a[0] = 3, a[i++] = a[3] = 11, *p = a[1] = 7, *(p+2) = a[3] = 11.

This is exactly the output you get - See here.

Ajay Brahmakshatriya
  • 8,993
  • 3
  • 26
  • 49
  • So " *(p++) = ++i; " means that p[0] = 3 ( a[0] = 3 ) and then p move forward to a[1]. Am I right? – jetsai Oct 29 '18 at 16:14
2

For the line *(p++) = ++i; This sets the value of a[0] to 3. Note since ++ is after p, it evaluates p = p + 1 after the expression.

a[i++] is a[3] which is 11. Note we start from 0 when counting.

We incremented p in the line *(p++) = ++i; therefore p points to a[1] which is 3.

Lastly *(p+2) means that p now points to a[3] which is 11.

There you have it 3 11 7 11

0

This

int a[] = {5,7,9,11,13};
p = a;

looks like below

 ---------------------------------
 |  5  |  7  |  9  |  11  |  13  |
 ---------------------------------
 0x100  0x104  0x108 ..(lets assume bas address of a is 0x100)
 a
 p <-- p pints to base address of a

Next when you do like

*(p++) = ++i; /* ++i means 3 */

p++ results in same(post increment rule) address in this expression so 3 got assigned to 0x100 memory location, in the next iteration p points to 0x104 memory location, so now array a looks like below

 -----------------------------------------
 |  3(5<--old)  |  7  |  9  |  11  |  13  |
 -----------------------------------------
 0x100          0x104  0x108 ..
 a               |
                 p <-- p points here

Next when the below printf() executes as below

printf("%d %d %d %d", a[0], a[i++], *p, *(p+2));

lets solve one by one

*(p+2) == *(0x104 + 2*4)
        == 11 (prints 11)

And then *p yields in 7 as p points to 0x104 memory location.

and

a[i++] yields in a[3] i.e 11 but for next expression i becomes 4.

and

a[0] prints 3 as I pointed in above figure. hence it prints

3 11 7 11.

Side note, function parameters are not evaluated in a defined order in C, read this.

Achal
  • 11,821
  • 2
  • 15
  • 37
0

This line

*(p++) = ++i;

uses a mix of pre- and post-increments. When you have trouble understanding such code, you should rewrite the code so that only a single thing happens in each line.

In this case it can be rewritten to:

i = i + 1;   // From ++i which is the pre-increment, i.e. increment first and
             // then use the new value

*p = i;      // The assignment without pre/post increments

p = p + 1;   // From p++ which is the post-increment, i.e. use the current value and
             // then increment afterwards

Now you have 3 simple statements that makes it easier to understand the code.

Support Ukraine
  • 42,271
  • 4
  • 38
  • 63