任何人都可以解释这是如何工作的
#define maxMacro(a,b) ( (a) > (b) ) ? (a) : (b)
inline int maxInline(int a, int b)
{
return a > b ? a : b;
}
int main()
{
int i = 1; j = 2, k = 0;
k = maxMacro(i,j++); // now i = 1, j = 4 and k = 3, Why ?? Where is it incremented ?
//reset values
i = 1; j = 2, k = 0;
k = maxInline(i,j++); // now i = 1, j = 3, and k = 2, Why ??
return 0;
}
Run Code Online (Sandbox Code Playgroud)
所以,我想知道j的值到底在哪里增加,同时检查条件或返回或在调用时?
更新:感谢所有人,现在我理解这一点.但出于好奇,为什么有人会在调用方法时执行j ++,为什么不在调用方法后增加j,这样就不那么容易混淆了.我在某个地方看到了这段代码,所以要问它!
Mic*_*ael 21
问题是预处理器只是直接替换宏文本.
maxMacro(i, j++)
Run Code Online (Sandbox Code Playgroud)
变
( (i) > (j++) ) ? (i) : (j++)
Run Code Online (Sandbox Code Playgroud)
如您所见,当j更大时,它会增加两个增量.
这正是您应该优先选择内联函数而不是宏的原因.
CB *_*ley 10
k = maxMacro(i,j++);
Run Code Online (Sandbox Code Playgroud)
扩展为:
k = ( (i) > (j++) ) ? (i) : (j++)
Run Code Online (Sandbox Code Playgroud)
由于?:这个行为的序列点是明确定义的.当i小于初始值时j,j则递增两次,并且k接收一次递增的值j.
(如果i大于初始值j,则j在评估时仅增加一次(i) > (j++),k将分配该值,(i)并且不执行第二个增量.)
在:
k = maxInline(i,j++);
Run Code Online (Sandbox Code Playgroud)
使用值调用maxInline i,j在递增(1和2)之前,j 在函数调用之前递增,并被k赋予maxInline(2)的返回值.
宏导致文本扩展.它发生在编译器甚至考虑表达式和运算符之前,并且在将输入文本拆分为单个标记之后立即发生.因此,以下行:
k = maxMacro(i,j++);
Run Code Online (Sandbox Code Playgroud)
是恰好相当于宏膨胀后的下面的行:
k = ( (i) > (j++) ) ? (i) : (j++);
Run Code Online (Sandbox Code Playgroud)
显然,这里有两个增量.
另一方面,内联函数只是函数,并且就调用而言,与非内联函数完全相同.在函数调用中,首先计算参数列表中的表达式,然后将它们的值绑定到函数体内的相应参数名称.因此,评估只发生一次.
这就是为什么宏是邪恶的!
宏是由proprocessor文字文本subsitution之前,你的编译器得到它,因此k = maxMacro(i,j++);变得( (i) > (j++) ) ? (i) : (j++);.我希望你能在这里看到问题.
在(内联)函数调用中,a和b的值通过值传递到函数中,其中i和j的初始值被传入,之后j递增.