2015-05-07 5 views
0

Когда я повторяю элементы 2D-массива для отображения каждого int, я получаю строку цифр. Я испробовал несколько разных вещей, чтобы исправить это, но я полагаю, что это что-то маленькое, я упускаю из виду, что приведет все это вместе.2 Размерный массив не печатает Ожидаемый ответ

Во всяком случае, в header.h мы создаем

typedef struct gol{ 
    int **board; 
    size_t size; 
}gol; 

и main.C

void GOL_Opton1(){ 

    printf(" This is running Game Of Life on a default board\n"); 

    gol* mainGOL = (gol*)malloc(sizeof(gol)); 

    mainGOL = create_default_gol(); 
    print_gol(mainGOL); 
} 

gol* create_default_gol() 
{ 
    gol* defaultGol = (gol*)malloc(sizeof(gol)); 

    int defaultArray[20][20]; 
    defaultGol->board = defaultArray; 

    for (i = 0; i<20; i++){ 
     for (j = 0; j<20; j++){ 
      defaultGol->board[i,j] = 0; 
    } 
    } 
    return defaultGol; 
} 

void print_gol(gol* g){ 
printf(" ------------------------------------------------\n"); 
for (i = 0; i<20; i++){ 
    for (j = 0; j<20; j++){ 
     printf("%d \t",g->board[i,j]); 
    }printf("\n"); 
    } 
} 

Вариант 1, вызывается из меню, то массив доска в голе заполняется набор 0 для начальной точки.

+1

Синтаксис для доступа к элементам массива должны быть defaultGol-> доска [I] [J] не defaultGol-> доска [I, J] – paisanco

+0

'defaultGol-> плата = defaultArray;': тип 'defaultArray' не' int ** ', а также локальная переменная. – BLUEPIXY

+0

предлагают НЕ вводить определение структуры. Это просто загромождает код, приводит к неправильному пониманию и загромождает пространство имен компилятора. – user3629249

ответ

4

Есть несколько вещей, чтобы улучшить там. Во-первых, в вашем заголовке более простым способом справиться с двумерным массивом было бы хранить указатель на первый элемент массива, а также на размер. (Ваш код предполагает, что все доски квадрата. Мы будем идти с этим в настоящее время.)

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"); 
    } 
} 
+0

Огромное вам спасибо, что исправил это довольно хорошо. Теперь мне просто нужно выяснить, почему 2 из первого целого числа в первых двух строках составляет 7012548 –

1

Конкретная проблема, с которой вы сталкиваетесь, находится в create_default_gol().

int defaultArray[20][20]; 
defaultGol->board = defaultArray; 
[...] 
return defaultGol; 

defaultArray является alloc'ed в стеке, то это указатель ускользает функцию. Данные, которые вы написали до defaultArray (или ->board, если на то пошло), к тому времени, когда вы к нему получите доступ, будет долгое время.

Вы можете исправить это alloc'ing ваши ->board в куче с malloc с: один для всей платы (malloc(20 * sizeof(int*))), затем более 20 для каждой строки (malloc(20 * sizeof(int))).

0
#include <stdio.h> 
#include <stdlib.h> 

typedef struct gol{ 
    int **board; 
    size_t size; 
}gol; 


gol *create_gol(size_t size){ 
    size_t i, j; 
    gol *aGol = (gol*)malloc(sizeof(gol)); 

    aGol->board = malloc(size * sizeof(int*)); 
    aGol->size = size; 
    for (i = 0; i < size; i++){ 
     aGol->board[i] = malloc(size * sizeof(int)); 
     for (j = 0; j < size; j++){ 
      aGol->board[i][j] = 0; 
     } 
    } 
    return aGol; 
} 

gol *create_default_gol(void){ 
    return create_gol(20); 
} 

void print_gol(gol *g){ 
    size_t i, j; 
    printf("------------------------------------------------\n"); 
    for (i = 0; i < g->size; i++){ 
     for (j = 0; j < g->size; j++){ 
      printf("%d ", g->board[i][j]); 
     } 
     printf("\n"); 
    } 
} 

void GOL_Opton1(void){ 
    printf("This is running Game Of Life on a default board\n"); 

    gol *mainGOL = create_default_gol(); 
    print_gol(mainGOL); 
} 

int main(void){ 
    GOL_Opton1(); 
    //deallocate 
    return 0; 
} 
Смежные вопросы