# [ACCEPTED]-what is `int *userMask[3][4]` pointing to?-pointers

Score: 43

``````int *userMask[3][4];
``````

then `userMask` has 35 type `int*[3][4]`. It's a 2d array of pointers to int. The 34 size of the outer dimension is 3, the size 33 of the inner dimension is 4. Really that 32 is nothing more than a 3-element 1d array 31 which element type is another 4-element 30 1d array which element type is `int*`.

## Steps explained

So if you 29 do

``````userMask[2][maskElement][user]
``````

then essentially with the first two indices 28 you pick the particular pointer out of the 27 2d array:

``````int * p = userMask[2][maskElement];
``````

then you pick an int somewhere 26 offset from that pointer by doing

``````p[user]
``````

now that 25 code is all in `userMask[2][maskElement][user]`.

## Valid C Code

To do it step by step with 24 valid c code (don't worry if you don't understand 23 everything yet in the following):

``````int * userMask[3][4] = { { 0 } };
int ** pa = userMask[2]; /* int*[4] becomes int** implicitly */
int i = pi[user];

``````

## Difference between Arrays and Pointers

So i think 22 i show you something important. The array 21 above does not contain pointers to arrays. Lets 20 look how different they behave, which many 19 c programmers don't expect:

``````int array[5][4][3];
/* int[4][3] implicitly converts to int(*)[3] (pointer to first element) */
int (*parray)[3] = array[0];
int ** pint = (int**) array[0]; /* wrong!! */
``````

Now, what will 18 happen if we do `parray[1]` and `pint[1]` ? The first will advance 17 parray by `sizeof(int[3])` bytes (`3 * sizeof(int)`), the second will advance 16 by only `sizeof( int* )` bytes. So actually while the first 15 gives you the correct array `array[0][1]`, the second 14 will give you `( char * )array[0] + sizeof( int* )`, which is somewhere we don't 13 really want it to be. But grabbing the wrong 12 offset is not all about it. Because it doesn't 11 know an array is accessed, it will try to 10 interpret what is at `pint[1]` as an `int*`. Say your array 9 was initialized with `0x00`. Then it will do the 8 next index step based off address 0x00 (Doing 7 `pint[1][0]` for example). Oh noes - utterly undefined 6 behavior! So it's really important to stress 5 the difference.

## Conclusion

This was more than you asked 4 for, but I think it's quite important to 3 know these details. Especially if you want 2 to pass 2d arrays to functions then this 1 knowledge is really useful.

Score: 18

This is a two-dimensional array where each 10 element is a pointer to an `int`, and all the 9 pointers are initialised to zero.

In your 8 follow-up, you show that the array is used 7 like this:

``````if(userMask[2][maskElement][user] && blah)
result = true;
``````

In this case, each element in 6 `userMask` should actually point to an array of `int`s. (An 5 `int*` can point to a single `int` or an array of `int`s). To 4 determine this, check the code that assigns 3 values to `userMask`. For example, it is possible 2 to write:

``````int userArray[2] = { 10, 20 };

// first element of userArray.
``````

Then the following code indexes 1 into `userArray`:

``````int value = userMask[0][0][1]; // sets value = userArray[1], giving 20.
``````
Score: 12
``````int *userMask[3][4] = {0};
``````

is a 2-dimensional array where each member 8 is a pointer to int. Additionally, all 7 members are initialized to null pointers.

``````int (*userMask)[3][4];
``````

would 6 be a pointer to a 2-dimensional array of 5 ints. Brackets in C bind tighter than * so 4 the parenthesis are needed to create a pointer 3 to an array.

`cdecl` is a simple utility you can 2 download to explain complex declarations:

``````cdecl> explain int *userMask[3][4]
declare userMask as array 3 of array 4 of pointer to int
``````

It 1 can also do the opposite:

``````cdecl> declare userMask as pointer to array 3 of array 4 of int
``````
Score: 3
``````if(userMask[2][maskElement][user] && blah)
result = true;
``````

The second part here is that there are no 8 arrays in C; there is only pointer arithmetic. By 7 definition, `p[i]` is always equivalent to `*(p+i)` so

``````userMask[2][maskElement][user]
``````

is 6 equivalent to

``````*((userMask[2][maskElement])+user)
``````

The code is somewhere assigning 5 a vector (I'd bet money it's from a malloc(3c) or 4 a similar call) to the pointer in that array; now 3 your if is saying

IF the user-th element of 2 the vector at userMask[2][maskElement] is 1 non-zero

THEN IF blah is non-zero (because of &&'s short circuit evaluation, the second conjunct doesn't get evaluated if the first conjunct is 0)

THEN set result = true.

Score: 2

Apply the inside-out rule.

``````int *userMask[3][4] = {0};
``````

Starting at the 7 innerpost part of the declaration,

``````userMask
``````

is the 6 name

``````userMask[3]
``````

allocates space for (is a vector of) 3 5 of them

``````userMask[3][4]
``````

allocates space for 4 `userMask[3]`'s

``````int *
``````

tells us 4 that `userMask` items are type pointer to `int`

and then 3 `= {0}` is an initializer where all elements are 2 `0`. So

``````int *userMask[3][4] = {0};
``````

is a 3x4 array of int *, initialized 1 to 0.

Score: 0

I think that statement accesses the third 7 row of the usermask array, then accesses 6 the maskElement'th pointer in that row, and 5 since that is an int pointer, it can point 4 to the beginning of an int array (think 3 character strings), which I assume it is 2 doing, and that array is sub-indexed by 1 user.

Score: 0

`userMask[2]` is of type `int*[]`,
`userMask[2][maskElement]` is of type `int*`,
and so `userMask[2][maskElement][user]` is of 3 type `int`.

The declaration

``````int *userMask[3][4] = {0};
``````

is shorthand for

``````int *userMask[3][4] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}};
``````

where 2 each of the zeros is implicitly converted 1 to `(int*)0`.

Score: 0

it helps if you read it like this:

``````type variablename[array_spec];
``````

in this 11 case: int* usermask[3][4];

so its a matrix 10 of int*.

now, since c does not differentiate 9 between pointer and arrays, you can use 8 array indexing on pointers.

``````int* i;
int the_int_behind_i = *(i+1);
int also_the_int_behind_i = i[1];
``````

This needs i 7 to point to an area where several ints are 6 lined up behind each other, of course, like 5 an array.

Note that the index operator[] used 4 in the last examples looks like the array_spec 3 in the first, but the two are quite different.