2010-12-06 3 views
4

Я программист на Java, и я борюсь с этими простыми вещами.Возвращение указателя многомерного массива

Как я могу вернуть этот многомерный массив? Нужно ли возвращать ** указатель? Как я могу получить его в другом файле?

static MoveDirection ghost_moves[GHOSTS_SIZE][4]; 

MoveDirection** get_ghost_moves() { 
    return ghost_moves; 
} 

ответ

5

2D-массив не является указателем на указатель. Массивы и указатели имеют принципиально разные типы в C и C++. Массив распадается на на указатель на его первый элемент (отсюда частая путаница между ними), но он только распадается на первом уровне: если у вас многомерный массив, он распадается на указатель на массив, а не на указатель к указателю.

Правильная декларация get_ghost_moves является объявить его как возвращающая указатель на массив:

static MoveDirection ghost_moves[GHOSTS_SIZE][4]; 

// Define get_ghost_moves to be a function returning "pointer to array 4 of MoveDirection" 
MoveDirection (*get_ghost_moves())[4] { 
    return ghost_moves; 
} 

Этот синтаксис синтаксис очень запутанный, поэтому я рекомендую сделать ЬурейеЕ для него:

// Define MoveDirectionArray4 to be an alias for "array of 4 MoveDirections" 
typedef MoveDirection MoveDirectionArray4[4]; 

MoveDirectionArray4 *get_ghost_moves() { 
    return ghost_moves; 
} 
0

ghost_moves занимает непрерывный набор GHOSTS_SIZE*4 MoveDirections в памяти: его эквивалент MoveDirection*

Он не может использоваться с указателем на указатель, но с одним указателем.


Если вы хотите использовать два operator[] -s, чтобы индексировать массив у вас есть два варианта:

  1. использовать переменную типа: MoveDirection (*ghost_moves) [GHOST_SIZE], а затем просто сделать ghost_moves[i][j]

  2. Это в основном указатель на указатель, как правило, не является хорошим решением: есть ghost_moves типа MoveDirection**

    , например:

    MoveDirection ghost_moves_original[GHOST_SIZE][4]; 
    MoveDirection *ghost_moves[GHOST_SIZE]; 
    ghost_moves[0] = ghost_moves_original; 
    ghost_moves[1] = ghost_moves_original + GHOST_SIZE; 
    ... 
    
+1

На самом деле, `GHOSTS_SIZE * 4 * SizeOf (MoveDirection)` :) – 2010-12-06 23:09:09

+0

GHOSTS_SIZE * 4 MoveDirections == GHOSTS_SIZE * 4 * SizeOf (MoveDirection) байт – peoro 2010-12-06 23:09:44

0

Многомерный массив не является массивом указателей. Это единый блок памяти. Он имеет смысл только внутри области, где он объявлен.

Вы не можете чисто вернуть это, как у вас здесь. Вам нужно будет вернуть MoveDirection[GHOSTS_SIZE][4].

2

Нет, только один * - это все, что вам нужно. Главное - подумать о том, как ваши данные упорядочены в памяти: массив - это всего лишь серия предметов того же типа, выложенных смежно в памяти. В этом контексте не имеет значения, какова форма или размер массива - вы просто возвращаете указатель на начало, что означает, что вы возвращаете адрес первого элемента.

Конечно, кому бы вы не возвращали этот указатель, вам нужно знать, какова форма и размер массива.

Одна из приятных вещей о C и указателях заключается в том, что все просто число, а память - это просто большой массив байтов. Как только вы получите такое удобное мышление, все это встанет на свои места.

3

Я считаю, что вы хотите следующее:

MoveDirection (* get_ghost_moves()) [GHOSTS_SIZE][4]; 

В приведенном выше get_ghost_moves функция возвращает указатель на массив массив MoveDirection с размерами GHOSTS_SIZE и 4.

Я нашел следующие два сайта очень полезны для изучения того, как понимать декларации C:

3
#define MAX 20 

char canopy[20][MAX]; 
typedef char frank[MAX]; 

frank friend[MAX]; 

frank *getList() 
{ 
    return friend; 
} 

void test(int n) 
{ 
    frank *list = getList(); 

    int i; 

    for (i = 0; i < 5; i++) 
    {  
     printf("list[%d] %s\n\r", i, list[i]); 
    } 
} 

int main(void) 
{ 
    int i, nf; 

    for (i = 0; i < 5; i++) 
    { 
     snprintf(friend[i], MAX, "test%d", i); 
     printf("test[%d] %s \n\r", i, friend[i]); 
    } 

    test(5); 

    return 0; 
} 
Смежные вопросы