Search code examples
arrayscmemory-addresspointer-arithmetic

How does subtracting an address reference work?


I think the value of z should be 40 because a[5] has 20 elements, and the space between it and a[3] also has 20 elements. However, the actual value of z is 2.

Can anyone explain this concept?

#include <stdio.h>

int main()
{
    int a[10][20];
    int z = &a[5] - &a[3];
    printf("%d\n", &a[3]); // the address information is 6421740
    printf("%d\n", &a[5]); // the address information is 6421900
    printf("%d\n", z);     // z value is 2. why?
}

Solution

  • According to the C Standard (6.5.2.1 Array subscripting)

    2 A postfix expression followed by an expression in square brackets [] is a subscripted designation of an element of an array object. The definition of the subscript operator [] is that E1[E2] is identical to (*((E1)+(E2))). Because of the conversion rules that apply to the binary + operator, if E1 is an array object (equivalently, a pointer to the initial element of an array object) and E2 is an integer, E1[E2] designates the E2-th element of E1 (counting from zero).

    So the expression a[3] is evaluated like *( a + 3 ). As a result the expression &a[3] is equivalent to the expression &*( a + 3 ) that in turn is equivalent to ( a + 3 ).

    The same way the expression &a[5] is equivalent to the expression ( a + 5 ).

    So the difference &a[5] - &a[3] is evaluated like ( a + 5 ) - ( a + 3 ) that yields 2. That is between these two addresses &a[5] and &a[3] there are only two elements of the type int[20].

    On the other hand if you would write ( int * )&a[5] - ( int * )&a[3] that is if the array would be interpreted as a one-dimensional array of the type int you would get 2 * 20 that yields the expected by you value 40.