从另外两个数组创建静态分配的数组

时间:2016-11-06 18:57:02

标签: c arrays static-initialization

假设我有两个静态分配的全局数组:

const int foo[] = {1, 2, 3};
const int bar[] = {4, 5, 6, 7};

稍后在同一个编译单元中,我想声明一个静态分配的数组,它是foobar的串联:

const int foo_and_bar[] = ... ?

可能与否?

当然,我可以用像......这样的宏做丑事。

#define FOO_CONTENTS 1, 2, 3
#define BAR_CONTENTS 4, 5, 6, 7

const int foo[] = {FOO_CONTENTS};
const int bar[] = {BAR_CONTENTS};

const int foo_and_bar[] = {FOO_CONTENTS, BAR_CONTENTS};

...但我正在寻找C语言本身支持的习语。

4 个答案:

答案 0 :(得分:1)

严格来说,我不认为你可以用非扩展语言静态地做这个(我敢肯定像GCC这样的宽容编译器允许这里有几个选项,利用他们的C ++前端需要这种事情的事实)。两个相关的标准引用,重点是我的:

  

具有静态或线程存储持续时间的对象的初始值设定项中的所有表达式都应为常量表达式或字符串文字。

6.7.9 p4

  

数组下标[]和成员访问.->运算符,地址&和间接*一元运算符以及指针强制转换用于创建地址常量,但不能使用这些运算符访问对象的值。

6.6 p9

换句话说,虽然[]运算符在文件范围内有一些合法用途,但是当时不允许显式读取数组的内容。因此,要将一个数组的内容设置为等于另一个数组的内容,而不是简单地复制初始化程序(这在宏观解决方案中是机械上的),您必须在运行时执行一些工作

答案 1 :(得分:1)

以下是另一种方法:

由于所有三个数组都是只读的,因此您也可以只分配其中一个:

const int foo_and_bar[] = {1,2,3,4,5,6,7};

然后,使用指示每个子数组的索引和大小的其他变量:

int fooIndex = 0, fooSize = 3;
int barIndex = 3, barSize = 4;

答案 2 :(得分:1)

问题是所有静态存储持续时间变量都适用于初始化列表,这些列表需要是语言定义的编译时常量。另一个变量,即使声明为const,也不被视为编译时常量。此外,您无法初始化或直接从另一个阵列分配数组。

因为语言的限制所以你不能这样做。您的初始化列表#defines版本实际上是一个常见的解决方案。这是一个简单的解决方案,因此它可能是最好的解决方案。

如果您正在寻找以不同方式访问数据的方法,那么一种替代方案可能是联合会和C11匿名结构:

#include <stdio.h>

#define FOO_INIT 1, 2, 3
#define BAR_INIT 4, 5, 6, 7

#define FOO_SIZE ( sizeof((int[]){ FOO_INIT }) / sizeof(int) )
#define BAR_SIZE ( sizeof((int[]){ BAR_INIT }) / sizeof(int) )

typedef union
{
  int array [FOO_SIZE + BAR_SIZE];
  struct
  {
    int foo [FOO_SIZE];
    int bar [BAR_SIZE];
  };
} foobar_t;



int main (void)
{
  static const foobar_t foobar = { .foo = {FOO_INIT}, .bar = {BAR_INIT} };

  // print 1 2 3 4 5 6 7
  for(size_t i=0; i<FOO_SIZE + BAR_SIZE; i++)
  {
    printf("%d ", foobar.array[i]);
  }
}

现在,如果你想对数组进行硬拷贝,你实际上可以做foobar_t foobar2 = foobar;。 C非常奇怪,因为虽然它不允许分配数组,但是对于包含数组的结构/联合的分配来说完全没问题。 (但如果foobar2具有静态存储持续时间,那么这仍然无效。)

答案 3 :(得分:-2)

Yup! you can create another array whose size is the sum of both foo and bar . Then you can one by one copy the elements using looping statements. first loop will begin from 0 to the size of first array and second loop will begin from the size of first array to the size of the second array.