Возврат указателя многомерного массива - PullRequest
4 голосов
/ 07 декабря 2010

Я программист на Java, и я борюсь с этим простым делом.

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

static MoveDirection ghost_moves[GHOSTS_SIZE][4];

MoveDirection** get_ghost_moves() {
    return ghost_moves;
}

Ответы [ 6 ]

5 голосов
/ 07 декабря 2010

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

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

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

MoveDirectionArray4 *get_ghost_moves() {
    return ghost_moves;
}
3 голосов
/ 11 октября 2012
#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;
}
3 голосов
/ 07 декабря 2010

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

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

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

Я обнаружил, что следующие два сайта очень полезны для изучения понимания объявлений C:

2 голосов
/ 07 декабря 2010

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

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

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

0 голосов
/ 07 декабря 2010

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

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

0 голосов
/ 07 декабря 2010

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;
    ...
    
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...