2009-09-09 29 views
7

Tôi có đoạn mã sau đó hoạt động tốt ...Đi qua một mảng int có độ dài biến như một tham số chức năng trong Objective C

int testarr[3][3] = { 
    {1,1,1}, 
    {1,0,1}, 
    {1,1,1} 
}; 
[self testCall: testarr]; 

nào gọi chức năng này:

- (void)testCall: (int[3][3]) arr { 

    NSLog(@"cell value is %u",arr[1][1]); 
} 

tôi cần mảng có độ dài biến - Cách tốt nhất để khai báo hàm là gì?

Sử dụng khoảng trống không hoạt động:

- (void)testCall: (int[][]) arr { 

Nhờ sự giúp đỡ của bạn.

Trả lời

6

Tôi sẽ viết những dòng này như:

- (void) testCall: (int *) aMatrice; 

Làm như vậy cho phép bạn để tránh nhiều mallocs và toán để tính toán một offset duy nhất trong một mảng tuyến tính dựa trên tọa độ x, y trong một mảng 2D là tầm thường. Nó cũng tránh được nhiều mallocs được ngụ ý bởi int ** và những hạn chế của cú pháp mảng 2D được duy trì bởi ngôn ngữ.

Vì vậy, nếu bạn muốn có một mảng 4x5, bạn có thể làm:

#define WIDTH 4 
#define HEIGHT 5 
#define INDEXOF(x,y) ((y*WIDTH) + x) 

int *myArray = malloc(sizeof(int) * 5 * ELEMS_PER_ROW); 

Sau đó, bạn có thể khởi tạo mảng tuyến tính hoặc với một lồng nhau vòng lặp for:

for(int x=0; x<width; x++) 
    for(int y=0; y<height; y++) 
     myArray[INDEXOF(x,y)] = ... some value ...; 

Và bạn sẽ vượt qua nó theo phương pháp như:

[foo testCall: myArray]; 

Mặc dù bạn cũng có thể muốn mang theo chiều rộng và chiều cao hoặc bette Tuy nhiên, tạo ra một lớp con IntMatrix của NSObject kết thúc tốt đẹp tất cả số học con trỏ và lưu trữ ngoài một API sạch đẹp.

(tất cả các mã gõ vào SO)

+0

Đây là một cách rất thông minh để giải quyết nó - cảm ơn. –

+1

Đừng quên 'free()' bộ nhớ sau khi gọi '[foo testCall: myArray];'. –

1

Tại sao bạn không chỉ sử dụng NSArray hoặc NSMutableArray với NSInteger s? Các lớp mảng đó có độ dài thay đổi và dễ sử dụng hơn nhiều.

này sẽ cho kết quả trong

- (void)testCall: (NSArray *) arr { 
    NSLog(@"cell value is %u", [[arr objectAtIndex:1] objectAtIndex:1]); 
} 

(Tất nhiên, bạn cũng sẽ phải xác định testarr sử dụng NSArray.)



Nếu bạn thực sự muốn sử dụng mảng C, làm cho đối số phương thức con trỏ tới một int có

- (void)testCall: (int*) arr {

lẽ sẽ làm việc (với phần còn lại của mã ở cùng).

+2

Các OP sẽ cần phải sử dụng '(int **)' để có được một mảng hai chiều. –

+0

Bạn không thể đặt NSIntegers trong NSArray vì NSInteger không phải là một đối tượng, nó chỉ là một typedef của một số loại int. Bạn sẽ phải sử dụng NSNumber, mà sẽ giới thiệu một số chi phí. – Amok

+0

Chris, (int **) có nghĩa là một con trỏ trỏ đến một con trỏ tới một int, không phải là một con trỏ tới một mảng hai chiều. Thêm một indirection không có gì để làm với bố trí của bộ nhớ bạn đang tham khảo. – NSResponder

2

Bạn không thể sử dụng int[][] vì kích thước của chiều kích thứ hai ảnh hưởng đến cách mảng được đặt ra trong bộ nhớ. Nếu bạn biết kích thước thứ hai bạn có thể sử dụng int[][x], nếu không bạn sẽ phải sử dụng int** mà có thể được truy cập giống như một mảng.

3

C mảng không thể biến trong hơn một chiều.

Bạn có thể không có điều này:

int testarr[][] = { 
    {1,1,1}, 
    {1,0,1,2}, 
    {1,1} 
}; 

Nhưng bạn có thể có điều này:

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 
} 
0

gọi

int testarr[3][3] = { 
    {1,1,1}, 
    {1,0,1}, 
    {1,1,1} 
}; 
[self testCall: (int *)testarr]; 

chức năng

- (void)testCall: (int *) arr 
{ 
    int (*V_arr)[3] = (int(*)[3])arr; 
    NSLog(@"cell value is %u",V_arr[1][1]); 
} 
Các vấn đề liên quan