C 带有新参数的宏

C 带有新参数的宏,c,macros,C,Macros,我编写此宏用于在数组中搜索数字: #define FIND(VALUE,ARR,INDEX){\ int i;\ INDEX = -1;\ for(i = 0;i <sizeof(ARR)/sizeof(VALUE); i++){\ if(ARR[i] == VALUE){\ INDEX = i;\ }\ }\ \ } #定义查找(值、ARR、索引){\ int i\ 指数=-1\ 对于(i=0;i宏

我编写此宏用于在数组中搜索数字:

#define FIND(VALUE,ARR,INDEX){\
    int i;\
    INDEX = -1;\
    for(i = 0;i <sizeof(ARR)/sizeof(VALUE); i++){\
        if(ARR[i] == VALUE){\
            INDEX = i;\
        }\
    }\
\
}
#定义查找(值、ARR、索引){\
int i\
指数=-1\

对于(i=0;i宏中的
i
将隐藏在周围上下文或全局中声明的任何其他
i
。是否将此视为问题取决于是否需要能够访问隐藏的
i
这是正常的。宏中的
i
将仅在宏中可见,并且也将隐藏外部
i
在此宏范围内。

否。内部块将隐藏外部。但是,如果传入的
索引是
i
,则会出现问题。这就是为什么您经常在宏中看到像
\u i
这样奇怪的变量名。这是为了避免名称冲突


在现代编译器和硬件中,几乎没有理由以他的方式摆弄宏。只需使用函数。

即使您在
main
中重新定义
i
,也不会有问题

#定义查找(值、ARR、索引){\
int i\
指数=-1\

对于(i=0;i当然,
i
只是一个问题,如果将
i
作为参数传递给宏,因为宏执行纯文本替换

除此之外,您的代码还有几个问题:

  • 包装类似宏的void函数的惯用方法是使用
    do{…}while(0)
    循环。只有这样才能正确地接受分号

  • 您没有像应该的那样将所有参数都用括号括起来。如果将
    7&foo
    作为
    VALUE
    传递,表达式
    If(ARR[i]==VALUE){
    将扩展为
    If(ARR[i]==7&foo){
    ,这不会达到您的预期效果

  • 您的宏参数会被计算多次,因此如果您为它们中的任何一个传递类似于
    foo++
    的内容,代码将爆炸

  • 元素计数计算
    sizeof(ARR)/sizeof(VALUE)
    完全错误。不能保证
    VALUE
    的类型与数组的元素类型相同。如果在宏中计算数组元素计数,则始终使用
    sizeof(ARR)/sizeof(*ARR)