【问题标题】:How to Concat Strings using macro or any other ways如何使用宏或任何其他方式连接字符串
【发布时间】:2021-04-16 04:13:53
【问题描述】:

我定义了类似的宏,只是它们的区别是数字。 例如

#define Function_01_Call(param)  (FunctionName((int)01, param))
#define Function_02_Call(param)  (FunctionName((int)02, param))
#define Function_03_Call(param)  (FunctionName((int)03, param))
#define Function_04_Call(param)  (FunctionName((int)04, param))

我想使用宏 Function_XX_Call 调用函数 FunctionName。如何将一个字符串用于宏并更改其数字?我试过了

#define FUNCTION_CALL(num)   Function_num_Call

 int main()
 {
    char num;
    for(num = "01"; num<="04"; num++)
    {
       FUNCTION_CALL(num); //HOW TO PASS param HERE?
    }
  }

但是如何在调用期间动态更改数字,因为变量不能在宏中使用。另外如何在通话期间传递参数?有没有办法使用函数指针?

【问题讨论】:

  • 这意味着什么?:char num; for(num = "01"
  • 您的真正问题是什么?请注意宏和 C 代码的不同“执行时间”:宏在编译期间扩展,但函数在运行时调用。
  • 确实如此。为什么你会发现自己处于拥有这 4 个宏的情况?

标签: c embedded c-preprocessor dynamic-function


【解决方案1】:

如何动态更改数字

最好是创建调用者和查找表。所以完全忽略整个处理器的东西并转移到运行时。

void function_call_01(int param) { Function_01_Call(param); }
void function_call_02(int param) { Function_02_Call(param); }
void function_call_03(int param) { Function_03_Call(param); }
void function_call_04(int param) { Function_04_Call(param); }

static void (*const function_calls[])(int) {
    function_call_01,
    function_call_02,
    function_call_03,
    function_call_04,
};
static const function_calls_cnt = sizeof(function_calls)/sizeof(*function_calls);

void function_call(size_t idx, int param) {
   assert(idx < function_calls_cnt);
   function_calls[idx](param);
}

int main() {
    for (size_t i = 0; i < function_calls_cnt; ++i) {
         function_call(i, 62);
    }
}

预处理器是静态的,编译后无法更改。如果你想让任何东西依赖于运行时的东西,你必须在运行时而不是在预处理器中编写它。

函数列表和数组定义可以用 FOREACH 宏“缩短”,例如 P99_SEQBOOST_PP_SEQ_FOR_EACH 或类似的。

【讨论】:

  • 对于将单个函数调用分派到四个单独的函数来说,这是一个有价值的答案。然而,OP 的问题似乎表明他/她正在寻找相反的东西:四个函数调用调度到一个函数。但话又说回来,这个问题令人困惑......
  • 我认为#define Function_01_Call(param) (FunctionName((int)01, param)) 中的FunctionName 只是一个模板,在实际代码中FunctionName 对于每个宏都不同。 OP 想要实现#define FUNCTION_CALL(num) Function_num_Call 调度。但可以肯定 - OP 代码可能只是 FunctionName(i, param),因为所有 4 个宏都是相同的......
【解决方案2】:

你不能!

因为 for 循环将在运行时执行,但宏会在预处理器阶段进行扩展,甚至在编译之前。 显然num的值是未知的,当时无法在宏中展开。

for(num = 1; num<=4; num++)
{
   FUNCTION_CALL(num); //HOW TO PASS param HERE?
}

顺便说一句。您不能在char 中存储两个字符的字符串

你可以做类似的事情

#define __PASTE1(a,b,c)  __PASTE2(a,b,c)
#define __PASTE2(a,b,c)  a##b##c
#define FUNCTION_CALL(num,param)   __PASTE1(Function_,num,_Call)(param)

int main()
{
  FUNCTION_CALL(01); // Expands to Function_01_Call(param)
  FUNCTION_CALL(02);
  FUNCTION_CALL(03);
  FUNCTION_CALL(04); // Expands to Function_04_Call(param)
}

【讨论】:

  • 感谢您的回复!为什么这里使用两个不同的宏 __PASTE1 和 __PASTE2?宏中__的意义是什么?
  • @A.BHi __ 对宏没有特殊意义,我只是用它来表明它是一个 internal 宏。 ## 是预处理器中的连接标记。在这种情况下,您不需要两个 __PASTE 宏,只是我的习惯是避免其他问题,例如创建字符串
猜你喜欢
  • 1970-01-01
  • 2017-10-03
  • 2021-03-29
  • 2020-10-28
  • 2019-11-18
  • 2015-06-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多