【问题标题】:How can I perform looped macro in C如何在 C 中执行循环宏
【发布时间】:2014-10-21 13:24:55
【问题描述】:

我定义了一些宏,例如

#define NUM_A 3
#define A1 10
#define A2 100
#define A3 8

总计数和值特定于设备。 现在我需要一个数组看起来像

int Array[NUM_A]={A1, A2, A3};

现在,如果总数,NUM_A 变为 4,并且我已经定义了宏 A4,但我忘记将 A4 附加到数组中。实际的数组是 {A1, A2, A3, 0}。编译时不会出错。运行程序时也很难发现错误。当我在头文件中编写宏并在源文件中声明数组时,更有可能发生这种情况。 我可以编写一个循环宏来通过定义的宏 NUM_A、A1、A2 和 A3 生成数组吗?或者如果编译或运行时出现错误,我可以写一个断言或其他东西来警告自己吗?

【问题讨论】:

  • Boost 有工具可以做到这一点。我想它们是 C 兼容的……我的意思是,它们一定是,对吧?无论如何,总而言之,你必须编写可怕的宏魔法......但它可能的。
  • @LightnessRacesinOrbit Boost 适用于 C++,为什么“必须”它与 C 兼容?我随机查看的任何 Boost 代码一直都在模板中。
  • 简单地省略声明中的元素数量怎么样,如stackoverflow.com/questions/9846920/define-array-in-c
  • @Codor 无助于检测 OP 忘记更新值列表以匹配预期元素数量的情况。

标签: c macros


【解决方案1】:

只是一个问题/建议。

你真的需要“NUM_A”吗?至少从代码 sn-p 的角度来看,它不是必需的。不确定您是否将它用于其他目的。

您可以将数组声明为:

int Array[] = {A1, A2, A3}; /* So this becomes the only place to be modified, just add A4 in the future. No confusion with array size */

NUM_A 等价于“sizeof Array / sizeof Array[0]”。

示例:

  int arr[] = {A1, A2, A3};
  int i;

  for(i = 0; i < sizeof arr / sizeof arr[0]; i++)
  {
    printf("%d\n", arr[i]);
  }

【讨论】:

  • +1,但更好的是sizeof arr / sizeof arr[0]。这使得类型更改更加健壮。
  • 开放数组操作符已经解决了这个问题。谢谢。
【解决方案2】:

你可以断言数组是预期的大小:

assert(sizeof(Array) == NUMA * sizeof(Array[0]));

这是运行时检查。根据您的编译器版本,在编译时有多种方法可以做到这一点;见Static assert in C

【讨论】:

    【解决方案3】:

    除了使用开放数组运算符将变量声明为 A.M.D.已显示:

      int arr[] = {A1, A2, A3};
    

    您还可以定义一个较短的 sizeof arr/sizeof arr[0] 表示形式,方法是定义一个宏来替换代码中定义 arr 的任何位置的该语句,如下所示:

    #define ARR_SIZE sizeof arr/sizeof arr[0]  
    

    宏将在运行时计算数组元素的数量,并且适应运行时数组中元素数量的变化,无需编辑宏。

    对于arr[] = {1,2,5,8,9,3}; ARR_SIZE 将计算为 6
    对于arr[] = {1,2,5,8,9,3,4,7,1,0,4}; ARR_SIZE 将评估为 11

    这是一种有用的代码可读性技术,例如循环:

    for(i=0;i< ARR_SIZE;i++); // is more readable
    
    for(i=0;i< sizeof arr/sizeof arr[0];i++); // is less readable
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-05-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-03-07
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多