2008-08-06 39 views
45

'da işlev argümanları olarak geçirme C dizisinin boyutlarının ne olacağını bilmediğimde çok boyutlu bir diziyi tek bir argüman olarak bir işleve iletebilir miyim?Çok boyutlu dizileri C

Ayrıca çok boyutlu dizilim dizeler dışında başka türde de içerebilir.

cevap

19

Bunu herhangi bir veri türü ile yapabilirsiniz. Basitçe bunu bir işaretçi-to-işaretçi olun:

typedef struct { 
    int myint; 
    char* mystring; 
} data; 

data** array; 

Ama hala değişken Malloc zorunda unutmayın ve biraz karmaşık olsun:

//initialize 
int x,y,w,h; 
w = 10; //width of array 
h = 20; //height of array 

//malloc the 'y' dimension 
array = malloc(sizeof(data*) * h); 

//iterate over 'y' dimension 
for(y=0;y<h;y++){ 
    //malloc the 'x' dimension 
    array[y] = malloc(sizeof(data) * w); 

    //iterate over the 'x' dimension 
    for(x=0;x<w;x++){ 
    //malloc the string in the data structure 
    array[y][x].mystring = malloc(50); //50 chars 

    //initialize 
    array[y][x].myint = 6; 
    strcpy(array[y][x].mystring, "w00t"); 
    } 
} 

ayırması kodu yapı benzer görünüyor - malloced her şeyi ücretsiz() aramak için unutmayın! (Ayrıca, sağlam uygulamalarda, check the return of malloc().

Şimdi bunu bir işleve aktarmak istediğinizi varsayalım.

int whatsMyInt(data** arrayPtr, int x, int y){ 
    return arrayPtr[y][x].myint; 
} 

Çağrı ile bu fonksiyon:

printf("My int is %d.\n", whatsMyInt(array, 2, 4)); 

Çıktı muhtemelen veri yapılarının işaretçilere veri yapısı değil, üzerindeki imleci manipülasyonlar yapmak istiyorum çünkü hala çift işaretçi kullanabilirsiniz:

My int is 6. 
+0

help here here: http: //stackoverflow.com/questions/16943909/manipulate-multidimensional-array-in-a-function – Dchris

+3

İşaretçi bölümlü arama tablosuna bir işaretçi bir 2D dizi değildir. Sadece [] [] sözdizimine izin verdiği için, bir diziye dönüşmez.Hafıza, diziler için gerekli olan bitişik bellek hücrelerine tahsis edilmediğinden, memcpy() vb. Arama tablonuz yığının her yerine dağınık, aramaları yavaşlatıyor ve yığın parçalanmış. – Lundin

31

Açık bir işaretçiyi birinci öğeye, dizi boyutlarını ayrı parametreler olarak geçirin.

... 
int arr1[10][20]; 
int arr2[5][80]; 
... 
func_2d(&arr1[0][0], 10, 20); 
func_2d(&arr2[0][0], 5, 80); 

aynı prensip yüksek boyut dizileri için de geçerlidir

olarak

void func_2d(int *p, size_t M, size_t N) 
{ 
    size_t i, j; 
    ... 
    p[i*N+j] = ...; 
} 

aranmak: Örneğin, gelişigüzel int-2-d diziler boyutlu işlemek için

func_3d(int *p, size_t X, size_t Y, size_t Z) 
{ 
    size_t i, j, k; 
    ... 
    p[i*Y*Z+j*Z+k] = ...; 
    ... 
} 
... 
arr2[10][20][30]; 
... 
func_3d(&arr[0][0][0], 10, 20, 30); 
+2

'p [i * Y + j * Z + k]' yerine p [i * Y * Z + j * Z + k] 'olmalıdır. –

+0

http://stackoverflow.com/questions/16943909/manipulate-multidimensional-array-in-a-function – Dchris

+0

i ve j'nin değerleri nedir? –

-2
int matmax(int **p, int dim) // p- matrix , dim- dimension of the matrix 
{ 
    return p[0][0]; 
} 

int main() 
{ 
    int *u[5]; // will be a 5x5 matrix 

    for(int i = 0; i < 5; i++) 
     u[i] = new int[5]; 

    u[0][0] = 1; // initialize u[0][0] - not mandatory 

    // put data in u[][] 

    printf("%d", matmax(u, 0)); //call to function 
    getche(); // just to see the result 
} 
+0

http://stackoverflow.com/questions/16943909/manipulate-multidimensional-array-in-a-function – Dchris

+1

Bu bir 2D dizi değil, bir arama tablosu. Ayrıca bu, C. – Lundin

15

İşlevinizi şu şekilde bildirebilirsiniz:

f(int size, int data[][size]) {...} 

Derleyici daha sonra sizin için tüm işaretçi aritmetik yapacaktır.

Boyutların, dizinin kendisinden önce görünmesi gerektiğini unutmayın.

GNU C (durumda gerçekten dizi sonra boyutları geçmesi gerekir) bağımsız değişken beyanı yönlendirme sağlar: an argüman olarak, ancak,

f(int size; int data[][size], int size) {...} 

ilk boyut, C derleyicisi için işe yaramaz (sizeof operatörü için bile, argüman olarak iletilen dizi üzerinden uygulandığında her zaman davranacağız ilk öğeye işaretçi olarak gösterilecektir).

+1

IMO olarak etiketlenmiştir, bu kabul edilen cevap olmalıdır. Ek kod gerekmiyor ve gereksiz yığın ayırma yok. basit ve temiz – imkendal

+0

Teşekkürler @kjh, Ben de bunun en temiz çözüm olduğunu düşünüyorum. Kabul edilen cevap onun için işe yaradı. Bak: OP 2008'den, cevabımdan yaklaşık 6 yıl önceydi. Bunun yanı sıra, burada kullanmış olduğum sözdizimi için C standartlarına izin verilip verilmediğini bilmiyorum. – rslemos

+0

Bu, son olarak bir işlev argümanı olarak M x N büyüklüğünde bir tamsayı matrisini (iki boyutlu bir dizi) geçirmek için benim aldığım çözümdür. Belki biraz daha fazla bilgi yardımcı olacaktır: Fonksiyon prototipi gibidir: void f (int N, int veri [] [N], int M); Fonksiyonun gövdesinde [m] [n] öğesi veri olarak yazılabilir [m] [n] - çok uygun, indeks hesaplaması gerekmez. – jonathanzh