为什么在我的代码中使用宏会产生错误?
Why is using a macro in my code produces errors?
我写了一个宏来计算打开的奇数索引位的数量。
举几个例子:
在包含以下位的变量中:
10010101
只有索引 7 处的位打开,只有 1 个奇数索引位打开,所以答案是 1。
在包含以下位的变量中:
00101011
索引 1 的位打开,索引 3 的位打开,索引 5 的位打开,因此共有 3 个奇数索引位打开,所以答案是 3 .
我写了一个main函数来测试这个宏。
完整程序如下:
#include <stdio.h>
#define ODD(n)\
int count = 0;\
int i = 1; \
while(n>>i)\
{\
if( ((n>>i)%2) == 1)\
count++;\
i = i+2;\
}\
int main()
{
int i;
int j;
int array1[] = {1,2,3,4};
/*array1 contains (binary representation):
00000001
00000010
00000011
00000100
After passing these into the macro:
00000001 ----> 0 odd indexed bits are turned on
00000010 ---->1 odd indexed bit is turned on
00000011 ---->1 odd indexed bit is turned on
00000100 ----> 0 odd indexed bits is turned on
*/
int array2[4];
for(i=0; i<4; i++)
{
array2[i] = ODD(array1[i]);
}
for(j=0; j<4; j++)
{
printf("Array2: %d\n",array2[j]);
}
return 0;
}
我不知道为什么会出现以下错误:
odd.c: In function ���main���:
odd.c:4:5: error: expected expression before ���int���
int count = 0;\
odd.c:34:19: note: in expansion of macro ���ODD���
array2[i] = ODD(array1[i]);
^
odd.c:8:13: error: ���count��� undeclared (first use in this function)
count++;\
^
已声明计数,所以我不知道它有什么问题。
为什么会出现这些错误,我该如何解决?
您遇到错误,因为宏不是函数。是一种token扩容机制,扩容成下面废话:
array2[i] = int count = 0;
while(array1[i]>>1)\
{\
if( ((array1[i]>>1)%2) == 1)\
count++;\
}\
把它写成函数,然后你就可以把它当作返回一个实际结果来对待:
int odd(int n) {
int count = 0;
while(n>>1)
{
if( ((n>>1)%2) == 1)
count++;
}
return count;
}
如果你坚持用宏来写,那么你需要重构它:
#define ODD(n, res) do { \
int count = 0; \
while(n>>1)\
{\
if( ((n>>1)%2) == 1)\
count++;\
}\
(res) = count;\
} while(0)
要定义一个变量,你必须引入一个作用域,所以为此添加了一个do while循环。这个特殊的循环结构有一个很好的特性,当你在宏调用后写一个语句终止符时,不会产生关于空语句的警告 (ODD(...);
)。
结果的位置目标应作为另一个参数传递给宏,如下所示:
ODD(array1[i], array2[i]);
我写了一个宏来计算打开的奇数索引位的数量。
举几个例子:
在包含以下位的变量中:
10010101
只有索引 7 处的位打开,只有 1 个奇数索引位打开,所以答案是 1。
在包含以下位的变量中:
00101011
索引 1 的位打开,索引 3 的位打开,索引 5 的位打开,因此共有 3 个奇数索引位打开,所以答案是 3 .
我写了一个main函数来测试这个宏。
完整程序如下:
#include <stdio.h>
#define ODD(n)\
int count = 0;\
int i = 1; \
while(n>>i)\
{\
if( ((n>>i)%2) == 1)\
count++;\
i = i+2;\
}\
int main()
{
int i;
int j;
int array1[] = {1,2,3,4};
/*array1 contains (binary representation):
00000001
00000010
00000011
00000100
After passing these into the macro:
00000001 ----> 0 odd indexed bits are turned on
00000010 ---->1 odd indexed bit is turned on
00000011 ---->1 odd indexed bit is turned on
00000100 ----> 0 odd indexed bits is turned on
*/
int array2[4];
for(i=0; i<4; i++)
{
array2[i] = ODD(array1[i]);
}
for(j=0; j<4; j++)
{
printf("Array2: %d\n",array2[j]);
}
return 0;
}
我不知道为什么会出现以下错误:
odd.c: In function ���main���:
odd.c:4:5: error: expected expression before ���int���
int count = 0;\
odd.c:34:19: note: in expansion of macro ���ODD���
array2[i] = ODD(array1[i]);
^
odd.c:8:13: error: ���count��� undeclared (first use in this function)
count++;\
^
已声明计数,所以我不知道它有什么问题。
为什么会出现这些错误,我该如何解决?
您遇到错误,因为宏不是函数。是一种token扩容机制,扩容成下面废话:
array2[i] = int count = 0;
while(array1[i]>>1)\
{\
if( ((array1[i]>>1)%2) == 1)\
count++;\
}\
把它写成函数,然后你就可以把它当作返回一个实际结果来对待:
int odd(int n) {
int count = 0;
while(n>>1)
{
if( ((n>>1)%2) == 1)
count++;
}
return count;
}
如果你坚持用宏来写,那么你需要重构它:
#define ODD(n, res) do { \
int count = 0; \
while(n>>1)\
{\
if( ((n>>1)%2) == 1)\
count++;\
}\
(res) = count;\
} while(0)
要定义一个变量,你必须引入一个作用域,所以为此添加了一个do while循环。这个特殊的循环结构有一个很好的特性,当你在宏调用后写一个语句终止符时,不会产生关于空语句的警告 (ODD(...);
)。
结果的位置目标应作为另一个参数传递给宏,如下所示:
ODD(array1[i], array2[i]);