首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在C中高效地初始化数组/数据块

在C中高效地初始化数组/数据块
EN

Stack Overflow用户
提问于 2011-12-17 01:50:14
回答 4查看 903关注 0票数 0

我试图用C语言初始化一个数组,对于每个元素,GCC都会生成一条mov指令(如果有很多元素需要初始化,这是一种低效的方法)。我如何用数组数据加载内存并从中返回一个指针,而不是以这种方式初始化?

代码语言:javascript
复制
6:array.c       ****         int a[]={1,2,3,4,5,9};
26                      .loc 1 6 0
27 0008 C745E001        movl    $1, -32(%rbp)
27      000000
28 000f C745E402        movl    $2, -28(%rbp)
28      000000
29 0016 C745E803        movl    $3, -24(%rbp)
29      000000
30 001d C745EC04        movl    $4, -20(%rbp)
30      000000
31 0024 C745F005        movl    $5, -16(%rbp)
31      000000
32 002b C745F409        movl    $9, -12(%rbp)
32      000000
EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2011-12-17 02:05:03

我相信下面的答案回答了你的问题“我将如何用数组数据加载内存并返回一个指针?”:

代码语言:javascript
复制
int a_data[] = {1,2,3,4,5,9};

int main() {
  int *a = a_data;
}

这将编译为:

代码语言:javascript
复制
        .data
a_data:
        .long   1
        .long   2
        .long   3
        .long   4
        .long   5
        .long   9

        .text
main:
        .cfi_startproc
        pushq   %rbp
        .cfi_def_cfa_offset 16
        movq    %rsp, %rbp
        .cfi_offset 6, -16
        .cfi_def_cfa_register 6
        movq    $a_data, -8(%rbp)
        leave
        ret
        .cfi_endproc

正如您所看到的,值位于数据段中,而main()只是将指针指向数据。

当然,如果你突变了a[],下次你取a_data的地址时,这些突变仍然存在。如果您希望获得原始值,则应该制作a_data的副本,而不是简单地使用指向它的指针。

票数 3
EN

Stack Overflow用户

发布于 2011-12-17 01:54:18

我假设a是一个局部变量,对吗?尝试将数组声明为静态--那么它的数据应该是从文本块加载的。然而,变量的含义和它的初始化将会改变。

票数 1
EN

Stack Overflow用户

发布于 2011-12-17 02:22:41

根据您的需求,您有两个简单的选择:

1)设置为静态

代码语言:javascript
复制
void bar(const int *);

void foo() {
    static int a[]={1,2,3,4,5,9};

    bar(a);
}

收益率-这只是对静态数据的引用。

代码语言:javascript
复制
foo:
.LFB0:
        .cfi_startproc
        movl    $a.1591, %edi
        jmp     bar
        .cfi_endproc
.LFE0:
        .size   foo, .-foo
        .data
        .align 16
        .type   a.1591, @object
        .size   a.1591, 24
a.1591:
        .long   1
        .long   2
        .long   3
        .long   4
        .long   5
        .long   9

如果您需要非静态或常量的数据,则可以选择另一种方法。就是把静态数据放在周围,然后自己做一个memcpy,把它移到合适的地方。有趣的是,优化的gcc随后会使用各种to策略将其复制到位。

代码语言:javascript
复制
void bar(const int *);

void foo() {
    static int s[]={1,2,3,4,5};
    int a[sizeof(s)/sizeof(s[0])];
    memcpy(a, s, sizeof(s));

    bar(a);
}

总之,代码是必要的,因为数据的内存位置在编译时是不固定的,因此一些代码需要将数据复制到内存中。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/8538121

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档