2013-01-01 54 views
1

可能重複:
How do I use arrays in C++?當在C語言中的二維陣列和多維數組作爲函數參數

一個維陣列作爲函數參數:

#include <stdio.h> 
#include <string.h> 

int func(int a[], int n) 
{ 
    int i; 
    for(i = 0; i < n; i++) 
     printf("%d ", a[i][j]); 
} 

int main(void) 
{ 
    int a[2] = {1,2}; 
    func(a, 2); 
} 

它編譯並正確運行。

但是,當一個二維陣列作爲函數參數:

#include <stdio.h> 
#include <string.h> 

int func(int a[][], int n) 
{ 
    int i, j; 
    for(i = 0; i < n; i++) 
     for(j = 0 ; j < n; j++) 
      printf("%d ", a[i][j]); 
     printf("\n"); 
} 

int main(void) 
{ 
    int a[2][2] = {{1,2}, {3,4}}; 
    func(a, 2); 
} 

它不能正確編譯。我必須這樣修改代碼:

#include <stdio.h> 
#include <string.h> 

int func(int a[][2], int n) 
{ 
    int i, j; 
    for(i = 0; i < n; i++) 
     for(j = 0 ; j < n; j++) 
      printf("%d ", a[i][j]); 
     printf("\n"); 
} 

int main(void) 
{ 
    int a[2][2] = {{1,2}, {3,4}}; 
    func(a, 2); 
} 

我不知道爲什麼?任何人都可以解釋它是如何工作的?非常感謝。

+0

'int a []'然後'a [i] [j]' - 地球上的這種編譯是否正確? – 2013-01-01 17:02:18

+0

此問題不是「如何在C++中使用數組」的重複。無論如何,這個問題非常廣泛(如此糟糕的表述)。這個問題更具體(儘管需要對英文正確性進行一些編輯)。而且,儘管在這個問題中涉及到的一些內容與C++相關,但它們通常專用於C++,而這個問題應該僅限於C並且面向C語言。如果這是關於SO的另一個問題的重複,那麼讓我們在這裏列出正確的一個。 – labyrinth

回答

8

c中的數組(一維和多維)駐留在連續的內存塊中。這意味着,當你定義char a[3],陣列中的存儲佈局是這樣的(原諒我糟糕的ASCII藝術技能):

| a[0] | a[1] | a[2] | 

對於二維數組char a[2][3],佈局是這樣的:

| a[0][0] | a[0][1] | a[0][2] | a[1][0] | a[1][1] | a[1][2] | 
          ^
           +--- first row ends here 

因此,當索引爲二維陣列a[i][j],編譯器生成的代碼相當於此:

*(a + i*3 + j) 

可以將其讀作「跳過i行並將該行中的單元格j」。要做到這一點,編譯器必須知道行的長度(這是第二維)。這意味着第二維是類型定義的一部分!

因此,當您想要將2d數組傳遞給函數時,您必須爲類型定義指定所需的維度。

0

沒有第二個層面到陣列的編譯器不知道如何索引它。這是因爲編譯器會用指針來進行一些算術運算,找出在哪裏找到內存中的值。

0

C中的數組非常「弱」,並且通常只在第一個元素的指針的運行時表示。當你聲明類似int a[][]時,不可能知道如何計算每個元素的地址,因爲類型聲明沒有說明。這就是爲什麼它不能編譯,因爲類型是無效的。

如果你能有int a[][],然後把它稱爲傳遞要麼int big[8][8]int small[2][2],有沒有辦法神奇地「適應」對於這些不同的陣列正確的地址計算函數內部的代碼。這就是爲什麼它不起作用。

您可以編寫int *matrix, size_t width一般功能和手動操作的地址計算,即元素「matrix[i][j]」是matrix[i * width + j]row-major ordering

2

最近的(如C2011,也許C99ç標準使得variable length array所以下面的功能不工作

int 
sum (int n, int t[n][n]) 
{ 
    int s = 0; 
    for (int i = 0; i < n; i++) 
    for (int j = 0; j < n; j++) 
     s += t[i][j]; 
    return s; 
} 

這一點沒有警告編譯時gcc-4.7 -std=gnu99 -Wall -O -c ex.c和生成的彙編是你所期望的

至於爲什麼int t[][]不能工作,這是因爲整個t的每個元素將是型它有不確定的大小。