2017-01-23 9 views
-2

Взгляните на этот массив:Получить значение из массива внутри другого массива [C]

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} }, 
}; 

Игнорировать странный размер и структуру массива, что это не то, что важно. Мне нужно иметь возможность использовать массив внутри этого массива. Например, у меня есть массив под названием H002:

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

Мне нужно, чтобы иметь возможность использовать H002 внутри c000. Такие, как:

{ {h002, 0, 0} }, 

Это компилируется нормально, однако

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

извлекает адреса с из H002. Мне нужен первый элемент в h002, а не адрес. Я смущен, почему он даже дал мне адрес h002? Я бы предположил, что * h002 будет извлекать адрес, но тогда это вообще не компилируется.

Я видел несколько вопросов по SO, которые очень похожи на шахты, такие как этот:

Creating an array of int arrays in C?

Я пробовал этот конкретный пример выше. Он работает, когда он есть в моем файле main.c, но когда я пытаюсь использовать его в том же файле .c, который содержится в c000 и h002, он не компилируется. Может быть, это связано с этим? Я не уверен, почему это было бы, учитывая, что использование h002 внутри c000 возвращает адрес h002 просто отлично. Странно, что код, представленный в ссылке выше, не будет компилироваться за пределами моего основного файла.

Я чувствую, что делаю какую-то очевидную, небольшую ошибку. Я уже около 5 дней общался с этим и продолжал. Судебные разбирательства и ошибки и исследования ни к чему не привели. Исследование было достаточно сложным, так как, похоже, не так много используют такие массивы, и ни одно из моих результатов не помогло мне.

Вы можете задать вопросы. Я буду рад указать дополнительную информацию, если это необходимо.

EDIT: Большое спасибо Стефану Лехнеру за помощь в решении моей проблемы. Чтобы получить результат, мне нужно было, я должен был сделать

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

Это прекрасно работает. Я также могу добавить любое число, которое мне нравится в конце, чтобы получить различные индексы в h002. Например:

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

Надеюсь, это поможет кому-то в будущем.

+0

'h002' представляет адрес вашего массива, в то время как' * hoo2' или 'h002 [0]' представляет значение, сохраненное в адресе, на который указывает 'h002'. –

+0

Похоже, что я получил это смешение. Если это так, есть ли причина, почему добавление указателя делает так, что моя программа не будет компилироваться? –

+0

Возможно, потому, что c000 не является массивом 'int', а массивом' int * '; попробуйте объявить его как 'const int c000 [64] [1] [3]' –

ответ

1

Я думаю, что основное недоразумение - это значение const int *c000[64][1][3], которое обозначает трехмерный массив указателей на int, но не указатель на трехмерный массив целых чисел.Чтобы продемонстрировать это, рассмотрим следующие упрощенные примеры вместе с предупреждениями компилятора:

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} } }; 

Только для показа другое значение: если один хотел бы объявить указатель на массив из 5 целых чисел, то это может быть выражено следующим образом:

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

Учитывая, что, давайте объясним смысл

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 } } }; 

Обратите внимание, что элемент c000 является указателем на целое число, и заметим, что Варя ble h002, используемый в контексте инициализатора массива, распадается на указатель на целое число (указывая на первый элемент h002). Это почти так же, как объявление const int* ptrToH002 = h002, и следующий распечатывают показывает, что это на самом деле то же самое:

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 

Следовательно, должно быть ясно, что myVar = c000[0][0][0] извлекает адрес, а не целое значение или целочисленный массив. Адрес указывает на первый элемент массива h002.

+0

Значит, я должен иметь возможность ссылаться на h002 (& h002) и получить его первый элемент, правильно? Я делаю это, и он не работает, он по-прежнему возвращает адрес h002. –

+1

Если вы ссылаетесь на что-то, например. написав '& h002', вы всегда получите адрес, а не значение. Если вы хотите получить доступ к значению массива, используйте индексы, например 'myValue = h002 [0]'; Если вы хотите получить доступ к значению, на которое у вас есть указатель, разыщите указатель, например. 'myValue = * ptrToH002' - обратите внимание, что' ptrToH002' указывает на первый элемент массива 'h002'. ОК? –

+0

Хорошо, я понимаю. Итак, допустим, мой массив c001 такой же, как и в моем исходном сообщении, но у меня есть h002 как h002 [0]. Это компилируется отлично, однако я все еще получаю адрес, а не элемент. Что тогда? –

-2

Пример многомерного массива:

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]); 
} 

Вы должны быть в состоянии изменить свой код на то, что вам нужно, используя этот пример.

+1

Во-первых, это помечено 'c', а не' C++ '. Во-вторых, это не многомерный массив. – EOF

+0

Теперь его C, спасибо. Вы обнаружите, что два измерения на самом деле многомерны. – user3853544

+0

Массив указателей! = Многомерный массив. – EOF