доступ к массиву из структуры в C - PullRequest
0 голосов
/ 29 января 2010

В моем data.h файле у меня есть:

typedef struct {
    double ***grid;
} Solver;

В моем .c файле у меня есть

static Solver _solver;

, который сначала вызывает функцию для некоторого распределения в сетке, например

_solver.grid = malloc(....);

//then makes a call to

GS_init(_solver.grid);

Функция GS_init объявлена ​​в GS.h как:

void GS_init(double ***grid);

Когда я пытаюсь скомпилировать, я получаю две ошибки:

the struct "<unnamed>" has no field "grid"
GS_init(_solver.grid)
^

и

too many arguments in function call
GS_init(_solver.grid)
^

Есть идеи, что здесь происходит не так?

1 Ответ

1 голос
/ 29 января 2010

Этот код компилируется с помощью 'gcc -Wall -Werror -c':

data.h

typedef struct
{
    double ***grid;
} Solver;

gs.h

extern void GS_init(double ***grid);

gs.c

#include "data.h"
#include "gs.h"
#include <stdlib.h>

static Solver _solver;

void anonymous(void)
{
    _solver.grid = malloc(32 * sizeof(double));
    GS_init(_solver.grid);
}

Дерек спросил:

Почему это работает? Это из-за ключевого слова extern?

«Внешний» не является материальным для того, чтобы заставить его работать, хотя я всегда использую его.

Когда мне нужно конкретизировать GS_init (), скажем, compute.c, я бы написал: void GS_init(double ***grid){ //loop over grid[i][j][k] setting to zero }

В некотором роде ... да, код GS_init () может сделать это, если структура данных настроена правильно, что потребует больше информации, чем в настоящее время видно в структуре.

Для обработки компилятором:

grid[i][j][k] = 0.0;

код должен знать действительные диапазоны для каждого из i, j и k; Предположим, что число строк в каждом измерении равно N i , N j , N k . «Структура» данных, на которую указывает grid, должна быть массивом значений N i 'double **', которые должны быть выделены. Каждая из этих записей должна указывать на значения N j 'double *'. Итак, вам нужно сделать больше выделения, чем один malloc(), и вам нужно сделать больше инициализации, чем просто установить все на ноль.

Если вы хотите использовать только один массив значений типа double, вам нужно написать другое выражение для доступа к данным:

grid[(i * Ni + j) * Nj + k] = 0.0;

И при этом сценарии grid будет простым double *, а не тройным указателем.

...