2010-03-31 4 views
1

Я смущен указателями в объективе-c.Массив указателей в объективе-c

В основном у меня есть куча статических данных в моем коде.

static int dataSet0[2][2] = {{0, 1}, {2, 3}}; 
static int dataSet1[2][2] = {{4, 5}, {6, 7}}; 

И я хочу иметь массив для индексации всего этого.

dataSets[0]; //Would give me dataSet0... 

Какой должен быть тип наборов данных и как его инициализировать?

+0

Спасибо, ребята, это было очень полезно. – Justin

ответ

3

Несмотря на то что в памяти указана то же самое, указатель на многомерный массив отличается от указателя на плоский массив. Компилятор должен преобразовать индекс [] [] в индекс плоского массива для любых многомерных массивов. Невозможно смешивать два или различие для компилятора теряется. Вы можете использовать все плоские массивы:

static int dataSet00[2] = {0,1}; 
    static int dataSet01[2] = {2,3}; 
    static int * dataSet0[2] = {dataSet00, dataSet01}; 

    static int dataSet10[2] = {4, 5}; 
    static int dataSet11[2] = {6, 7}; 
    static int * dataSet1[2] = {dataSet10, dataSet11}; 

    static int ** dataSets[2] = {dataSet0, dataSet1}; 

или один большой многомерный массив:

static int dataSets[2][2][2] = {{{0,1},{2,3}},{{4,5},{6,7}}}; 

, но не сочетание двух, если вы ключ компилятор в объявляя специальный тип данных за предложение Джона.

+0

Это не так, как в памяти. В многомерном массиве все это находится в непрерывной памяти, а компилятор использует знание длины строки для определения смещения для арифметики указателя. С вашим другим подходом (int * и int **) вам на самом деле нужно указывать указатели разнесения на каждом уровне индексации. – sblom

+0

@sblom прав, что они структурно очень разные. Странно, однако, остальное сообщение (примеры и все) в остальном на 100% вернее, насколько я могу судить. – Chuck

+0

ах - да, два подхода определенно будут разложены по-разному. В этом первом предложении говорится, что хотя {{1,2}, {3,4}} и {1,2,3,4} выложены одинаково, они имеют важное различие во время компиляции, что мешает им назначаться взаимозаменяемо. – dstnbrkr

1

Ваш индексный массив будет представлять собой массив указателей на указатели на int.

Так что декларация будет выглядеть следующим образом:

int ** dataset[numOfDataSets] = {dataSet0, dataSet1, ...} 

Помните, что Objective-C является собственным подмножеством из ANSI-C, и этот вопрос, в частности, идет о языке с, на самом деле.

Редактирование: важно помнить, что в C массивы являются по существу просто указателями, а двумерные массивы - указателями на указатели.

Редактирование 2: Я считаю, что я фактически нарушил приоритет оператора. Должно быть:

int (** dataset)[numOfDataSets] = {dataSet0, dataSet1, ...} 
+0

Это действительно работает, спасибо. Однако он дает предупреждение: 'инициализация из несовместимого типа указателя'. Любая идея, как очистить это? – Justin

+0

@Justin: Я думаю, что я сделал ошибку приоритета оператора. См. Отредактированное решение. –

+0

dataSet0 и dataSet1 на самом деле не являются массивами указателей (поэтому int ** не будет работать) - это просто плоские массивы с удобным доступом. – dstnbrkr

3

Указатели на многомерные массивы могут быть сложными. ЬурейеЕ может помочь:

typedef int (*DataSetType)[2]; 
DataSetType dataSets[] = { dataSet0, dataSet1 /* and so on*/ }; 
Смежные вопросы