2016-02-22 12 views
6

Pracuję nad przydziałem zadań domowych do mnożenia macierzy z dynamicznie przydzielanymi tablicami 2d. Pisałem następujące funkcje załadować matrycy:Różnica między ** i & ** w C w kontekście macierzy 2D

void loadMatrix(FILE* fp, int** matrix, int rowSize, int colSize) { 

    for (int i = 0; i < rowSize; i++) { 
     for (int j = 0; j < colSize; j++) { 
      fscanf(fp, "%d", &matrix[i][j]); 
     } 
    } 
} 

Deklaruję macierz jako zmienną globalną w następujący sposób:

int **a; 

a następnie zainicjować i załadować go w następujący sposób:

// allocate memory for the array rows 
a = (int **) malloc(m * sizeof(int*)); 

// allocate memory for array columns 
for (int i = 0; i < m; i++) { 
    a[i] = malloc(k * sizeof(int)); 
} 

loadMatrix(fp, a, m, k); 

Wszystko działa zgodnie z oczekiwaniami, jednak podpis funkcji podany przez nauczyciela jest następujący:

void loadMatrix(FILE*, int ***, int, int); 

Próbowałem użyć tej sygnatury i przekazać adres macierzy przy użyciu & i usunąć & z mojej funkcji loadMatrix, myśląc, że wyjścia powinny być takie same, ale używanie *** nie działa zgodnie z oczekiwaniami. czego mi brakuje? Jaka byłaby korzyść z używania potrójnych wskaźników, jeśli taki istnieje?

+3

'loadMatrix (fp, & a, m, k);' i do malloc'd wewnątrz funkcji. – BLUEPIXY

+3

Wystarczy zmienić '& matrix [i] [j]' na '& (* matrix) [i] [j]' w 'fprintf' i wywołanie funkcji na' loadMatrix (fp, & a, m, k); '. – haccks

+0

@Haccks wow, który działał dobrze. Dlaczego tak jest? Czuję, że & i * w pewnym sensie powinni się wzajemnie pozbyć. Co ja nie rozumiem? –

Odpowiedz

1

Twój kod ma następujące problemy:

  • Nie przeznaczają tablice 2D, ale raczej wskaźnik do wskaźnika stoły look-up oparte na segmenty całej stercie. Jest to powszechna, ale słaba praktyka: nigdy nie ma powodu, aby segmentować tablicę 2D i przydzielać ją w wielu miejscach. Kod staje się skomplikowany, a program zmienia się powoli, bez żadnej korzyści.

  • Nie ma powodu, aby deklarować macierz jako zmienną globalną.

  • Nigdy nie ma powodu, aby mieć 3 poziomy dwukierunkowości w C. Jest to znane jako "programowanie trzygwiazdkowe" i jest pewną oznaką zasadniczo wadliwego projektu programu. Niestety oznacza to, że twój nauczyciel nie jest godnym zaufania źródłem wiedzy C.

Zamiast tego, należy być przydzielenie tablice 2D:

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

void loadMatrix(FILE* fp, int rowSize, int colSize, int matrix[rowSize][colSize]) 
{ 
    for (int i = 0; i < rowSize; i++) { 
     for (int j = 0; j < colSize; j++) { 
      fscanf(fp, "%d", &matrix[i][j]); 
     } 
    } 
} 


int main (void) 
{ 
    const int ROWS = 4; 
    const int COLS = 5; 
    int (*matrix)[ROWS][COLS]; // array pointer to variable-length array 

    matrix = malloc(sizeof(int[ROWS][COLS])); 
    if(matrix == NULL) 
    { 
    // error handling 
    } 

    FILE* fp = ...; 
    loadMatrix(fp, ROWS, COLS, *matrix); // contents of what the pointer points at is the array 

    free(matrix); 
} 

Aby w pełni zrozumieć powyżej, polecam studiując tablice o zmiennej długości i jak tablice rozpad na wskaźniki do pierwszego elementu.

Powiązane problemy