They are assigned as follows:
1 2 3 4 5 0
Zero is that you have allocated an array of size 6, but only 5 elements specified.
This is called "row order."
You can style your code a bit. Your code is currently:
int a[2][3] = {1,2,3,4,5};
If you compile this with gcc main.c -Wall -pedantic --std=c99 , you will get a few warnings:
temp.c: 2: 17: warning: missing curly braces around the initializer [-Wmissing-braces]
Allow this with
int a[2][3] = {{1,2,3,4,5}};
This will give you a new warning:
temp.c: 2: 25: warning: extra elements in the array initializer
Allow this using:
int a[2][3] = {{1,2,3},{4,5,0}};
This explicitly displays the data as having two rows of three elements.
Some thoughts on memory layout
int a[2][3] will create an "array of arrays". This is similar to, but contradictory, from an "array of pointers to arrays." Both have similar access syntax (e.g., a[1][2] ). But only for the "array of arrays" you can reliably access the elements with a+y*WIDTH+x .
Some codes may clarify:
#include <stdlib.h>
When you run this, you will get:
1 2 3 4 5 6 1 2 3 0 0 0
Printing b gives zeros (on my machine) since it runs in uninitialized memory. The result is that using continuous memory allows you to do convenient things, allowing you to set all values without the need for a double loop.