【问题标题】:C: Can I do static intialization of an array with both size and address?C:我可以对具有大小和地址的数组进行静态初始化吗?
【发布时间】:2021-02-02 07:30:33
【问题描述】:

(如何)通过同时指定地址和元素数量(“大小”)来初始化 C 数组?

使用元素计数进行静态初始化:

static int foo[4] = {0, 1, 2, 3};

这很好,因为人类阅读器、linter 和编译器都知道数组元素的数量。

带地址的静态初始化:

static int* foo = (int*)address_of_foo;

这不是很好,因为元素的数量是未知的。

使用元素计数和地址进行静态初始化?

考虑将大型数组存储在其他地方(例如,在非源代码文件或嵌入式系统上的不同硬件寄存器中)。我知道这个数组的地址,也知道它的大小,但我想拥有在代码中指定大小的所有优点。这有可能吗?以下代码

static int foo[4] = (int*) address_of_foo;

编译失败,例如出现此错误:error: array initializer must be an initializer list

是否有解决方案或 C 编译器不支持?

【问题讨论】:

  • 你不能分配一个数组的地址。或任何其他变量。不是通过编译器。您可以使用一些编译器扩展和/或一些链接器魔法(例如将变量放在具有已知地址的特定部分中)。
  • C 不关心一维数组的长度。与以往一样,如果您知道它的长度,则可以在代码中使用它来保持在界限内,int* 指针将完成这项工作。如果您希望信息在一个地方,您可以使用struct 来包含指针和数据长度。
  • @WeatherVane:我知道inf* 指针可以完成这项工作,但它并不好。在阅读代码时了解重要信息方面,我一直在寻找更好的解决方案。
  • struct data { int *address; size_t elements; } rec = { (int*)0xDEADBEEF, 42 }; 不是都在一个地方并且可读吗?
  • 编译器不检查数组边界,除非在定义点初始化。这留给程序员检查。

标签: arrays c static initialization


【解决方案1】:

你可以有这样一个指向数组的指针:

/* casting to (void *) since i am to lazy to figure out the correct casting */
static int (*foo)[4] = (void *) address_of_foo;

这样的缩小,是你必须在使用数组元素时取消引用指针:

(*foo)[2] =42;
/* A good compiler should hopefully give you a warning on this: */
(*foo)[95] = 42;

如果您愿意,可以将取消引用隐藏在 #define 后面:

static int (*foo_ptr)[4] = (void *) address_of_foo;
#define foo (*foo_ptr)

foo[2]=42;

我个人觉得这两种解决方案都有点“hackish”,所以我自己不会使用它们

【讨论】:

    猜你喜欢
    • 2021-06-08
    • 1970-01-01
    • 2014-10-31
    • 1970-01-01
    • 2010-10-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-01-11
    相关资源
    最近更新 更多