7

Given the definition of an array in C: int a[2][3][4][5], and the address of a[0][0][0][0] is 1000 what is the address of a[1][1][1][1], assuming an int occupies 4 bytes.

I got:

(3*4*5 * 4bytes) + (4*5 * 4bytes) + (5* 4bytes) + 4bytes = 344

344 + 1000 = 1344 Location of a[1][1][1][1]

but I have no idea if I'm right. But my math seemed sound to me.

Schwarz
  • 395
  • 4
  • 18

3 Answers3

4

Just print the adress of the variable any you will see it!:

#include <stdio.h>  

int main() {

    int a[2][3][4][5];

    printf ("Size of int %d\n", sizeof(int));

    printf("Adress of the frist element \t%p\n", &a[0][0][0][0]);
    printf("Adress of x element \t\t%p\n", &a[1][1][1][1]);

    printf ("In decimal: \t\t\t%d\n", &(a[0][0][0][0]));
    printf ("In decimal: \t\t\t%d\n", &(a[1][1][1][1]));

    printf("Difference between the adresses %d", (char *)&a[1][1][1][1] - (char *)&a[0][0][0][0]);




    return 0;

}

After that you can check if you where right!

And as you see your right! it's 334

Rizier123
  • 58,877
  • 16
  • 101
  • 156
  • Your second `printf` give the address of `a[1][1][1][0]`, not `a[1][1][1][1]`. Why not be straightforward about what you are trying to do and write `&a[0][0][0][0]`? – Red Alert Nov 13 '14 at 01:36
  • `%d` with a pointer is problematic (especially if int is 32bit and pointer is 64bit) , consider using [uintptr_t](http://stackoverflow.com/questions/5795978/string-format-for-intptr-t-and-uintptr-t) – M.M Nov 13 '14 at 02:00
  • Pardon me if I am wrong, but in the first example is all the referencing and dereferencing really needed? Surely `&a[0][0][0][0]` is just `a`? – Vality Nov 13 '14 at 02:12
  • @Vality I have it made for more clarity! But your right! – Rizier123 Nov 13 '14 at 02:14
3

Your math is correct. You can check by subtracting the two addresses, but don't forget that pointer arithmetic will recognize the type size, so you have to cast the addresses to char which has a size of a byte:

( char* )&a[1][1][1][1] - ( char* )&a[0][0][0][0]

which gives the difference in bytes. Then just add the starting address and you have your answer.

2501
  • 25,460
  • 4
  • 47
  • 87
0

Something like that is fairly simple to check (a):

#include <stdio.h>

int main (void) {
    int a[2][3][4][5];

    // Ignore incorrect format specifiers for now.

    printf ("%d\n", sizeof(int));
    printf ("%d\n", &(a[0][0][0][0]));
    printf ("%d\n", &(a[1][1][1][1]));
    printf ("%d\n", (int)&(a[1][1][1][1])
                  - (int)&(a[0][0][0][0])
                  + 1000);

    return 0;
}

and the output of that is:

4
2665056
2665400
1344

Note the conversions of the pointers to int values in that final printf. Without this, the 1000 would be scaled as an int *, giving the wrong value.

So, yes, bottom line, your reasoning is correct.


(a) That's not always the case since some aspects of the C language can differ across implementations (implementation-specified behaviour) or in any way they want (undefined behaviour).

Happily, layout of arrays is specified specifically by the standard, in C11 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).

3/ Successive subscript operators designate an element of a multidimensional array object. If E is an n-dimensional array (n >= 2) with dimensions i * j * ... * k, then E (used as other than an lvalue) is converted to a pointer to an (n − 1)-dimensional array with dimensions j * ... * k. If the unary * operator is applied to this pointer explicitly, or implicitly as a result of subscripting, the result is the referenced (n − 1)-dimensional array, which itself is converted into a pointer if used as other than an lvalue. It follows from this that arrays are stored in row-major order (last subscript varies fastest).

Community
  • 1
  • 1
paxdiablo
  • 854,327
  • 234
  • 1,573
  • 1,953
  • 1
    that output seems strange, `2665400 - 2665056 + 1000` is not `1086`. I imagine the compiler thinks you are trying to do pointer arithmetic. – Red Alert Nov 13 '14 at 01:46
  • 1
    @RedAlert, yes, just noticed that, and you'd think someone with as much C under their belt as me would know that up front :-) Modified to fix. – paxdiablo Nov 13 '14 at 01:50