-5

Shouldn't the output of following program be -

2 3 20

instead it is showing

3 2 15

Can anyone explain the reason behind this?

#include<stdio.h>
main()
{
    int a[5] = {5,1,15,20,25};
    int i,j,m;
    i = ++a[1];
    j = a[1]++;
    m = a[i++];
    printf("%d %d %d",i,j,m);
}
Yu Hao
  • 119,891
  • 44
  • 235
  • 294
raesrem
  • 55
  • 4
  • 6
    `i = ++a[1]; j = a[1]++; m = a[i++];` why would anybody do that in real life ? Please, don't ask help for your homeworks. – blue112 Jul 20 '15 at 13:56
  • 3
    It would be helpfull (for you) to add the reasoning why you think `2 3 20` is the correct output. – A4L Jul 20 '15 at 14:01
  • 2
    I'm voting to close this question as off-topic because it's garbage homework code of no value. – Martin James Jul 20 '15 at 14:18

3 Answers3

7

3 2 15

is the correct output.

  1. i is 3, because i became 2 in i = ++a[1]; for pre-increment and then it got post-incremented in m = a[i++];
  2. j is 2, because j = a[1]++;, no changes afterwards.
  3. m is 15 because m = a[i++]; i is being post-incremented, the old value of i (which is 2) is used in indexing and the post-increment on i is sequenced after the evaluation of the = statement.

Having said that, the recommended signature of main() is int main(int argc, char *argv[]) or at least, int main(void).

Sourav Ghosh
  • 133,132
  • 16
  • 183
  • 261
  • The signature of `main` is completely correct in OPs code. He's using the implicit `int` rule and provides no argument list—thus allowing arbitrary arguments of arbitrary type. – fuz Jul 20 '15 at 14:08
  • 3
    @FUZxxl `implicit int rule` has been dropped since `C99`. and the signature I mentioned is recommended in the same standard. Just trying to make OP aware of the latest standard. Please note the **recommended** part. Hope it's clear. :-) – Sourav Ghosh Jul 20 '15 at 14:10
  • But OP is using the recommended signature, he is just defining his function in a way you don't recommend. – fuz Jul 20 '15 at 14:22
  • @FUZxxl Sir, I did not understand your point. And, the recommendation is not by me, it's by the standard. I'm just _repeating_ it. :-) – Sourav Ghosh Jul 20 '15 at 14:24
  • What I say is that OP follows the recommendations by the standard. A function defined `main() { ... }` is compatible to both `int main(int, char**)` and `int main(void)`. There is nothing wrong with this way of defining `main`. – fuz Jul 20 '15 at 14:25
  • @FUZxxl The fact that gcc yields a warning *return type defaults to int* should tell you that it is not really good style. Sure, it's not plain-dead wrong, but it's discouraged, to say the least. – Filipe Gonçalves Jul 20 '15 at 14:28
  • @FilipeGonçalves My point is that the reason why you shouldn't write `main() {...}` is wrong. It's not because it's the wrong signature, it's because you are using the implicit `int` rule which you shouldn't. – fuz Jul 20 '15 at 14:29
  • @FUZxxl Sir, my native is not English, so I'm not that good at understanding. May I please ask you to point me somewhere where this is explained in detail? I was relying on §5.1.2.2.1 from `C11`. – Sourav Ghosh Jul 20 '15 at 14:30
  • @SouravGhosh C11 does no longer contain the implicit `int` rule, but even C11 says that the definition needs only be *equivalent* to the given one (cf. footnote 10). – fuz Jul 20 '15 at 14:34
  • The definition `main() { ... }` declares `main` as a function returning `int`, not `void`. This is called the implicit `int` rule: If you leave out the type in certain contexts, such as in the return type of a function, `int` is assumed. – fuz Jul 20 '15 at 14:48
  • @FUZxxl absolutely agree. Sorry about `void` part, I must have mixed up my tabs with some other question. So as the implicit `int` is not supported by the standard any more, we need to be explicit. So, missing `int` is not really recommended, right? – Sourav Ghosh Jul 20 '15 at 14:56
  • @SouravGhosh No, implicit `int` is not recommended. – fuz Jul 20 '15 at 15:35
2

At this point, values of variables are:

a = {5,1,15,20,25};
i = uninitialized
j = uninitialized
m = uninitialized

Now,

i = ++a[1];

Gets the value of a[i] which is 1, increments it and it becomes 2, and then, it is stored in i.

At this point, values of variables are:

a = {5,2,15,20,25};
i = 2
j = uninitialized
m = uninitialized

Next,

j = a[1]++;

Gets the value in a[1] which is 2 (since it was incremented in the previous statement), stores this value in j and then, increments the value stored in a[1].

At this point, values of variables are:

a = {5,3,15,20,25};
i = 2
j = 2
m = uninitialized

Then,

m = a[i++];

Gets the value in a[i](a[2] since i is currently 2) which is 15 and this value is stored in m. Then, i is incremented.

At this point, values of variables are:

a = {5,3,15,20,25};
i = 3
j = 2
m = 15
Spikatrix
  • 20,225
  • 7
  • 37
  • 83
1
3 2 15 is correct

#include<stdio.h>

    main()
    {
    int a[5] = {5,1,15,20,25};
    int i,j,m;
    i = ++a[1];
    j = a[1]++;
    m = a[i++];
    printf("%d %d %d",i,j,m);
    }

Now lets go line by line assume i , j , m equals 0 {better to initialize}

from line 3 , i = ++a[1]; i = 2 as (++ pre increment , change then use , and a[1] = 1 so , i = 2)

from line 4, j = a[1]++; j = 2 as (++ here is post increment , use then change , a[1] becomes 3 but j is equals to 2)

from line 5, m = a[i++]; i = 2 by line 3 , here ++ post increment then i will increment to 3 but a[2] will be used .

Hence i = 3 , j = 2 , m = 15

Hope you got it ..........

Sohil Omer
  • 1,171
  • 7
  • 14