-2

Take a look at this array:

const int *c000[64][1][3] =
{
//Row 1
{ {0, 0, 0} }, { {0, 0, 0} }, { {0, 0, 0} }, { {0, 0, 0} }, { {0, 0, 0} }, { {0, 0, 0} }, { {0, 0, 0} }, { {0, 0, 0} },

//Row 2
{ {0, 0, 0} }, { {0, 0, 0} }, { {0, 0, 0} }, { {0, 0, 0} }, { {0, 0, 0} }, { {0, 0, 0} }, { {0, 0, 0} }, { {0, 0, 0} },

//Row 3
{ {0, 0, 0} }, { {0, 0, 0} }, { {0, 0, 0} }, { {0, 0, 0} }, { {0, 0, 0} }, { {0, 0, 0} }, { {0, 0, 0} }, { {0, 0, 0} },

//Row 4
{ {0, 0, 0} }, { {0, 0, 0} }, { {0, 0, 0} }, { {0, 0, 0} }, { {0, 0, 0} }, { {0, 0, 0} }, { {0, 0, 0} }, { {0, 0, 0} },

//Row 5
{ {0, 0, 0} }, { {0, 0, 0} }, { {0, 0, 0} }, { {0, 0, 0} }, { {0, 0, 0} }, { {0, 0, 0} }, { {0, 0, 0} }, { {0, 0, 0} },

//Row 6*
{ {0, 0, 0} }, { {0, 0, 0} }, { {0, 0, 0} }, { {0, 0, 0} }, { {0, 0, 0} }, { {0, 0, 0} }, { {0, 0, 0} }, { {0, 0, 0} },

//Row 7
{ {0, 0, 0} }, { {0, 0, 0} }, { {0, 0, 0} }, { {0, 0, 0} }, { {0, 0, 0} }, { {0, 0, 0} }, { {0, 0, 0} }, { {0, 0, 0} },

//Row 8
{ {0, 0, 0} }, { {0, 0, 0} }, { {0, 0, 0} }, { {0, 0, 0} }, { {0, 0, 0} }, { {0, 0, 0} }, { {0, 0, 0} }, { {0, 0, 0} },
};

Ignore the strange size and structure of the array, that's not what is important. I need to be able to use an array inside this array. For example, I have an array called h002:

const int h002[18] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 0xe0, 0xe0};           //01

I need to be able to use h002 from inside c000. Such as:

{ {h002, 0, 0} },

This compiles just fine, however

myVar = c000[0][0][0];

retrieves the address of h002. I need the first item in h002, not the address. I'm confused as to why it would even give me the adress of h002 at all? I would imagine *h002 would retrieve the address, but then that doesn't compile at all.

I have seen several questions on SO that closely resemble mine, such as this one:

Creating an array of int arrays in C?

I have tried that particular example above. It works when I have it in my main.c file, but when I try it in the same .c file that c000 and h002 are contained in, it fails to compile. Perhaps this has something to do with it? I'm not sure why it would, considering using h002 inside c000 returns the address of h002 just fine. It's strange that the code presented in the link above wouldn't compile outside of my main file.

I feel like I'm making some kind of obvious, little mistake. I've been messing around with this off and on for about 5 days now. Trial and error and research has gotten me nowhere. Researching was difficult enough, as there doesn't seem to be much on using arrays like this, and none of my findings significantly helped me.

Feel free to ask questions. I'll be glad to specify more information if needed.

EDIT: Thanks so much to Stephan Lechner for helping me solve my issue. To get the result I needed, I had to do

myVar = *(c000[0][0][0]);

This works perfectly. I can also add whatever number I like at the end to retrieve different indexes in h002. For example:

myVar = *(c000[0][0][0] + 7); 

Hope this helps someone out in the future.

Community
  • 1
  • 1
  • `h002` represents the adress of your array, while `*hoo2` or `h002[0]` represents the value stored at the adress pointed at by `h002`. – m.raynal Jan 23 '17 at 18:02
  • Looks like I got that mixed up then. If that's the case, is there a reason why adding the pointer makes it so my program won't compile? –  Jan 23 '17 at 18:03
  • Maybe because c000 is not an `int` array, but an `int *` array ; try declaring it as `const int c000[64][1][3]` – m.raynal Jan 23 '17 at 18:06
  • I've tried that, that does not work. –  Jan 23 '17 at 18:16
  • 1
    @m.raynal "`h002` represents the adress of your array" - No! It represents a 1D array of `int`. An array is not a pointer! – too honest for this site Jan 23 '17 at 18:18
  • @Olaf So I guess I was correct then?? Man, I'm confusing myself. –  Jan 23 '17 at 18:20
  • You have a 3D array of pointers, what else do you expect to get if you access an element of the array? Note that you should use the `NULL` macro to initialise an entry to a null pointer. Alternitively you can use didcated initialisers to set only those entries you want to differ from null pointers and leave the rest for the implicit initialisation. However, while legal, `0` is not recommended to be used as null-pointer-constant. – too honest for this site Jan 23 '17 at 18:27
  • @olaf sorry for my misunderstanding ; a quick visit on a SO page explained me about the autoconversion I was unaware of. @Mr. Potatobadger : still, `h002` is definitly not an int, and `c000` is an array of `int *`, not an array of `int`. – m.raynal Jan 23 '17 at 18:28
  • @m.raynal: `c000` is not an array of `int *`, but `int *[64][1][3]`. – too honest for this site Jan 23 '17 at 18:30
  • You should get a compiler warning, compile with `-Wall -pedantic`. Also check [cdecl](http://cdecl.org/) if you're not sure what your declaration actually means – Elias Van Ootegem Jan 23 '17 at 18:31
  • @EliasVanOotegem I have no other compiler options other than what I'm using. I am developing for the Sega Saturn, so my options are incredibly limited. –  Jan 23 '17 at 18:41

2 Answers2

0

I think the basic misunderstanding is the meaning of const int *c000[64][1][3], which denotes a three dimensional array of pointers to int, but not a pointer to an 3D-array of integers. To demonstrate this, consider the following simplified examples together with compiler warnings:

int aSingleIntValue = 10;  // integer value
int *aSinglePtrToIntValue = &aSingleIntValue;  // pointer to an integer value

// 1D-array of integer values
int oneDArrayOfInt[5] = { 3,4,5,6,7 };

// 1D-array of pointers to int; Note: OK, since 0 is interpreted as NULL
int *oneDArrayOfIntPtrOK[5] = { aSinglePtrToIntValue,0,0,0,0 };

// 1D-array of pointers to int; Note: 3,4,.. are int values, not pointers to int; Hence compiler complains:
// Warning: Incompatible integer to pointer conversion initializing "int *"  with an expression of type "int"
int *oneDArrayOfIntPtrWarning[5] = { 3,4,5,6,7 };

// 3D-array of pointers to int; Note: OK, since 0 is interpreted as NULL
int *threeDArrayOfIntPtrOK[5][5][5] = { { { aSinglePtrToIntValue,0,0 }, { 0,0,0} } };

// 3D-array of pointers to int; Warining: Incompatible integer to pointer conversion initializing "int *"  with an expression of type "int"
int *threeDArrayOfIntPtrWarning[5][5][5] = { { { 3,4,5 }, { 2,3,1} } };

Just for showing a different meaning: if one would like to declare a pointer to an array of 5 integers, this could be expressed as follows:

typedef int arrayOf5Int_t[5];
arrayOf5Int_t *arrayOf5IntPtr = &oneDArrayOfInt;

Given that, let's explain the meaning of

const int h002[18] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 0xe0, 0xe0};
const int *c000[64][1][3] = { { { h002, 0, 0 } } };

Note that an element of c000 is a pointer to an integer, and note that variable h002 used in the context of the array initialiser decays to a pointer to an integer (pointing to the first element of h002). This is pretty much the same as declaring const int* ptrToH002 = h002, and the following print out demonstrates that this is actually the same:

const int *elemAt0x0x0 = c000[0][0][0];
const int *ptrToH002 = h002;
int isTheSame = elemAt0x0x0 == ptrToH002;
printf("pointer elemAt0x0x0 == ptrToH002 is %s", (isTheSame ? "true" : "false"));
// Prints: pointer elemAt0x0x0 == ptrToH002 is true

Hence, it should be clear that myVar = c000[0][0][0] retrieves an address, and not an integer value or an integer array. The address points to the first element of array h002.

Stephan Lechner
  • 34,891
  • 4
  • 35
  • 58
  • So that means I should be able to reference h002 (&h002) and get its first element, correct? I do that, and it doesn't work, it still returns the address of h002. –  Jan 24 '17 at 00:50
  • 1
    If you reference something, e.g. by writing `&h002`, you will always get an address, never a value. If you want to access a value of an array, use indices, like `myValue = h002[0]`; If you want to access a value to which you hold a pointer, dereference the pointer, e.g. `myValue = *ptrToH002` - note that `ptrToH002` points to the first element of array `h002`. OK? – Stephan Lechner Jan 24 '17 at 01:03
  • Ok, I understand. So let's say my c001 array is the same as in my original post, but I have the h002 as h002[0]. This compiles fine, however I am still getting an address, not the element. What then? –  Jan 24 '17 at 01:08
  • 1
    Let your code as in your post and try `int myVar = *(c000[0][0][0])` - this should give you `1`. – Stephan Lechner Jan 24 '17 at 01:10
  • Yes!! This is exactly what I was looking for! Oh man, thank you so much! –  Jan 24 '17 at 01:16
-2

Example of multidimensional array:

int main(){
    int a1[] = {1,2,3,4};
    int a2[] = {5,6,7,8};
    int a3[] = {9,10,11,12};
    int * superArr[3] = {a1,a2,a3};
    printf("%d\n", superArr[2][1]);
}

You should be able to change your code to what you need using this example.

user3853544
  • 581
  • 3
  • 9
  • 1
    First of, this is tagged `c`, not `c++`. Second, this is not a multidimensional array. – EOF Jan 23 '17 at 18:04
  • Now its C, thank you. You will find that two dimensions is in fact multidimensional. – user3853544 Jan 23 '17 at 18:07
  • Its still multidimensional its just not guaranteed to be next to each other in memory or forced to have the same col size as if int [][] ={{ ... }}. – user3853544 Jan 23 '17 at 18:14
  • A pointer is not an array. @EOF is right: this is not a multidimensional array, but a completely different data structure. Just because you can use the index-operator to both does not make them identical or even similar. – too honest for this site Jan 23 '17 at 18:19
  • The definition of multidimensional array is an array of arrays. This is an array of pointers to an array. – user3853544 Jan 23 '17 at 18:21
  • @user3853544 I had the same misconception an hour ago before olaf corrected it ; check that link, it's woth it ! http://stackoverflow.com/questions/1641957/is-an-array-name-a-pointer-in-c – m.raynal Jan 23 '17 at 19:21