【问题标题】:Multi-dimensional array of unspecified size as an instance variable?未指定大小的多维数组作为实例变量?
【发布时间】:2012-10-28 01:56:54
【问题描述】:

我是 OOP 的初学者,所以这可能是一个愚蠢的问题!

我想在objective-c 类中使用多维CArray 作为实例变量,并且还希望能够在运行时,在对象初始化方法期间指定它的大小:

@interface ArrayClass : NSObject {

int array[][];

}

-(id)initWithSizeX:(int)sizeX sizeY:(int)sizeY;

@end

这会产生错误“Instance variable 'array' has unknown size.”

如果我将数组声明为具有初始大小(例如 [20][20]),我似乎只能使用该数组 - 但这当然违背了这一点,因为我希望它在运行时决定!

我猜这是有必要的,因为需要预先知道对象的内存占用?

有谁知道我正在尝试做的事情是否可行?是否有任何解决方法可以让我在运行时调整数组的大小?还是我以完全错误的方式解决这个问题?

我知道有很多关于多维数组的主题,但我似乎找不到任何可以回答我问题的内容!

【问题讨论】:

  • 如果它需要是动态的,那么也许可以这样做。 NSMutableArray 可能会给你你想要的东西,同时留在 Obj-C 土地上。您可能需要通过索引算术来完成多维工作,但这在二维中很容易。它必须是一个C数组吗?

标签: objective-c c arrays multidimensional-array instance-variables


【解决方案1】:

由于您使用的是 Objective-C,您可能会考虑使用 NSArray(或 NSMutableArray,具体取决于您计划对数组执行的操作)。这将让您向它发送 Objective-C 消息并“免费”获得更多功能,因为它是一个对象,而不仅仅是一块内存(就像 C 中的数组一样)。此外,如果您使用 ARC 或垃圾回收,它会为您管理内存。

但是如果你知道你想使用一个 C 数组(这是完全有效的),你需要像你一样在你的代码中 malloc 它(以及当你完成它时 free 它)通常会在 C 中。(如您所述,只有在编译时创建定义大小的静态数组时才能解决此问题。)

编辑:正如@Mahesh 在 cmets 中指出的那样,您需要将您的 array 变量声明为
int **array;
而不是
int[][] array;

如果您需要更多帮助,请查看here

【讨论】:

  • +1 如果 OP 需要走 C 路,那么 int ** 就是需要的。
  • 谢谢,我会试试看效果如何!我没想过那样做。我想,试图了解面向对象的编程会让我忘记我应该知道的关于 C 的事情!我更喜欢使用 C 数组,因为我只需要基本功能,而且我有点担心如果我的数组非常大,创建太多 NSNumber 对象可能会导致性能影响!
  • 是的,如果您需要做的只是存储ints 的二维数组,那么将它们推入NSNumber 对象只是为了将它们保存在NSArray 中绝对是浪费 - - plan 'ole C 数组是正确的选择!
【解决方案2】:

如果可能,请使用 NSArray 或派生类。如果它必须是 C 数组,则可以使用单线性 malloc() 来完成,并自己对二维进行算术。 IE。

int *ar = malloc(sizeof(int) * nrows * ncols);

并通过偏移量的算术访问适当的“单元格”

// access cell at [n,m]
ar[n*ncols+m] = value;

我通常发现这比尝试管理指向值数组的指针数组要简单得多,但是您的里程可能会有所不同。

或者,我将其保存在最后,以防您想要多维动态数组中的真正“多”而不使用最推荐的 row-malloc-happy 列表,并且您的 C 编译器支持 C99 标准中定义的可选功能,称为VLA(可变长度数组)。 C99 在实现级别支持变量数组声明(即编译器可以支持标准定义的特性,但不是必须的;有关更多信息,请参见 C99 标准的 6.7.6.2)。如果您的编译器不支持它,则必须定义一个预定义的宏 __STDC_NO_VLA__ 并且可以在编译时进行测试(参见 C99 标准的第 6.10.8.3-1 节)。话虽如此,我在过去十多年中使用过的每一个符合 C99 的编译器都支持它,所以如果你的不支持,请在下面的评论中告诉我们。对于 OP,如果您在 Xcode 中使用 gcc 或 llvm,我保证您会这样做。对于其他人,只需测试是否定义了__STDC_NO_VLA__。如果是,则支持该功能。

int nrows = 10, ncols = 15;
int (*ar)[cols] = malloc(sizeof(int) * nrows * ncols);

立即注意几件事。分配与以前完全相同相同。然而,被声明的变量有点不同。 ar 的声明表明它是一个指向 ncols 整数数组的指针。只要您分配 ncols 的倍数(我们通过乘以 nrows 来实现),现在就可以使用您已经喜欢的熟悉的下标来访问生成的矩阵:

// for any n'th row, m'th column
ar[n][m] = value;

【讨论】:

  • 感谢您的回复!我其实很喜欢这种方法,我从来没想过用这种方式实现多维数组……而且确实看起来管理起来更简单!
  • @tom1990 只要您在访问之前检查 [n,m] 值(0int ar[10][20];,所以这对我来说似乎很自然。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-11-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-04-11
相关资源
最近更新 更多