C语言 如何迭代结构数组
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/18914960/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to iterate over of an array of structures
提问by Dariusz
In my application I use an array of structs and I need to iterate over the array. What is the proper way to do it? How can I check if I have reached the end of the array?
在我的应用程序中,我使用了一个结构数组,我需要遍历该数组。什么是正确的方法呢?如何检查我是否已到达数组的末尾?
// structure
struct MyData {
int count;
char name[20];
float average;
}
I have tried iterating like this, but my application crashes:
我试过这样迭代,但我的应用程序崩溃了:
struct MyData data[2] = { {3, "name1", 1.0}, {5, "name2", 2.5} };
struct MyData* ptr = data;
while (*ptr != NULL) {
// print the contents, works ok for 2 elements
ptr++; // increment the pointer
}
回答by Dariusz
How is an array of structs allocated
如何分配结构数组
In your case, the MyData[2]array looks like this in memory:
在您的情况下,MyData[2]数组在内存中如下所示:
| count | name | average | count | name | average |
^ -- your ptr points here
This is a single, continuous space with size 3 * sizeof (struct MyData).
这是一个大小为 的单个连续空间3 * sizeof (struct MyData)。
Whenever you perform a ptr++operation the pointer will move to the next structure in the array, which means that it takes into account the size of a single struct MyData.
每当您执行ptr++操作时,指针将移动到数组中的下一个结构,这意味着它考虑了单个struct MyData.
| count | name | average | count | name | average |
^ -- after ptr++ your ptr points here
After another ptr++your pointer will point to the memory just afteryour array.
又一次,ptr++您的指针将指向数组之后的内存。
| count | name | average | count | name | average |
^ -- another ptr++ and your ptr points here
When you dereference your ptrpointer you access memory which is not yet used or even allocated. This is undefined behavior and because of that your application crashes.
当您取消引用您的ptr指针时,您将访问尚未使用甚至未分配的内存。这是未定义的行为,因此您的应用程序崩溃。
How to iterate?
如何迭代?
There are several ways to do it. Note that not all ways are applicable in all cases.
有几种方法可以做到。请注意,并非所有方式都适用于所有情况。
A simple for
一个简单的
Very often we simply know the size of the array. We can then just use a normal forloop to iterate over the contents.
很多时候我们只知道数组的大小。然后我们可以使用普通for循环来迭代内容。
int len = 2;
struct MyData data[len] = { {3, "name1", 1.0}, {5, "name2", 2.5} };
struct MyData* ptr = data;
for (int i=0; i<len; i++, ptr++ ) {
// do your thing with the ptr
// and note that ptr gets increased inside for
}
Using sizeof to determine array length
使用 sizeof 确定数组长度
struct MyData data[2] = { {3, "name1", 1.0}, {5, "name2", 2.5} };
struct MyData* ptr = data;
struct MyData* endPtr = data + sizeof(data)/sizeof(data[0]);
while ( ptr < endPtr ){
// do your thing with the ptr
ptr++;
}
The sizeof(data)/sizeof(data[0])calculates the amount of elements: gets the total size of an array and divides it by the size of a single element.
所述sizeof(data)/sizeof(data[0])计算元件的量:由单个元件的尺寸得到的阵列和将其划分的总大小。
This method has its drawbacks. It can not be used when the array is declared as a pointer! For example, when we pass the array as a parameter to a function it usually gets converted to a pointer - and then we can not determine the size of the array.
这种方法有其缺点。数组声明为指针时不能使用!例如,当我们将数组作为参数传递给函数时,它通常会转换为指针 - 然后我们无法确定数组的大小。
回答by Oragon Efreet
If you don't have any control on the size of the array and can even not ask for it, you could try reorganize your code, not using an array of MyDatabut an array of pointersto MyData.
Your array must then be one slot longer to store a guard with NULLvalue.
如果没有对数组的大小任意控制,甚至可以不问它,你可以尝试重新组织你的代码,而不是使用数组MyData,但数组的指针来MyData。你的数组必须多一个槽来存储一个有NULL值的守卫。
Your iteration will look like the one you wrote as an example.
您的迭代将类似于您作为示例编写的迭代。
// N is the number of MyData instances you have
MyData* vData[N+1];
// vData[i] is filled, and vData[N] = NULL
// ...
MyData* vPtr = vData[0];
while(vPtr) {
// ...
}
But this involves changing the type of your array from MyData[]to MyData*[]. If you can't, you should follow Dariusz answer.
但这涉及将数组的类型从 更改MyData[]为MyData*[]。如果你不能,你应该按照 Dariusz 的回答。

