【问题标题】:Initialize a 2D array of unknown size using macros in C使用 C 中的宏初始化一个未知大小的二维数组
【发布时间】:2015-03-03 07:01:58
【问题描述】:

我正在处理一个小型宏项目,该项目需要我将二维数组文字传递给我的一个宏,如下所示:myMacro({{0, 1, 2}, {2, 1, 0}})。无需将数组文字的大小传递给宏,有没有办法让它扩展为以下内容:int[2][3] = { {0, 1, 2}, {2, 1, 0} } 或等效的东西(任何保留数组形状的初始化都可以工作)?在此先感谢您的帮助

【问题讨论】:

  • 是二维还是任意维度?另外,您是否有第二个索引(列数)的上限?
  • 它将始终是 2d,但它可以是任何宽度/长度。例如,它也可以称为myMacro{{1, 2, 3, 4}, {5, 6, 7, 8}})。没有上限,但每行的列数始终相同。
  • 试试可变参数宏?
  • @n.m.我目前正在使用可变参数宏,但我需要能够将__VA_ARGS__ 绑定到一个变量以供以后使用。
  • 哦,这是 C。我知道解决这个问题的唯一方法是窃取 Boost::Preprocessor 库。 Boost 是一个 C++ 库,但预处理器部分应该适用于 C,只需极少或无需修改。

标签: c arrays multidimensional-array c-preprocessor


【解决方案1】:
#include <boost/preprocessor/tuple/size.hpp>
#include <boost/preprocessor/tuple/elem.hpp>
#include <boost/preprocessor/variadic/to_seq.hpp>
#include <boost/preprocessor/seq/for_each.hpp>

#define VA(...) __VA_ARGS__
#define TRANS(r, data, elem) { VA elem},

#define myMacro(name, arg)\
    int name[BOOST_PP_TUPLE_SIZE(arg)][BOOST_PP_TUPLE_SIZE(BOOST_PP_TUPLE_ELEM(0,arg))] = \
    { BOOST_PP_SEQ_FOR_EACH(TRANS, , BOOST_PP_VARIADIC_TO_SEQ arg)}

int main(){
    myMacro(a, ((1,2,3),(4,5,6)) );//=>int a[2][3] = { { 1,2,3}, { 4,5,6}, };
    return 0;
}

【讨论】:

  • 哦,对不起,我直到现在才看到这个答案。这在 C (最好是 99 之前)中有效吗?我以为 Boost 只是 C++?
  • @NerdicViking 的 boost 预处理器的一部分甚至可以使用 C。不能保证使用 C99 以前的 C 的决定,但已确认使用 VC2010。
  • @BLUEPIXY 很酷,我不知道 Boost 有那种宏。我检查了 GCC,并且需要 C99 级别(之前在预处理器中会失败)。
  • @SanteriPaavolainen 是的,可变参数宏似乎来自 C99。
【解决方案2】:

如果您有第二个维度的上限,那么您可以使用标记值,例如:

#include <stdio.h>

#define MAXCOLUMNS 20
#define VALUE {{0,1,2,-1},{2,3,4,-1},{0,0,0,0,1,-1},{-1}}

int main()
{
  int v[][MAXCOLUMNS] = VALUE;
  int x, y;

  for (y = 0; v[y][0] != -1; y++)
    for (x = 0; v[y][x] != -1; x++)
      printf("[%d,%d] = %d\n", x, y, v[y][x]);

  return 0;
}

这将在事先不知道确切尺寸的情况下打印出值。这是您想要实现的目标吗?

编辑:@BLUEPIXYs 解决方案不需要知道或猜测最大尺寸,另一方面,这适用于较旧的 C 版本(虽然不是大问题)。

【讨论】:

  • 上限值可以工作,但仅适用于第一个元素。代码应该能够猜测有多少不同的行(一个对应于另一个宏创建的枚举的每个元素,我可以在末尾添加一个ENUM_SIZE 值来计算行数,但是各个列是未知的。
  • 我采用的解决方案是猜测它可能有多大。我试图用:#define VA_NUM_ARGS(_1, _2, _3, _4, N ...) N 做一些事情,但它最多只能工作 63 并且根据传递的数字也可能是错误的,所以我不能使用它。
猜你喜欢
  • 1970-01-01
  • 2023-04-11
  • 1970-01-01
  • 2020-10-11
  • 2012-04-06
  • 1970-01-01
  • 1970-01-01
  • 2014-10-27
  • 2014-04-21
相关资源
最近更新 更多