It's called undefined behavior
With undefined behavior anything may happen. It may print 1, 3, 4
but it could also print 42, 42, 42
or the program could crash or your computer could turn off or.... anything
The only valid access is a[0]
but the others are just invalid (aka undefined behavior).
A pointer in C points to one element that you can access using either *pointer
or pointer[0]
.
The C language also allows you to access *(pointer + 1)
or pointer[1]
. In that case the compiler expect that you have an array of element. And.. if you don't it's your problem - the compiler kind of trust that you know what you are doing and just generates the equivalent code.
So if you do it wrong (like in your posted code) the compiler won't notice. You just end up with a program that has undefined behavior.
The reason that your code is wrong is that a[1]
will access the memory just after a[0]
(which is b
) and expect that another int
is located there. And that expectation doesn't hold for your program. Maybe it's true and maybe c
is actually located in the memory just after b
but there is no guarantee for that. The compiler may place the variables in memory in any order so we can't tell what the memory after b
(aka a[0]
) contains. So reading it by doing a[1]
is just undefined behavior... we won't know what will happen.
To make things even more "strange"... perhaps c and e isn't present in memory.... in fact that's highly likely for your code...