我写了这个宏来搜索数组中的数字:
#define FIND(VALUE,ARR,INDEX){\
int i;\
INDEX = -1;\
for(i = 0;i <sizeof(ARR)/sizeof(VALUE); i++){\
if(ARR[i] == VALUE){\
INDEX = i;\
}\
}\
\
}
我的问题是,如果我在宏中和主要中定义int i
会不会有问题?
答案 0 :(得分:4)
宏中的i
将隐藏在周围环境或全局声明的任何其他i
。是否将此视为问题取决于是否需要能够访问隐藏的i
。
答案 1 :(得分:2)
没有。内部块将隐藏外部。但是,如果传入的INDEX
为i
,则将成为问题。这就是为什么你经常看到奇怪的变量名称,如宏中使用的_i_
。这是为了避免姓名冲突。
使用现代编译器和硬件,没有理由以他的方式摆弄宏。只需使用一个功能。
答案 2 :(得分:1)
当然,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)
。
答案 3 :(得分:0)
开启。宏中的i
仅在宏中可见,并且还会在此宏范围内隐藏外部i
。
答案 4 :(得分:0)
即使您在i
中重新定义main
,也不会有任何问题。
#define FIND(VALUE,ARR,INDEX){\
int i;\
INDEX = -1;\
for(i = 0;i <sizeof(ARR)/sizeof(VALUE); i++){\
if(ARR[i] == VALUE){\
INDEX = i;\
}\
}\
\
}
由于您在宏中定义了自己的范围“{”。