当我阅读某人的代码时,我遇到了不熟悉的代码。 代码如下:
struct Employee {
int id;
};
#define getId(ptr) ((ptr)->id)
#define setId(ptr, value) ((ptr)->id = (value), 0)
我无法理解((ptr)->id = (value), 0)
。
此宏是否与((ptr)->id = (value)
相同?
答案 0 :(得分:1)
我无法理解
((ptr)->id = (id), 0)
。这是宏吗? 和((ptr)->id = (id)
一样?
,
是预处理器宏中的comma operator used in a complex return context。
所以,当你打电话给宏时,它会设置员工的id,然后返回0
(这只是程序员的设计决定,可能只是为了返回0
的含义“没有错误“)。
但正如其他人在评论中指出的那样,宏的定义可能有错误,应该看起来像:
#define setId(ptr) ((ptr)->id = (id), 0)
答案 1 :(得分:1)
我无法理解“((ptr) - > id =(id),0)”。这个宏是否与“((ptr) - > id =(id)”?
相同
假设宏定义是:
#define setId(ptr, name) ((ptr)->id = (name), 0)
如果您有表达式
a = setId(ptr, name);
它扩展到
a = ((ptr)->id = (name), 0);
执行该表达式时,a
的值为0
,这是逗号表达式((ptr)->id = (name), 0)
的值。评估表达式的副作用是id
指向的对象的ptr
成员设置为name
。
答案 2 :(得分:0)
您发布的代码似乎有误:
#define setId(ptr, name) ((ptr)->id = (id), 0)
setId
宏应该使用name
参数而不是某些本地id
标识符。如果name
是整数,则可以是:
#define setId(ptr, name) ((ptr)->id = (name), 0)
否则,它可能是这样的:
#define setId(ptr, name) ((ptr)->id = nameToId(name), 0)
关于, 0)
部分,它是逗号运算符的一个实例:宏扩展为一个表达式,用于计算赋值,然后计算0
。如果使用setId(ptr, name)
的结果,则其值始终为0
。像这样的构造不是很易读,很可能会在某些编译器上产生警告。
答案 3 :(得分:0)
这些宏取代了" setter"和" getter"功能。假设" setter"应该返回0表示成功,-1表示失败,函数看起来像这样
int getId( struct Employee *ptr )
{
return( ptr->id );
}
int setId( struct Employee *ptr, int value )
{
ptr->id = id;
return 0; // this setter always succeeds
}
用宏替换getter非常简单。更换setter有点棘手,因为你需要"返回"正确的价值。这是逗号运算符有用的地方。
逗号运算符计算第一个表达式并丢弃结果。然后它计算第二个表达式,第二个表达式的结果用作逗号运算符的结果。因此setter宏总是计算为0。