For your edification, this is all C, Cocoa isn't involved.
So you have a few options:
1) You have an array of int * instead of a two dimensional array, and you allocate space for each "dimension". This could be rectangular, or jagged, depending on your needs. You'd then pass an int ** to your method. You can still access the elements using [x][y]. However, you should probably also pass an array with the widths of each row, so you can safely access these elements.
2) You have an int [][], that is one big chunk of memory. In this case you need to define all but the first dimension, so the offsets can be properly calculated. For example:
Code:
int myArr[5][6];
myFunc(myArr);
void myFunc(int myArg[][6]) {
...
}
When you use the first dimension, the compiler knows how to do the math to find the offset in your array.
3) I came up with a few other options, but neither was too elegant. Both involved passing your dimensions as arguments, and one used the gcc extension to declare a variable shaped array using these arguments, then memcpy'ing over the argument that is passed in. Then you can use [][] without issue to access the new array, but you've wasted a lot of memory. For the sake of exploration, it looks like this:
Code:
#include <stdio.h>
#include <string.h>
void myfunc(int *,int,int);
int main(int argc, char **argv) {
int myarr[5][6];
myarr[1][4]=8;
myfunc(&myarr[0][0],5,6);
}
void myfunc(int *myarg,int dim1,int dim2) {
int test[dim1][dim2],x,y;
memcpy((void *)test,(void *)myarg,(size_t)dim1*dim2*sizeof(int));
for(x=0;x < dim1;x++) {
for(y=0;y < dim2;y++) {
printf("test[%d][%d] = %d\n",x,y,test[x][y]);
}
}
}
This is wasteful, but the code looks more elegant. I came up with another way that does not use the variable shaped array extension, but the code does not look pleasant:
Code:
#include <stdio.h>
void myfunc(int *,int,int);
int main(int argc, char **argv) {
int myarr[5][6];
myarr[1][4]=8;
myfunc(&myarr[0][0],5,6);
}
void myfunc(int *myarg,int dim1,int dim2) {
for(x=0;x < dim1;x++) {
for(y=0;y < dim2;y++) {
printf("test[%d] = %d\n",x*(dim2)+y,myarg[x*(dim2)+y]);
}
}
}
This is essentially doing the compilers job by calculating your own offsets (though at least you're doing it by elements and not bytes). You could, of course, make a helper function that is called elementAt and obscure this from the main sections of your code:
Code:
int elementAt(int *list,int dim2,int x,int y){
return list[x*(dim2)+y];
}
This still requires you to carry around the lower dimension of the array to calculate the offset.
As for getting the length of a C-style array, you don't. An array is just a pointer to the base of the array in memory. That's all. It's not a complex data-type that carries around the length/width/# of dimensions, etc. You can #define something in a header file that defines the length of a particular thing, so you have easy access to it, but otherwise you're out of luck. You'll just need to pass the length around with the array, or find some other solution (such as passing around a struct that has the pointer, and it's length, etc.).
Edit: I lied, a bit. If you have an int *, for example, you are out of luck. If you are in the scope where a multidimensional array is declared, you can use sizeof to get the information:
Code:
#include <stdio.h>
int main(int argc, char **argv) {
int myarr[5][6];
myarr[1][4]=8;
printf("size: %d\t%d\t%d\n",sizeof(myarr)/sizeof(int),sizeof(myarr[0])/sizeof(int),sizeof(myarr)/sizeof(myarr[0]));
}
This ultimately raises the question of why you'd go through this kind of silliness when you have dynamic data structures at your disposal in Objective-C. Unless there's a huge performance hit, why not use an NSMutableArray of NSMutableArrays of NSNumbers? Then you do have methods to get length, etc.
-Lee