0
#include<stdio.h>
int main()
{
    int arr[3][4] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12};
    printf("%u ,%u\n",arr, &arr+1);
    return 0;
}

In the print statement: (Assuming integer size 4 bytes)
Let arr's memory location be 1000

arr+1--gives 1016 (ie.next row memory)

1000 1004 1008 1012 1016

1     2     3    4    5

&arr+1 gives 1048

I understood the logic but I can't understand that how the compiler identifies
arr as 'pointer to an array of 4 integer' and &arr as 'pointer to array of 3 arrays of 4 integer'

Even though both points to the same address (1000) before increment

2
  • arr decays to the same type as &arr[0], which is an array of 4 integers. &arr on the other hand is a pointer to array of 3 by 4 integers Commented Jun 23, 2021 at 16:25
  • 1
    &arr gives you a pointer to the array. arr gives you a pointer to the array's first element. Commented Jun 23, 2021 at 16:55

2 Answers 2

2

arr is a 3-element array of 4-element array of int.

Arrays in expressions are automatically converted to pointers pointing at the first element of the array (some exception exists). Therefore arr is converted to a pointer pointing at its first element. The type of the first element is "a 4-element array of int, so arr is converted to "a pointer to a 4-element array of int" (int(*)[4]).

Operand of unary & (address) operator is one of the exceptions. arr is a 3-element array of 4-element array of int, so &arr is "a pointer to a 3-element array of 4-element array of int".

Note that the line

printf("%u ,%u\n",arr, &arr+1);

invokes undefined behavior by passind data having wrong type to printf(). %u expects unsigned int. You should cast the pointer to void* and use %p to print pointers like this:

printf("%p ,%p\n",(void*)arr, (void*)(&arr+1));

Alternatively, you can convert the pointers to integers (in an implementation-defined manner) and print them.

#include<stdio.h>
#include<inttypes.h>
int main(void)
{
    int arr[3][4] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12};
    printf("%" PRIuPTR " ,%" PRIuPTR "\n",(uintptr_t)arr, (uintptr_t)(&arr+1));
    return 0;
}
Sign up to request clarification or add additional context in comments.

Comments

1

Arrays designates used in expressions with rare exceptions are converted to pointers to their first elements.

So the array arr declared like

int arr[3][4] = { /*...*/ };

is converted to pointer to its first element when it is used as an argument of a call of printf. The type of the array element is int[4]. So a pointer to an object of this type has the type int ( * )[4].

On the other hand the expression &arr has the type int ( * )[3][4]. Incrementing the pointer like &arr + 1 yields the value that greater than the value of the expression &arr by sizeof( int[3][4] ) (that is equal to 12 * sizeof( int )).

Pay attention to that you have to use the conversion specifier %p to output values of pointers.

printf("%p ,%p\n", (void * )arr, ( void * )( &arr+1 ) );

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.