#define SATA_PORT_0 "/sata-ahci/port0"
#define SATA_PORT_1 "/sata-ahci/port1"
#define SATA_PORT_2 "/sata-ahci/port2"
#define SATA_PORT_3 "/sata-ahci/port3"
#define SATA_PORT_4 "/sata-ahci/port4"
#define SATA_PORT_5 "/sata-ahci/port5"
#define SATA_NODE(p) HOW TO DEFINE THIS?!!
int main()
{
int i;
for (i=0;i<6;i++)
{
printf("%s\n", i, SATA_NODE(i));
}
return 0;
}
问题:如何定义上面的宏,在GCC中打印出字符串?
答案 0 :(得分:2)
你不能用宏来做到这一点。
问题是宏是一个编译时构造,你在那里的循环是一个运行时构造;你不能直接做到。
您可以调查Boost Preprocessor(这不是专门用于C ++;它也适用于C预处理器)并使用它来编写生成循环的宏。
您可以手动展开循环并使用带有常量参数的宏:
#define SATA_PORT(i) "/sata-ahci/port" #i
printf("%s\n", 0, SATA_PORT(0));
printf("%s\n", 1, SATA_PORT(1));
printf("%s\n", 2, SATA_PORT(2));
printf("%s\n", 3, SATA_PORT(3));
printf("%s\n", 4, SATA_PORT(4));
printf("%s\n", 5, SATA_PORT(5));
或者您可以使用字符串数组(也可以通过现在删除的答案建议)。
#define DIM(x) (sizeof(x)/sizeof(*(x)))
const char * const sata_ports[] =
{
"/sata-ahci/port0",
"/sata-ahci/port1",
"/sata-ahci/port2",
"/sata-ahci/port3",
"/sata-ahci/port4",
"/sata-ahci/port5"
};
for (int i = 0; i < DIM(sata_ports); i++)
printf("%d %s\n", i, sata_ports[i]);
答案 1 :(得分:1)
用C语言你不能。宏替换发生在普通编译之前。预处理器不知道预处理令牌i将在以后的普通编译期间被声明为int。
执行甚至更晚。编译器可以发现我的值将介于0到5之间,但这对你没有帮助。实际的分配在执行期间发生,这是在编译完成之后,即在预处理完成之后。
答案 2 :(得分:0)
感谢您的上述答案。我找到了一种自己做的方法。
#define SATA_PORT(p) (p==0)?SATA_PORT_0:ISP1
#define ISP1 (p==1)?SATA_PORT_1:ISP2
...
在某些情况下,上面的宏会使代码更好。
答案 3 :(得分:0)
编辑:我已经使解决方案更好一些(因为GCC编译器中compound statements的可用性)。
如果我有类似的问题,我会这样解决:
#define SATA_PORT(p) ({char prt[100]; sprintf(prt, "/sata-ahci/port%d", p); prt;})
顺便说一下,你忘记了变量printf
的{{1}}格式说明符。
答案 4 :(得分:0)
也许这就是你需要的(编辑):
#define STRINGIFY(x) #x
#define TOSTRING(x) STRINGIFY(x)
#define SATA_NODE_TO_SATA_PORT(p) SATA_PORT_##p
#define SATA_NODE(p) TOSTRING(SATA_NODE_TO_SATA_PORT(p))
然后,如果您尝试使用以下命令打印预处理的宏
std::cout << SATA_NODE(3) << " - " << SATA_NODE(5) << std::endl;
std::cout << SATA_NODE(7) << std::endl;
你得到的是:
"/sata-ahci/port3" - "/sata-ahci/port5"
SATA_PORT_7