请教大家一个C语言的宏的递归完成自增定义的方法
思路这这样的:为了测试,需要一个数据块,数据的形式是0x55aa0000,0x55aa0001,0x55aa0002,0x55aa0003 。。。,共n*4个字节,如果放在ram中太浪费,就想直接生成到flash
笨办法就是直接写死,比如
const uint32_t DATA={0x55aa0000,0x55aa0001,0x55aa0002,0x55aa0003 。。。,0x55aa003F};
但是为了能方便调整大小,就考虑用宏递归,而且最好前面的0x55aa也能用宏定义
在asf中有如下的宏
/*! \brief Macro repeat.
*
* This macro represents a horizontal repetition construct.
*
* \param countThe number of repetitious calls to macro. Valid values range from 0 to MREPEAT_LIMIT.
* \param macroA binary operation of the form macro(n, data). This macro is expanded by MREPEAT with
* the current repetition number and the auxiliary data argument.
* \param data Auxiliary data passed to macro.
*
* \return <tt>macro(0, data) macro(1, data) ... macro(count - 1, data)</tt>
*/
#define TPASTE2( a, b) a##b
#define MREPEAT(count, macro, data) TPASTE2(MREPEAT, count)(macro, data)
#define MREPEAT0(macro, data)
#define MREPEAT1(macro, data) MREPEAT0(macro, data) macro(0, data)
#define MREPEAT2(macro, data) MREPEAT1(macro, data) macro(1, data)
#define MREPEAT3(macro, data) MREPEAT2(macro, data) macro(2, data)
#define MREPEAT4(macro, data) MREPEAT3(macro, data) macro(3, data)
#define MREPEAT5(macro, data) MREPEAT4(macro, data) macro(4, data)
#define MREPEAT6(macro, data) MREPEAT5(macro, data) macro(5, data)
#define MREPEAT7(macro, data) MREPEAT6(macro, data) macro(6, data)
。。。。
#define MREPEAT256(macro, data) MREPEAT255(macro, data) macro(255, data)
然后我用这个宏来生成自增定义
#define KEY_HEADER 0x55aa0000
#define X 16
#define Y 4
#define KEY_SIZE X*Y
#define KEY_HEADER_PLUS(c,d) c+d,
const uint32_t DATA={ // 160 bytes = 40 words
MREPEAT(KEY_SIZE, KEY_HEADER_PLUS, KEY_HEADER)
};
期望得到的结果是:
const uint32_t DATA={ // 160 bytes = 40 words
0x55aa0000,0x55aa0001,0x55aa0002,0x55aa0003 。。。,0x55aa003F,
};
但是上面的那段程序总是报错,无法通过编译
pasting "MREPEAT" and "(" does not give a valid preprocessing token
不知道问题出在哪里?
正巧前几天看到这个帖子,可能会对你有帮助
https://www.amobbs.com/thread-5511786-1-1.html liansh2002 发表于 2019-1-18 13:41
正巧前几天看到这个帖子,可能会对你有帮助
https://www.amobbs.com/thread-5511786-1-1.html ...
谢谢,帖子里面傻孩子提到:宏MREPEAT实际上只能接受实际的数值,也就是说,这里的REQ_ITEM_COUNT_BYTE必须是一个常数,而不能是任何表达式
我把
#define KEY_SIZE X*Y
替换成
#define KEY_SIZE 64
编译通过
我的解释,不知道对不对:
当KEY_SIZE被定义为64
MREPEAT(KEY_SIZE, KEY_HEADER_PLUS, KEY_HEADER)
展开一步
MREPEAT40(KEY_HEADER_PLUS, KEY_HEADER),然后再递归展开
如果KEY_SIZE定义为 X*Y
展开一步
MREPEATX*Y(KEY_HEADER_PLUS, KEY_HEADER),所以就报错了
修改错别字 你为吗不直接写个巨大的数组,反正const我记得都在rodata里面。 wye11083 发表于 2019-1-18 14:37
你为吗不直接写个巨大的数组,反正const我记得都在rodata里面。
就是为了能生成一个巨大的数组,里面的数据由宏自动生成 你需要boost_pp
不光能自增,还能配合boost array进行枚举
不过不建议这么搞,可读性太差,还不如弄个脚本自动生成一下 liuqian 发表于 2019-1-18 14:45
就是为了能生成一个巨大的数组,里面的数据由宏自动生成
你的想法很有道理,这在生成有规律的数据时候很有用,我觉得你可以试试用脚本生成,也可以用tcc把c文件作为脚本 用类似iap的方式, 上电后写到flash里好了,一共也要不了几行代码。
tomzbj 发表于 2019-1-18 21:02
用类似iap的方式, 上电后写到flash里好了,一共也要不了几行代码。
这个方法也不不错 在pc机上用脚本生成你需要的数组代码,然后把代码拷贝到程序文件里,再编译。。。笨办法;
在pc上写个 c程序或者shell脚本,printf出来 const char xxx[]={xxx,xxx,xxx,xxx}; 直接excel写好公式然后一拉到底,然后另存为CVS文件,然后记事本打开另存为ASCII编码文件,连分隔符都做好成逗号了~ 11楼的方法是最方便的,再进一步改进如下:
第一步:直接excel写好公式然后一拉到底(优先选向右拉),然后另存为CVS文件,比如abc.cvs。
第二步:在你的C文件中写入const uint32_t DATA[]={
#include "abc.cvs"
};这个只要一开始写一次就行了,以后都不用改动。 #include "abc.cvs"这样用很方便 你们都没听说__COUNT__宏吧…… Gorgon_Meducer 发表于 2019-1-19 08:05
你们都没听说__COUNT__宏吧……
谢谢,头次听说,立刻试了试。
__COUNT__宏代换的结果是一个从0开始的整数,每次自动+1。
和编译器有关,在IAR for ARM V7.4 认,其他两个编译器不认。 本帖最后由 zhanan 于 2019-1-19 18:34 编辑
#define xxx __COUNTER__
#define MREPEAT0xxx
#define MREPEAT1xxx,MREPEAT0
#define MREPEAT2xxx,MREPEAT1
#define MREPEAT3xxx,MREPEAT2
u8 mmxx={MREPEAT3};=========== u8 mmxx={0,1,2,3};
或者
#define xxx __COUNTER__
#define MREPEAT0xxx,MREPEAT1
#define MREPEAT1xxx,MREPEAT2
#define MREPEAT2xxx,MREPEAT3
#define MREPEAT3xxx
u8 mmxx={MREPEAT0};=========== u8 mmxx={0,1,2,3};
zhanan 发表于 2019-1-19 15:43
谢谢,头次听说,立刻试了试。
__COUNT__宏代换的结果是一个从0开始的整数,每次自动+1。
Arm Compiler 和 IAR都支持,GCC自然不必说。 MARK C语言宏定义。。。。。。。。。。。
页:
[1]