将数组替换为 C 中的另一个数组
出于纯粹的好奇心,我开始以以前从未使用过的方式使用数组。我尝试制作一个数据结构数组,并将其设置为等于另一个:
typedef struct _test {
float value;
} test;
足够简单的struct
,所以我尝试了这个:
test struct1[10];
test struct2[20];
struct1 = struct2;
我认为这行不通,而且它甚至无法编译。但是,这让我很感兴趣。是否可以在复制数据的同时将 10 个数组的大小增加到 20?
Objective-C
我实际上是用 Objective-C 来做这件事,所以我也想听听 Objective-C 人员的意见。我想看看是否可以更改此文件中 struct1 的大小。
@interface Object : NSObject {
test struct1;
}
记住:这只是出于好奇,所以一切都可以讨论。
Out of pure curiosity, I started playing with array's in ways that I have never used before. I tried making a data structure array, and set it equal to another:
typedef struct _test {
float value;
} test;
Simple enough struct
, so I tried this:
test struct1[10];
test struct2[20];
struct1 = struct2;
I didn't think this would work, and it didn't even compile. But, this interests me a lot. Is it possible to take an array of 10 and increase the size to 20, while copying the data?
Objective-C
I am actually doing this with Objective-C, so I'd like to hear from the Objective-C people as well. I want to see if it is possible to change the size of struct1
in this file.
@interface Object : NSObject {
test struct1;
}
Remember: This is only out of curiosity, so everything is open to discussion.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(7)
其他与您的问题不完全相关但仍然有趣的事情是,虽然不能分配数组,但可以分配包含数组的结构可以:
这也使得返回固定长度数组成为可能来自函数的数据(因为不允许返回普通数组):
Something else that is not exactly pertinent to your question but is interesting nonetheless, is that although arrays cannot be assigned to, structs containing arrays can be assigned to:
This also makes it possible to return fixed-length arrays of data from functions (since returning plain arrays is not allowed):
正如其他人所说,这样分配的数组是静态的,并且不能调整大小。您必须使用指针(使用
malloc
或calloc
分配数组)来获得可调整大小的数组,然后您可以使用realloc
。你必须使用free
来摆脱它(否则你会泄漏内存)。在 C99 中,数组大小可以在分配时在运行时计算(在 C89 中,其大小必须在编译时计算),但在分配后不能更改。在 C++ 中,您应该使用std::vector
。我怀疑 Objective-C 有类似 C++ 的向量的东西。但是,如果您想在 C 中的一个数组和另一个数组之间复制数据,请使用 memcpy:
当然,这只会复制前 10 个元素,因为 struct1 只有 10 个元素长。例如,您可以通过将
&struct2
更改为struct2+10
或&(struct2[10])
来复制最后十个。当然,在 C 中,不运行超出数组末尾是您的责任:memcpy 不检查。您也可以使用明显的 for 循环,但 memcpy 通常会更快(并且永远不会更慢)。这是因为编译器可以利用它知道的每一个技巧(例如,它可能知道如何一次复制 16 个字节的数据,即使每个元素只有 1 个字节宽)
As others have said, arrays allocated like that are static, and can not be resized. You have to use pointers (allocating the array with
malloc
orcalloc
) to have a resizable array, and then you can userealloc
. You must usefree
to get rid of it (else you'll leak memory). In C99, your array size can be calculated at runtime when its allocated (in C89, its size had to be calculated at compile time), but can't be changed after allocation. In C++, you should usestd::vector
. I suspect Objective-C has something like C++'s vector.But if you want to copy data between one array and another in C, use
memcpy
:That'll only copy the first ten elements, of course, since struct1 is only ten elements long. You could copy the last ten (for example) by changing
&struct2
tostruct2+10
or&(struct2[10])
. In C, of course, not running off the end of the array is your responsibility:memcpy
does not check.You can also you the obvious for loop, but memcpy will often be faster (and should never be slower). This is because the compiler can take advantage of every trick it knows (e.g., it may know how to copy your data 16 bytes at a time, even if each element is only 1 byte wide)
在 C 语言中,您无法使用静态数组执行此操作,但可以使用动态分配的数组执行此操作。例如,
You can't do this in C with static arrays, but you can do it with dynamically allocated arrays. E.g.,
在 C 中,我相信这是使用 realloc 函数的好地方。但是,它仅适用于动态分配的数组。无法通过声明
test struct1[10];
更改分配给struct1
的内存。In C, I believe that's a good place to use the realloc function. However, it will only work with dynamically allocated arrays. There's no way to change the memory allocated to
struct1
by the declarationtest struct1[10];
.在 C 语言中,数组是常量,您根本无法更改它们的值(即它们的地址),也无法调整它们的大小。
In C arrays are constants, you can't change their value (that is, their address) at all, and you can't resize them.
显然,如果您声明数组具有固定大小,
test struct1[10]
则无法调整其大小。您需要做的是将其声明为指针:然后您必须使用
malloc
来分配数组,并可以使用realloc
来调整它的大小,同时保留原始内容大批。Clearly if you declare your array with a fixed size,
test struct1[10]
then it cannot be resized. What you need to do is to declare it as a pointer:Then you must use
malloc
to allocate the array and can userealloc
to resize it whilst preserving the contents of the original array.如果您使用的是 Objective C,您知道您可以使用 NSMutableArray,它会自动执行重新分配技巧来重新分配自身以存储您放入其中的对象数量,直至达到内存限制。
但你想用 struct 来做到这一点?这意味着什么?假设您增加了 Object 中 struct1 的可用内存量。它仍然是一个只有一个成员的结构,并且不再执行任何操作。
是让 Object 能够包含扩展结构的想法吗?
但是你仍然无法正常访问
reference
,因为它不是Object的已知部分。如果您知道您有一个修改过的对象,您可以这样做
并且您仍然可以将 object2 传递给任何需要 Object 的对象。仅当 struct1 是 Object 的最后一个成员时,它才有可能工作,并且也不要混淆 Object 的子类化。
然后,某种类型的 realloc 技巧可能会起作用,但我不认为 realloc 特别重要,因为它旨在用于使用 malloc 分配的对象,并且使用 C 函数来分配对象的详细信息未在 Objective 中公开C,所以你不应该假设它是 malloc。如果您重写
alloc
,那么您也许能够确保使用malloc。另外,您还必须注意这样一个事实:在 Objective C 中,存在多个指向对象的指针是很常见的。 realloc 可能会移动一个对象,除非您更正所有指针,否则这在语义上是不正确的。
If you're using Objective C, you know you can just use NSMutableArray, which automatically does the realloc trick to reallocate itself to store however many objects you put in it, up the limit of your memory.
But you're trying to do this with struct? What would that even mean? Suppose you increase the amount of memory available to struct1 in Object. It's still a struct with one member, and doesn't do anything more.
Is the idea to make Object be able to contain an expanded struct?
But then you still can't access
reference
normally, because it's not a known part of Object.If you knew you had one of your modified objects, you could do
And also you could still presumably pass object2 to anything that expects an Object. It only has any chance of working if struct1 is the last member of Object, and don't mess with subclassing Object either.
Some variety of realloc trick might then work, but I don't think realloc in particular, because that's intended to be used on objects that are allocated with malloc, and the details of what C function is used to allocate objects in not exposed in Objective C, so you shouldn't assume it's malloc. If you override
alloc
then you might be able to make sure malloc is used.Also you have to watch out for the fact that it's common in Objective C for more than one pointer to an object to exist. realloc might move an object, which won't be semantically correct unless you correct all the pointers.