2016-05-08 16 views
7

Tôi có một mảng hai chiều làm việc với một chức năng:Làm thế nào để chuyển một con trỏ tới một mảng đa chiều trong C?

bool matrix[rows][cols]; 
func(rows, cols, matrix); 

void func(int rows, int cols, bool matrix[rows][cols]) { 
    //... 
} 

Tuy nhiên, ngay sau khi tôi cố gắng để có matrix trong hàm gốc được sửa đổi bởi:

bool matrix[rows][cols]; 
func(rows, cols, &matrix); 

void func(int rows, int cols, bool *matrix[rows][cols]) { 
    //... 
} 

tôi nhận được một con trỏ không tương thích loại lỗi. Tôi không biết gì về lý do tại sao.

+2

Chỉ cần loại bỏ '&' và '*' và tất cả đều phải là phân đoạn mảng - tốt cho con trỏ khi được truyền dưới dạng tham số hàm. –

+3

Lỗi nào bạn nhận được chính xác? – jboockmann

+0

@pytheos nó là một loại con trỏ không tương thích. Xấu của tôi - trông giống như rất nhiều khi tôi đã sửa đổi đầu tiên của tôi. – Synlar

Trả lời

7

bool matrix[rows][cols] là một mảng của các mảng của một loại bool

bool* matrix[rows][cols] là một mảng của các mảng của một con trỏ kiểu để bool hoặc đơn giản là bool*.

Vì vậy, nếu bạn đã định nghĩa chức năng của bạn để có một mảng của các mảng kiểu bool*, bạn cần phải vượt qua kiểu đó:

bool* m[row][col]; 
func(row , col , m); 

Nếu bạn muốn có một con trỏ đến bool matrix[rows][cols], sau đó cách tiếp cận của bạn không đúng.
Một con trỏ tới ma trận có loại: bool (*pmatrix)[rows][cols]. Vì vậy, xác định chức năng của bạn với loại đó và vượt qua địa chỉ của mảng ma trận:

func(rows , cols , &matrix); 
0

Một con trỏ đến một mảng chiều duy nhất, giả int a[10] thể trông giống như dưới đây:

int (*ptr)[10] 
     | |______________array of 10 integers(read type and number together) 
     |______a pointer to^

Một con trỏ tới một đa mảng chiều, nói int a[10][10] thể trông giống như dưới đây:

int (*ptr)[10][10] 
     | |  |_________________array of 10 integers(read type and number together) 
     | |______________array of^
     |______a pointer to^

Cảnh báo: Mind các parenthe sis.

*matrix[rows][cols]) khác với (*matrix)[rows][cols]). Sự khác biệt được chỉ ra trong câu trả lời của @ 2501.

+0

Tôi đã đọc sai câu hỏi ban đầu :( – sjsam

-3

Bạn có thể sử dụng *** cho ma trận.

char ***matrix = alloc_matrix(BUFFER_SIZE, BUFFER_SIZE);

char ***alloc_matrix(unsigned rows, unsigned columns) { 
    char ***matrix = malloc(rows * sizeof(char **)); 
    if (!matrix) abort(); 

    for (unsigned row = 0; row < rows; row++) { 
     matrix[row] = calloc(columns, sizeof(char *)); 
     if (!matrix[row]) abort(); 
     for (unsigned column = 0; column < columns; column++) { 
      matrix[row][column] = NULL; 
     } 
    } 
    return matrix; 
} 

Dưới đây là một ví dụ mà chúng ta sử dụng mallocpointers để tạo ra một ma trận.

3

@2501has already answered your question, nhưng vì bạn muốn mảng được sửa đổi được phản ánh với hàm chính, bạn không thực sự cần một con trỏ tới mảng (điều này sẽ làm phức tạp thêm)! Chỉ cần vượt qua mảng trực tiếp vì bạn sẽ nhận được kết quả mong đợi!

Tại sao, bạn hỏi?

Câu trả lời ngắn gọn: Trong C, mảng được chuyển bằng tham chiếu.

Long trả lời:

Luôn ghi nhớ rằng khi bạn sử dụng tên của một mảng, nó được chuyển đổi sang một con trỏ đến phần tử đầu tiên của nó. Điều này thường được gọi là "array decay".

Trở lại với mã của bạn, Sơ đồ bool matrix[rows][cols]; sẽ là:

+---------------------+---------------------+---------------------+---------------------+---------------------+ 
|      |      |      |      |      | 
|  matrix[0][0] |  matrix[0][1] |  matrix[0][2] |   ...   | matrix[0][cols - 1] | 
|      |      |      |      |      | 
+---------------------+---------------------+---------------------+---------------------+---------------------+ 
|      |      |      |      |      | 
|  matrix[1][0] |  matrix[1][1] |  matrix[1][2] |   ...   | matrix[1][cols - 1] | 
|      |      |      |      |      | 
+---------------------+---------------------+---------------------+---------------------+---------------------+ 
|      |      |      |      |      | 
|   ...   |   ...   |   ...   |   ...   |   ...   | 
|      |      |      |      |      | 
+---------------------+---------------------+---------------------+---------------------+---------------------+ 
|      |      |      |      |      | 
| matrix[rows - 1][0] | matrix[rows - 1][1] | matrix[rows - 1][2] |   ...   | matrix[rows - 1][cols - 1] | 
|      |      |      |      |      | 
+---------------------+---------------------+---------------------+---------------------+---------------------+ 

Từ sơ đồ trên, rõ ràng là yếu tố đầu tiên của

bool matrix[rows][cols]; 

là mảng con đầu tiên matrix[0][0] để matrix[0][cols - 1]. Vì vậy, những gì xảy ra ở đây là địa chỉ của subarray này đang được chuyển đến hàm. Đây là loại bool (*)[cols]. Điều này có nghĩa rằng

void func(int rows, int cols, bool matrix[rows][cols]) 

sẽ làm việc theo cách tương tự như

void func(int rows, int cols, bool (*matrix)[cols]) 

Vì vậy, ví dụ, nếu bạn muốn ghi vào khe thứ ba của mảng con thứ hai của matrix, bạn có thể sử dụng matrix[1][2] = WHATEVER; và những thay đổi được thực hiện từ chức năng cũng sẽ ảnh hưởng đến người gọi kể từ khi địa chỉ được thông qua.


: Có một vài trường hợp ngoại lệ nơi mảng "phân rã" không xảy ra. Xem Exception to array not decaying into a pointer?

Các vấn đề liên quan