2016-11-02 71 views
0

我正在處理C中的一些計算物理問題,並且我在代碼中遇到了一些困惑。我花了最後幾周閱讀C,但我仍然對這種語言不熟悉。我需要在二維數組上工作。每行的長度可能會有所不同,例如,我可能想要使用:創建和修改「三角形」矩陣:[[0,1,2][1,2][2]]在C中的函數中爲2D數組分配空間?

爲了以可維護,易於閱讀和修改的方式構建我的代碼,我想將部分邏輯移到一個函數中。但是,這似乎比我預期的更困難。

我開始,我創建一個int **matrix變量,並傳遞給函數的方法,用ampersand前綴並接受一家三星級INT:int ***,並與矩陣*matrix[i][j]工作。我無法得到它的工作,但matrix[0][i][j]工作和我只是無法讓我的頭。這兩個概念不一樣嗎?

這裏是我的代碼:

void alloc_subscript_notation(int number_of_rows, int *** matrix) { 
    matrix[0] = malloc(number_of_rows * sizeof(int *)); 
    for (int i = 0; i < number_of_rows; i++) 
     matrix[0][i] = calloc((number_of_rows-i), sizeof(int)); 

} 

void modify_subscript(int number_of_rows, int *** matrix) { 
    matrix[0][0][1] = 8; // just set a value of an element to 8, as a proof of concept 
} 

void subscript_notation (int number_of_rows, int *** matrix) { 
    alloc_subscript_notation(number_of_rows, matrix); 
    modify_subscript(number_of_rows, matrix); // I can even modify it 
} 


void alloc_star_notation(int number_of_rows, int *** matrix) { 
    *matrix = malloc(number_of_rows * sizeof(int *)); 

    for (int i = 0; i < number_of_rows; i++) 
     *matrix[i] = calloc((number_of_rows-i), sizeof(int)); 

    printf("alloc_subscript_notation: zeros: %d, %d, %d\n", // just a few examples 
      *matrix[0][2], *matrix[1][1], *matrix[2][0]); 
} 

void star_notation (int number_of_rows, int *** matrix) { 
    // SEGMENTATION FAULT!!! 
    alloc_star_notation(number_of_rows, matrix); 
} 

int main (void) { 
    int ** matrix; 
    int number_of_rows = 3; // it's dynamic in my program, but I use it this hard-coded value for clarity 
    // I want to be able to access matrix elements here 
    // All good here. 
    subscript_notation(number_of_rows, &matrix); 
    printf("subscript_notation ready. main: " 
      " %d, %d, %d, modified: %d\n", 
      matrix[0][2], matrix[1][1], matrix[2][0], matrix[0][1]); 

    // Segmentation Fault 
    star_notation(number_of_rows, &matrix); 
} 
+0

你知道如何讓一維數組工作嗎? –

+0

'alloc_star_notation'由'alloc_subscript_notation'分配的內存泄漏 – LPs

+0

順便說一句,使用你的代碼,你正在使用指針指針,這不是一個二維數組...... – LPs

回答

2

沒有,*matrix[i][j]matrix[0][i][j]是不一樣的。

前者與*(matrix[i][j])相同,後者與(*matrix)[i][j]相同。

由於您試圖訪問使用地址運算符傳遞給函數的指針,因此您必須使用後者的版本。

+0

你說的是真的,但是你可能想解釋差別的意義。 – Peter

+0

@Peter我們必須看看OP如何響應。 – 2501

+0

哦,這是一個(包括但不一定侷限於:))運算符優先級(http://en.cppreference.com/w/c/language/operator_precedence)問題 –

2

我無法讓它工作,但矩陣[0] [我] [J]的工作,我只是無法讓我的頭。這兩個概念不一樣嗎?

不,*matrix[i][j]matrix[0][i][j]是不同的東西。

鑑於int *** matrix,然後matrix[i][j]是指向int,而實際上*matrix[i][j]matrix[i][j][0]

0

是我建議你使用一個連續的內存塊來簡化旅遊代碼。

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

void alloc_subscript_notation(int number_of_rows, int number_of_cols, int **matrix) 
{ 
    *matrix = malloc(number_of_rows * number_of_rows * sizeof(int)); 

    if (*matrix != NULL) 
    { 
     for (int i=0; i<number_of_rows; i++) 
     { 
      for (int j=0; j<number_of_cols; j++) 
      { 
       (*matrix)[(i*number_of_cols)+j] = (i*number_of_cols)+j; 
      } 
     } 
    } 
} 


int main (void) { 
    int *matrix; 
    int number_of_rows = 3; // it's dynamic in my program, but I use it this hard-coded value for clarity 
    int number_of_cols = 3; // it's dynamic in my program, but I use it this hard-coded value for clarity 
    // I want to be able to access matrix elements here 
    // All good here. 
    alloc_subscript_notation(number_of_rows, number_of_cols, &matrix); 

    if (matrix != NULL) 
    { 
     printf("subscript_notation ready. main: " 
       " %d, %d, %d, modified: %d\n", 
       matrix[(0*number_of_cols)+2], matrix[(1*number_of_cols)+1], matrix[(2*number_of_cols)+0], matrix[(0*number_of_cols)+1]); 
    } 
} 
1

只是爲了擴大@artm的答案,你是不是(嚴格來說)爲一個二維數組預留空間,在C二維數組預留空間(不分段)的正確方法是使用VLA

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

static void func(size_t dim, int (**matrix)[dim]) 
{ 
    *matrix = malloc(sizeof(int[dim]) * dim); 
} 

int main(void) 
{ 
    size_t dim = 3; 
    int (*matrix)[dim]; /* A pointer to an array of n elements */ 

    func(dim, &matrix); 
    free(matrix); 
    return 0; 
}