我遇到过这个宏:
#define PUT(p, val) (*(int *)(p) = (val))
而且我不确定如何将其转换为函数。我认为这意味着p,一旦指针被解除引用(因此你有一个实际的int p变量)被设置为等于val。这是对的吗?
答案 0 :(得分:2)
这有点棘手,因为它基本上做了一些你不应该做的事情(因为它可能导致未定义的行为)。
第一步是将宏转换为函数体:
? PUT(? p, ? val) {
return *(int *)(p) = (val);
}
由于赋值总是返回其值,因此有一些返回值。那些数据类型呢?我们现在就来看看:
赋值的右边是微不足道的,因为实际上只有一对括号可以避免宏参数以某种方式与操作数的顺序相混淆,所以它实际上只是val
。
左侧有点复杂:
*(int *)(p)
再次,p
左右的括号只保留操作数的顺序,所以现在可以简化为:
*(int *)p
这是从右到左评估的:
p
。int *
。*
)。因此输入被转换为整数指针。为了使其有效(并且在某种程度上不完全是坚果),输入也必须是指针。执行此操作的最简单方法(并允许任何类似于宏的类型)是使用void*
。
由于您要为整数变量赋值(并且返回此值),因此返回类型将为int
。
有了这个说法,你最终会得到这样的结论:
int PUT(void *p, int val) {
return *(int *)(p) = (val);
}
现在,如果您想要更具体,可以将函数标记为inline
,这样代码实际上是内联/粘贴而不是调用,但这实际上取决于编译器:
inline int PUT(void *p, int val) {
return *(int *)(p) = (val);
}
答案 1 :(得分:1)
你可以将其分解以便更容易消化:
int *temp = (int *)p;
*temp = val;
答案 2 :(得分:0)
似乎将p
重新解释为int指针,并在(val)
表达式的任何位置写入结果。更短:在地址p。
val