【问题标题】:Array of size 1 vs. pointer to struct大小为 1 的数组与指向结构的指针
【发布时间】:2016-04-29 03:07:09
【问题描述】:

假设我有一个函数,它接受一个结构数组,定义如下:

void Foo(struct MyStruct *s, int count) {
    for (int i = 0; i < count; ++i) {
        // Do something with s[i]
    }
}

是否保证以下两个 sn-ps 的行为方式相同?

struct MyStruct s;
s.x = 0;
s.y = 0;
Foo(&s, 1);

对比

struct MyStruct s[1]; // stack-allocated array of size 1
s[0].x = 0;
s[0].y = 0;
Foo(s, 1);

【问题讨论】:

标签: c arrays pointers


【解决方案1】:

答案是肯定的,它们实际上是相同的。首先,当在函数参数中使用时,数组作为指向其第一个元素的指针传递。实际上,在存储方面,C 中的所有对象都可以被视为该类型的一个元素的数组。

【讨论】:

    【解决方案2】:

    它们是相同的;证明 - 我为这两个代码示例编译并保存了 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 中,字面上唯一的区别是:

    1. cmets 中的变量名(s vs as)
    2. 引用的行号(因为每个版本中未注释不同的行号)。

    因此,可以安全地假设这两种方法是相同的。

    【讨论】:

      【解决方案3】:

      是的。这两个选项都是堆栈分配的,并且正好创建一个struct MyStruct 的“实例”。您的编译器应该为这两个选项输出相同的机器代码。有关详细信息,请参阅 this link (C) 和 this link (C++)。

      【讨论】:

      • 操作员询问的是 C,链接是关于 C++ 和 Java。
      • 不完全...它解释了堆栈分配在 C++ 中的工作原理以及它与 Java 的关系——尽管它将 C++ 与 Java 进行了比较,但它解释了堆栈分配的工作原理。我刚刚添加了另一个链接,它也解释了纯 C 的堆栈分配。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-06-03
      • 2014-07-08
      • 1970-01-01
      • 2012-12-07
      • 2016-06-20
      相关资源
      最近更新 更多