Есть несколько вещей, чтобы улучшить там. Во-первых, в вашем заголовке более простым способом справиться с двумерным массивом было бы хранить указатель на первый элемент массива, а также на размер. (Ваш код предполагает, что все доски квадрата. Мы будем идти с этим в настоящее время.)
typedef struct { /* No need to name the struct if you typedef it */
int *board; /* We point to the first int, then calculate offsets manually */
size_t size;
} gol;
Затем мы можем вычислить положение в массиве вручную. Давайте предположим, что мы будем хранить числа в таком порядке:
012
345
678
Теперь, давайте предположим, что мы хотим, чтобы элемент в 1-й строке, второй столбец - , начиная с нуля, так что на самом деле средний ряд и последний столбец - мы знаем, что есть три столбца на строку, поэтому rows * columns_per_row + columns
будет элементом для поиска.
void GOL_Opton1(){
printf(" This is running Game Of Life on a default board\n");
create_default_gol()
уже называет malloc
для вас. Если вы сначала назначите mainGOL
возврат malloc
, вы запрашиваете эту память, но никогда не используете ее, так как вы сразу же сохраняете другой адрес в mainGOL
. Это приведет к утечке памяти.
gol* mainGOL = create_default_gol();
print_gol(mainGOL);
}
Чтобы избежать "магические числа", я хотел бы использовать #define
. Размер платы по умолчанию также легко регулируется.
#define DEFAULT_GOL_SIZE 20
gol* create_default_gol()
{
gol* defaultGol = (gol*)malloc(sizeof(gol));
Объявление массива обычно выделяет его в стеке. Однако вы хотите, чтобы create_default_gol
возвращал gol
, который может использоваться внешними функциями, поэтому вам нужно выделить его в кучу. В противном случае это может привести к возникновению всех видов странного поведения.
defaultGol->board = malloc(sizeof(int) * DEFAULT_GOL_SIZE * DEFAULT_GOL_SIZE);
defaultGol->size = DEFAULT_GOL_SIZE; /* and store the size */
Здесь функция memset
является распространенным способом быстро установив всю доску 0.
/* memset avoids an ugly for loop here */
memset(defaultGol->board, defaultGol->size * defaultGol->size, 0);
return defaultGol;
}
void print_gol(gol* g){
size_t row, col;
printf(" ------------------------------------------------\n");
Вы хотите, чтобы ваша print_gol
функции, чтобы иметь возможность обрабатывать доски разного размера чем 20, поэтому обобщаем это для использования члена size
.
for (row = 0; row < g->size; row++) {
for (col = 0; col < g->size; col++) {
Здесь обсуждаются вышеперечисленные смещения. В вашем исходном коде был [i, j]
, который не сделал бы то, что вы имели в виду; с обычным двумерным массивом, вы бы хотели [i][j]
, но в этом случае мы делаем вычисления смещения вручную, чтобы разрешить произвольные размеры.
printf("%d \t", g->board[col + row*g->size]);
}
printf("\n");
}
}
Синтаксис для доступа к элементам массива должны быть defaultGol-> доска [I] [J] не defaultGol-> доска [I, J] – paisanco
'defaultGol-> плата = defaultArray;': тип 'defaultArray' не' int ** ', а также локальная переменная. – BLUEPIXY
предлагают НЕ вводить определение структуры. Это просто загромождает код, приводит к неправильному пониманию и загромождает пространство имен компилятора. – user3629249