让我们说我有一个函数,它接受一个结构数组,定义如下:
void Foo(struct MyStruct *s, int count) {
for (int i = 0; i < count; ++i) {
// Do something with s[i]
}
}
以下两个片段是否保证以相同的方式运行?
struct MyStruct s;
s.x = 0;
s.y = 0;
Foo(&s, 1);
VS
struct MyStruct s[1]; // stack-allocated array of size 1
s[0].x = 0;
s[0].y = 0;
Foo(s, 1);
答案 0 :(得分:6)
答案是肯定的,它们实际上是一样的。首先,当在函数参数中使用时,数组作为指向其第一个元素的指针传递。实际上,在存储方面,C中的所有对象都可以被视为该类型的一个元素的数组。
答案 1 :(得分:3)
它们是相同的;证明 - 我为这两个代码示例编译并保存了MSVC 2015和GCC 4.9.3生成的汇编代码:
// Case 1: Pass by reference to single struct
typedef struct _mystruct
{
int x;
int y;
} mystruct;
void foo(mystruct *s, int count)
{
int i;
for(i = 0; i < count; i++)
{
(*(s + i)).x = 5;
(*(s + i)).y = 7;
}
}
int main()
{
mystruct ps;
//mystruct as[1];
foo(&ps, 1);
//foo(as, 1);
return 0;
}
我注意到foo
中的操作是随机的,与测试无关;它们只是为了防止编译器优化方法。
// Case 2: 1-length array
typedef struct _mystruct
{
int x;
int y;
} mystruct;
void foo(mystruct *s, int count)
{
int i;
for(i = 0; i < count; i++)
{
(*(s + i)).x = 5;
(*(s + i)).y = 7;
}
}
int main()
{
//mystruct ps;
mystruct as[1];
//foo(&ps, 1);
foo(as, 1);
return 0;
}
在生成的汇编文件中,在GCC上它们完全相同,而在MSVC中,字面上唯一的区别是:
因此,可以安全地假设这两种方法是相同的。
答案 2 :(得分:2)