int array[3] = {1,2,3}
allocates an array that can hold at most 3 integers and you can access any of them using the following ways:
array[0]
array[1]
array[2]
Here:
char array[3] = "123"
"123" consist of 4 bytes. The characters in the string literal ends with a NUL-terminator. But you allocate 3 bytes and can atmost hold 2 characters (+1 for the NUL-terminator). So, when you initialize the array with it, the '\0' is not written as there is no space.
When you print this using %s in a printf, it invokes Undefined behavior as %s prints everything until a NUL-terminator. So, the printf goes on reading values from invalid memory locations until a '\0'. Anything can happen when you do this. You might see random garbage getting outputted, crashes, segmentation faults etc. Basically, you should never rely on this behavior, even if it seemed to have "worked" as expected.
but doesn't array start from 0
Yes
so char array[3] is enough since it actually 4 space
Wrong. The valid indices for char array[3] are
array[0]
array[1]
array[2]
accessing array[3] is wrong and it invokes Undefined Behavior.
Fix the issue by using
char array[4] = "123";
or better:
char array[] = "123";
The empty brackets tell the compiler to determine the size of the array.