Objective c 用C中的另一个数组替换数组

Objective c 用C中的另一个数组替换数组,objective-c,c,arrays,Objective C,C,Arrays,出于纯粹的好奇心,我开始用我以前从未用过的方式玩array。我尝试制作一个数据结构数组,并将其设置为另一个: typedef struct _test { float value; } test; 结构非常简单,所以我尝试了以下方法: test struct1[10]; test struct2[20]; struct1 = struct2; 我认为这是行不通的,它甚至没有编译。但是,这让我很感兴趣。复制数据时,是否可以采用10的数组并将大小增加到20 目标-C 我实际上是在用Obje

出于纯粹的好奇心,我开始用我以前从未用过的方式玩array。我尝试制作一个数据结构数组,并将其设置为另一个:

typedef struct _test {
   float value;
} test;
结构非常简单,所以我尝试了以下方法:

test struct1[10];
test struct2[20];
struct1 = struct2;
我认为这是行不通的,它甚至没有编译。但是,这让我很感兴趣。复制数据时,是否可以采用10的数组并将大小增加到20

目标-C

我实际上是在用Objective-C做这件事,所以我也想听听Objective-C人员的意见。我想看看是否可以更改此文件中
struct1
的大小

@interface Object : NSObject {
    test struct1;
}

记住:这只是出于好奇,所以一切都可以讨论。

在C中,我相信这是使用realloc函数的好地方。但是,它只适用于动态分配的阵列。无法通过声明
test struct1[10]更改分配给
struct1
的内存是常量,您根本无法更改它们的值(即它们的地址),也无法调整它们的大小。

显然,如果您使用固定大小声明数组,
test struct1[10]
则无法调整其大小。您需要做的是将其声明为指针:

test *struct1;
然后必须使用
malloc
分配数组,并可以使用
realloc
调整数组大小,同时保留原始数组的内容

struct1 = malloc(10*sizeof(*struct1));
//initialize struct1 ...
test *struct2 = realloc(struct1, 20*sizeof(*struct1));

在C中,不能用静态数组实现这一点,但可以用动态分配的数组实现。例如:

float *struct1, *struct2, *struct3;
if(!(struct1 = malloc(10 * sizeof(float))) { 
  // there was an error, handle it here
}
if(!(struct2 = realloc(struct1, 20 * sizeof(float))) {
  // there was an error, handle it here
  // struct1 will still be valid
}
if(!(struct3 = reallocf(struct2, 40 * sizeof(float))) {
  // there was an error, handle it here
  // struct2 has been free'd
}

正如其他人所说,这样分配的数组是静态的,不能调整大小。您必须使用指针(使用
malloc
calloc
分配数组)来获得可调整大小的数组,然后才能使用
realloc
。您必须使用
free
清除它(否则会泄漏内存)。在C99中,您的数组大小可以在分配时在运行时计算(在C89中,它的大小必须在编译时计算),但在分配后不能更改。在C++中,应该使用<代码> STD::vector < /代码>。我怀疑Objective-C有点像C++的向量

但如果要在C中的一个数组和另一个数组之间复制数据,请使用
memcpy

/* void *memcpy(void *dest, const void *src, size_t n)
   note that the arrays must not overlap; use memmove if they do */
memcpy(&struct1, &struct2, sizeof(struct1));
当然,这只会复制前十个元素,因为struct1只有十个元素长。您可以通过将
&struct2
更改为
struct2+10
&(struct2[10])
来复制最后十个(例如)。当然,在C语言中,不从数组末尾运行是您的责任:
memcpy
不检查


您也可以使用显而易见的for循环,但是memcpy通常会更快(而且永远不会慢)。这是因为编译器可以利用它知道的每一个技巧(例如,它可能知道如何一次复制16个字节的数据,即使每个元素只有1个字节宽)

另一个与您的问题不完全相关但很有趣的是,尽管数组无法分配给,可以将包含数组的结构分配给:

struct test
{
    float someArray[100];
};


struct test s1 = { /* initialise with some data*/ };
struct test s2 = { /* initialise with some other data */ };

s1 = s2; /* s1's array now contains contents of s2's array */
这还可以从函数返回固定长度的数据数组(因为不允许返回普通数组):

struct测试函数,生成100个浮点(void)
{
结构测试结果;
对于(int i=0;i<100;i++)
result.someArray[i]=randomfloat();
返回结果;
}

如果您使用的是Objective C,您知道您可以使用NSMutableArray,它会自动执行realloc技巧,在内存限制内重新分配自身以存储放入其中的对象数量

但你想用struct做这个?那意味着什么?假设您增加了对象中struct1的可用内存量。它仍然是一个只有一个成员的结构,不再做任何事情

使对象能够包含扩展结构的想法是什么

typedef struct _test2 {
    float value;
    NSObject *reference;
} test2;
但您仍然无法正常访问
引用
,因为它不是对象的已知部分

Object *object2;
...
NSLog(@"%@", object2.struct1.reference); // does not compile
如果您知道您有一个修改过的对象,您可以这样做

Object *object2;
...
NSLog(@"%@", ((test2)(object2.struct1)).reference);
您还可以将object2传递给任何需要对象的对象。只有当struct1是对象的最后一个成员时,它才有可能工作,而且也不要搞乱对象的子类化

一些不同的realloc技巧可能会起作用,但我不认为realloc是特别的,因为它是用于分配malloc的对象的,而C函数分配对象的细节在目标C中没有公开,所以你不应该假设它是malloc。如果覆盖
alloc
,则可以确保使用malloc


此外,您还必须注意这样一个事实:在目标C中,存在多个指向对象的指针是很常见的。realloc可能会移动一个对象,除非您更正所有指针,否则它在语义上是不正确的。

realloc在动态分配的指针上工作,而不是在数组(由编译器分配)。嗯,是的。我相信我是这么说的。所以如果我使用
malloc
函数,
realloc
将是一个不错的选择?@Justin-是的。看一看如何使用它。(不要忘了在最后释放内存。)有趣的方法。我以前从未听说过这个,但对我来说很有意义。我假设sizeof()不应该只是一个数值常量?@Justin:
sizeof
实际上是一个数值常量,它只是让编译器为您计算。它还知道编译器决定如何布局您的数据(例如,它可能添加的任何填充)。我不知道这一点。这是一个非常好的方法。Objto-C语言没有一个可调整的数组类型,但是基础工具包框架(这是大多数ObjuleC程序员使用的)有<代码> NSMutableArray <代码>。情况可能是这样的,但是考虑它还是有趣的。
Object *object2;
...
NSLog(@"%@", ((test2)(object2.struct1)).reference);