In this expression a[1]+1
there is used the pointer arithmetic.
The sub-expression a[1]
having the array type int[3]
is implicitly converted to pointer to the array element type that is to pointer of the type int *
. So the whole expression has the type int *
. And this call of printf
printf("sizeof(a[1]+1): %zu\n", sizeof(a[1]+1));
outputs the size of a pointer of the type int *
.
In this expression a+1
where there is also used the pointer arithmetic the array designator a
having the array type int[3][3]
is implicitly converted to pointer to its element type int ( * )[3]
. And the full expression has this type.
So this call of printf
printf("sizeof(a+1): %zu\n", sizeof(a+1));
also outputs the size of a pointer.
If you need to get the size of the whole array you can write
printf("sizeof(a): %zu\n", sizeof(a));
If you want to output the size of its elements you can write
printf("sizeof(a[0]): %zu\n", sizeof(a[0]));
or
printf("sizeof(*a): %zu\n", sizeof(*a));
It seems you do not understand the pointer arithmetic as for example in this your statement
sizeof(a+1): 72 //sizeof(a) + sizeof(a) (36 + 36)
This expression
sizeof(a+1)
is not the same as the expression suzeof( a ) + sizeof( a )
.
The compiler determines the type of the expression a + 1
that has the type int ( * )[3]
as pointed above and yields the size of an object of this type.
I think this quote from the C Standard (6.3.2.1 Lvalues, arrays, and function designators) will be useful for you
3 Except when it is the operand of the sizeof operator or the unary &
operator, or is a string literal used to initialize an array, an
expression that has type ‘‘array of type’’ is converted to an
expression with type ‘‘pointer to type’’ that points to the initial
element of the array object and is not an lvalue. If the array object
has register storage class, the behavior is undefined.
So for example sizeof( a )
yields the size of the whole array. In this expression the array designator does not implicitly converted to pointer to the array element type.
However if you will write instead sizeof( a + 0 )
then in this expression a + 0
the array designator will be converted to pointer to the array element type and the operator sizeof
yields the size of pointer.