我是一名Java开发人员,我对C宏的语法不是很熟悉。我正在研究Deitel& Deitel书,但它没有帮助。
我无法理解这个宏的含义:
#define _GetFrontItem(d,q) ( (d)->itemCache + ( (q)*(d)->block_size + \
(d)->offset[q] % (d)->block_size )*(d)->itemSize)
d
是指向结构的指针,q
是size_t
。
宏使用in this file。
你能帮我理解一下吗?这个宏完成了什么?为什么写它的方式?有没有更清晰的方法来编写这个宏?答案 0 :(得分:5)
我不得不说,这是一个该死的丑陋宏。继续前进。
宏所做的是计算struct的“item cache”(无论是什么)的索引,并返回指向它的指针:(d->itemCache + something)
等同于&d->itemCache[something]
。
宏因此等同于以下内联函数(从Google匹配here中提取的标识符):
static inline char *_GetFrontItem(Data *d, size_t q) {
return &d->itemCache[
d->itemSize * (q * d->block_size + d->offset[q] % d->block_size)
];
}
......这更容易被理解。为什么它首先是一个宏可能是因为这是遗留代码,从过去的内联函数根本就不存在。
答案 1 :(得分:4)
每当您在源代码中编写_GetFrontItem(d,q)
时,预处理器就会将其替换为此行
(d)->itemCache + ( (q)*(d)->block_size + (d)->offset[q] % (d)->block_size )*(d)->itemSize
所以这里d
必须是->
的结构的指针。
更多d
指向的结构必须具有至少3个成员,如下所示itemCache
,block_size
和数据类型为offset
的数组
此宏除了替换计算外什么都不做。
另一件事,在第一行:
#define _GetFrontItem(d,q) ( (d)->itemCache + ( (q)*(d)->block_size +
\
注意该行末尾的反斜杠\
。在定义宏时使用此字符(当然在行的末尾)将允许您继续在第二行写入,就像在第一行中继续写一样。它可以被视为使代码可读而不复杂的工具!!
答案 2 :(得分:3)
在这种情况下,d
是指向struct对象的指针。该struct对象包含一个缓冲区d->itemCache
(很可能是unsigned char
s的数组)。缓冲区实际上表示一个较大对象的数组,每个对象由d->itemSize
个字节组成。因此,为了获得指向此数组中对象编号i
的指针,您必须评估以下表达式
d->itemCache + i * d->itemSize
这正是你的宏所做的,除了元素索引i
通过参数q
评估为
q * d->block_size + d->offset[q] % d->block_size
这可能取决于相关数据结构的细节。
为了使这个宏更具可读性,可以将其分成几个宏
#define _GetItem(d, i) ((d)->itemCache + (i) * (d)->itemSize)
#define _GetFrontIndex(d, q) ((q) * (d)->block_size + (d)->offset[q] % (d)->block_size)
#define _GetFrontItem(d, q) _GetItem(d, _GetFrontIndex(d, q))