编译时出现此错误:
macro.c:11:2: error: expression is not assignable
ProdottoAumentato(10, 20);
我不知道为什么会这样说,我找不到任何错误。 这是代码:
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#define ProdottoAumentato(X, Y) X++; X * Y;
int main(void) {
ProdottoAumentato(10, 20);
printf("\nEnd\n");
return(0);
}
答案 0 :(得分:7)
宏执行文本替换。因此,ProdottoAumentato(10, 20);
将替换为以下内容:
10++; 10 * 20;;
10++
无效。你不能修改文字,这就是错误信息&#34;表达不可分配的内容&#34;指的是。
如何增加该值呢?
您需要将值分配给变量才能对其进行修改。请参阅维托里奥·罗密欧的答案,作为一个例子。
答案 1 :(得分:5)
宏是不任何想象力的功能。宏中的X
以文本方式替换为宏的第一个参数; Y
也是如此 - 它被第二个参数替换。
表达式10++
无效,原因与10 = 10+1
无效的原因相同。但是,这是宏扩展后得到的表达式,这是编译器通过其表达式告诉你的表达式不可分配的#34;错误。
答案 2 :(得分:2)
回复Andr1x的评论:
如何增加该值呢?
你可以使用一个功能:
int ProdottoAumentato(int* x, int y)
{
++(*x);
return (*x) * y;
}
可以如下调用:
int my_x = 10;
int res = ProdottoAumentato(&my_x, 20);
assert(my_x == 11);
assert(res == 11 * 20);
我不能。这是大学的练习,我需要在宏观中做所有事情。
这很难过,因为这对宏来说是一个可怕的用例。然而,如果你想使用宏,你的参数必须评估为&#34;可递增的#34; (即左值)。
这里是最安全的&#34;使用宏执行此操作的方法:
#define ProdottoAumentato(result, X, Y) \
do { ++(X); result = (X) * (Y); } while(0)
然后你可以打电话:
int my_x = 10;
int res;
ProdottoAumentato(res, my_x, 20);
assert(my_x == 11);
assert(res == 11 * 20);
将对其进行预处理:
int my_x = 10;
int res;
do { ++(my_x); res = (my_x) * (20); } while(0);
assert(my_x == 11);
assert(res == 11 * 20);
答案 3 :(得分:0)
您没有解释您真正想要的内容以及您(错误地)使用宏的原因。我猜这是因为你认为宏运行得更快。
然后只需定义一个inline
函数,如
static inline int ProdottoAumentato(int x, int y)
{ return (x+1)*y; }
最多optimizing compilers(例如gcc -Wall -O2
如果使用GCC ....),这与您尝试过的宏一样快,因为编译器会执行inline expansion。
如果由于某种奇怪的原因你还想使用宏和C预处理器,请检查其输出,例如通过运行gcc -C -E yourcode.c > yourcode.i
,然后查看(使用less
或某些源代码编辑器等寻呼机)到包含预处理表单的生成的yourcode.i
中。
根据经验,您通常需要在宏定义中添加额外的括号:
#define ProdottoAumentato(X,Y) ((X)+1)*(Y))
否则ProdottaAumentato(u+3,v+5)
将不会像您希望的那样展开,因为预处理是纯粹的文本操作。
您也可以使用statement exprs(有用的GCC扩展程序)并拥有
#define ProdottoAumentato(X,Y) ({int _x = (X); int _y = (Y); (++_x * _y)})
您可以定义两个全局变量; int xx, yy;
并且
#define ProdottoAumentato(X,Y) ((xx=(X),((yy=(Y)),((++xx)*yy))
答案 4 :(得分:0)
你想要的是
#define ProdottoAumentato(X, Y) ((X)++, (X) * (Y))
int main(void)
{
int x = 10;
x = ProdottoAumentato(x, 20);
/* x is 220 here. */
}
在实际C编译之前,预处理器将上述源代码转换为:
int main(void)
{
int x = 10;
x = ((x)++, (x) * (20));
}
这个
((x)++, (x) * (20))
是逗号运算符排序的两个表达式。首先评估左侧(带序列点),然后评估右侧。后一个值作为整个表达式的结果被“返回”。
答案 5 :(得分:0)
你究竟想要这个宏做什么?您正在对常量执行操作,结果不会归因于任何变量。
如果你只想拿两个数字,先添加一个数字再乘以第二个数字,你应该尝试
#define ProdottoAumentato(X, Y) (X+1)*Y
另一方面,如果你想增加一个变量,然后将它乘以另一个变量,你应该尝试
#define ProdottoAumentato(X, Y) X++; Y*=X
对于像你试图拉动的常数一样,这将无法使用。