您可以使用宏来摆脱无函数调用的限制,因为宏会生成从技术上讲不是函数调用的内联代码
但是在更复杂的操作宏不能有返回值的情况下,所以你需要为结果使用一些局部变量(如果有多个表达式),例如:
int ret;
#define my_pow_notemp(a,b) (b==0)?1:(b==1)?a:(b==2)?a*a:(b==3)?a*a*a:0
#define my_pow(a,b)\
{\
ret=1;\
if (int(b& 1)) ret*=a;\
if (int(b& 2)) ret*=a*a;\
if (int(b& 4)) ret*=a*a*a*a;\
if (int(b& 8)) ret*=a*a*a*a*a*a*a*a;\
if (int(b&16)) ret*=a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a;\
if (int(b&32)) ret*=a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a;\
}
void main()
{
int a=2,b=3,c;
c=my_pow_notemp(a,b); // c = a^b
my_pow(a,b); c = ret; // c = a^b
}
如您所见,您可以直接使用my_pow_notemp,但代码是硬编码的,因此只有a^3,如果您想要更多,您必须将其添加到代码中。 my_pow 接受最大为 a^63 的指数,它也是一个示例,说明如何在宏内部代码更复杂的情况下返回值。如果您需要非整数或负指数,这里有一些(常规)方法来计算幂(但是如果没有循环/递归,将其转换为展开代码将非常困难):
如果您想摆脱递归和函数调用,您可以使用 模板 代替宏,但这仅限于 C++。
template<class T> T my_pow(T a,T b)
{
if (b==0) return 1;
if (b==1) return a;
return a*my_pow(a,b-1);
}
void main()
{
int a=2,b=3,c;
c=my_pow(a,b);
}
正如您所见,模板具有返回值,因此即使使用更复杂的代码(不止一个表达式)也没有问题。
要避免循环,您可以使用 LUT 表格
int my_pow[4][4]=
{
{1,0,0,0}, // 0^
{1,1,1,1}, // 1^
{1,2,4,8}, // 2^
{1,3,9,27}, // 3^
};
void main()
{
int a=2,b=3,c;
c=my_pow[a][b];
}
如果您可以访问 FPU 或高级数学汇编,则可以使用它,因为 asm 指令不是函数调用。 FPU 通常具有原生的log,exp,pow 函数。然而,这将代码限制在特定的指令集!!!
这里有一些例子:
所以当我考虑到您的限制时,我认为最好的方法是:
#define my_pow(a,b) (b==0)?1:(b==1)?a:(b==2)?a*a:(b==3)?a*a*a:0
void main()
{
int a=2,b=3,c;
c=my_pow(a,b); // c = a^b
}
这将适用于 int 指数 b 最多 3(如果您想要更多,只需添加 (b==4)?a*a*a*a: ... :0)以及 int 和 float 基础 a。如果您需要更大的指数,请使用带有局部临时变量的复杂版本来返回结果。
[Edit1] 终极单一表达式宏,通过平方高达 a^15
#define my_pow(a,b) (1* (int(b&1))?a:1* (int(b&2))?a*a:1* (int(b&4))?a*a*a*a:1* (int(b&8))?a*a*a*a*a*a*a*a:1)
void main()
{
int a=2,b=3,c;
c=my_pow(a,b); // c = a^b
}
如果您想要超过a^15,只需为每一位指数添加子项(int(b&16))?a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a:1 等等。