Objective Cの関数パラメーターとして可変長のint配列を渡す
-
05-07-2019 - |
質問
正常に動作する次のコードがあります...
int testarr[3][3] = {
{1,1,1},
{1,0,1},
{1,1,1}
};
[self testCall: testarr];
この関数を呼び出す:
- (void)testCall: (int[3][3]) arr {
NSLog(@"cell value is %u",arr[1][1]);
}
可変長の配列が必要です-関数を宣言する最良の方法は何ですか?
空白の使用は機能しません:
- (void)testCall: (int[][]) arr {
ご協力ありがとうございます。
解決
これを次のように書く:
- (void) testCall: (int *) aMatrice;
そうすることで、複数のmallocを回避し、2D配列のx、y座標に基づいて線形配列の1つのオフセットを計算する計算が簡単になります。また、int **によって暗示される複数のmallocと、言語によって永続化される2D配列構文の制限を回避します。
したがって、4x5配列が必要な場合は、次のようにします。
#define WIDTH 4
#define HEIGHT 5
#define INDEXOF(x,y) ((y*WIDTH) + x)
int *myArray = malloc(sizeof(int) * 5 * ELEMS_PER_ROW);
その後、線形またはネストされたforループで配列を初期化できます:
for(int x=0; x<width; x++)
for(int y=0; y<height; y++)
myArray[INDEXOF(x,y)] = ... some value ...;
そして次のようなメソッドに渡します:
[foo testCall: myArray];
幅と高さも一緒に持ち歩きたいかもしれませんが、さらに良いことに、すてきなAPIを超えてすべてのポインター演算とストレージをラップするNSObjectのIntMatrixサブクラスを作成します。
(すべてのコードをSOに入力)
他のヒント
C配列は、複数の次元で変数にすることはできません。
これはできません:
int testarr[][] = {
{1,1,1},
{1,0,1,2},
{1,1}
};
しかし、あなたはこれを持つことができます:
int testarr[][3] = {
{1,1,1},
{1,0,1},
{1,1,1},
{4,5,6},
{7,8,9}
}
foo(testarr);
void foo(int param[][3])
{
printf("%d", param[3][1]); // prints 5
}
int [] []
は使用できません。2番目の次元のサイズは、メモリ内での配列のレイアウトに影響するためです。 2番目の次元がわかっている場合は、 int [] [x]
を使用できます。それ以外の場合は、配列のようにアクセスできる int **
を使用する必要があります。
なぜ NSInteger
または NSMutableArray
を NSInteger
と一緒に使用しないのですか?これらの配列クラスは可変長であり、はるかに使いやすいです。
これにより、
- (void)testCall: (NSArray *) arr {
NSLog(@"cell value is %u", [[arr objectAtIndex:1] objectAtIndex:1]);
}
(もちろん、NSArrayを使用してtestarrを定義する必要もあります。)
C配列を本当に使用したい場合は、
-(void)testCall:(int *)arr {
おそらく動作します(残りのコードは同じままです)。
電話
int testarr[3][3] = {
{1,1,1},
{1,0,1},
{1,1,1}
};
[self testCall: (int *)testarr];
関数
- (void)testCall: (int *) arr
{
int (*V_arr)[3] = (int(*)[3])arr;
NSLog(@"cell value is %u",V_arr[1][1]);
}