我可以使用C / C ++预处理器添加数字吗?

对于一些基地。 基数1甚至。 某种复杂的替代。

此外,当然,在现实生产代码中这样做并不是一个好主意。 我只是出于好奇而被问到。

你可以比较容易地编写宏,它在二进制中添加两个整数。 例如 – 以二进制forms对两个4位整数求和的宏:

#include "stdio.h" // XOR truth table #define XOR_0_0 0 #define XOR_0_1 1 #define XOR_1_0 1 #define XOR_1_1 0 // OR truth table #define OR_0_0 0 #define OR_0_1 1 #define OR_1_0 1 #define OR_1_1 1 // AND truth table #define AND_0_0 0 #define AND_0_1 0 #define AND_1_0 0 #define AND_1_1 1 // concatenation macros #define XOR_X(x,y) XOR_##x##_##y #define OR_X(x,y) OR_##x##_##y #define AND_X(x,y) AND_##x##_##y #define OVERFLOW_X(rc1,rc2,rc3,rc4, rb1,rb2,rb3,rb4, a1,a2,a3,a4, b1,b2,b3,b4) OVERFLOW_##rc1 (rc1,rc2,rc3,rc4, rb1,rb2,rb3,rb4, a1,a2,a3,a4, b1,b2,b3,b4) // stringification macros #define STR_X(x) #x #define STR(x) STR_X(x) // boolean operators #define XOR(x,y) XOR_X(x,y) #define OR(x,y) OR_X(x,y) #define AND(x,y) AND_X(x,y) // carry_bit + bit1 + bit2 #define BIT_SUM(carry,bit1,bit2) XOR(carry, XOR(bit1,bit2)) // carry_bit + carry_bit_of(bit1 + bit2) #define CARRY_SUM(carry,bit1,bit2) OR(carry, AND(bit1,bit2)) // do we have overflow or maybe result perfectly fits into 4 bits ? #define OVERFLOW_0(rc1,rc2,rc3,rc4, rb1,rb2,rb3,rb4, a1,a2,a3,a4, b1,b2,b3,b4) SHOW_RESULT(rc1,rc2,rc3,rc4, rb1,rb2,rb3,rb4, a1,a2,a3,a4, b1,b2,b3,b4) #define OVERFLOW_1(rc1,rc2,rc3,rc4, rb1,rb2,rb3,rb4, a1,a2,a3,a4, b1,b2,b3,b4) SHOW_OVERFLOW(rc1,rc2,rc3,rc4, rb1,rb2,rb3,rb4, a1,a2,a3,a4, b1,b2,b3,b4) // draft-horse macros which performs addition of two 4-bit integers #define ADD_BIN_NUM(a1,a2,a3,a4, b1,b2,b3,b4) ADD_BIN_NUM_4(0,0,0,0, 0,0,0,0, a1,a2,a3,a4, b1,b2,b3,b4) #define ADD_BIN_NUM_4(rc1,rc2,rc3,rc4, rb1,rb2,rb3,rb4, a1,a2,a3,a4, b1,b2,b3,b4) ADD_BIN_NUM_3(rc1,rc2,rc3,AND(CARRY_SUM(0,a4,b4),OR(a4,b4)), rb1,rb2,rb3,BIT_SUM(0,a4,b4), a1,a2,a3,a4, b1,b2,b3,b4) #define ADD_BIN_NUM_3(rc1,rc2,rc3,rc4, rb1,rb2,rb3,rb4, a1,a2,a3,a4, b1,b2,b3,b4) ADD_BIN_NUM_2(rc1,rc2,AND(CARRY_SUM(rc4,a3,b3),OR(a3,b3)),rc4, rb1,rb2,BIT_SUM(rc4,a3,b3),rb4, a1,a2,a3,a4, b1,b2,b3,b4) #define ADD_BIN_NUM_2(rc1,rc2,rc3,rc4, rb1,rb2,rb3,rb4, a1,a2,a3,a4, b1,b2,b3,b4) ADD_BIN_NUM_1(rc1,AND(CARRY_SUM(rc3,a2,b2),OR(a2,b2)),rc3,rc4, rb1,BIT_SUM(rc3,a2,b2),rb3,rb4, a1,a2,a3,a4, b1,b2,b3,b4) #define ADD_BIN_NUM_1(rc1,rc2,rc3,rc4, rb1,rb2,rb3,rb4, a1,a2,a3,a4, b1,b2,b3,b4) OVERFLOW(AND(CARRY_SUM(rc2,a1,b1),OR(a1,b1)),rc2,rc3,rc4, BIT_SUM(rc2,a1,b1),rb2,rb3,rb4, a1,a2,a3,a4, b1,b2,b3,b4) #define OVERFLOW(rc1,rc2,rc3,rc4, rb1,rb2,rb3,rb4, a1,a2,a3,a4, b1,b2,b3,b4) OVERFLOW_X(rc1,rc2,rc3,rc4, rb1,rb2,rb3,rb4, a1,a2,a3,a4, b1,b2,b3,b4) #define SHOW_RESULT(rc1,rc2,rc3,rc4, rb1,rb2,rb3,rb4, a1,a2,a3,a4, b1,b2,b3,b4) STR(a1) STR(a2) STR(a3) STR(a4) " + " STR(b1) STR(b2) STR(b3) STR(b4) " = " STR(rb1) STR(rb2) STR(rb3) STR(rb4) #define SHOW_OVERFLOW(rc1,rc2,rc3,rc4, rb1,rb2,rb3,rb4, a1,a2,a3,a4, b1,b2,b3,b4) STR(a1) STR(a2) STR(a3) STR(a4) " + " STR(b1) STR(b2) STR(b3) STR(b4) " = overflow" void main() { printf("%s\n", ADD_BIN_NUM( 0,0,0,1, // first 4-bit int 1,0,1,1) // second 4-bit int ); printf("%s\n", ADD_BIN_NUM( 0,1,0,0, // first 4-bit int 0,1,0,1) // second 4-bit int ); printf("%s\n", ADD_BIN_NUM( 1,0,1,1, // first 4-bit int 0,1,1,0) // second 4-bit int ); } 

可以轻松扩展此宏,以添加两个8位或16位甚至32位的整数。 所以我们所需要的只是令牌连接和替换规则,以便用宏实现惊人的结果。

编辑:我已经改变了结果的格式化,更重要的是 – 我添加了溢出检查。

HTH!

预处理器在预处理令牌上运行,并且唯一一次评估数字是在评估#if#elif指令期间。 除此之外,预处理期间数字不是真正的数字; 它们被归类为预处理数字标记,实际上不是数字。

您可以使用标记连接来评估基本算术:

 #define ADD_0_0 0 #define ADD_0_1 1 #define ADD_1_0 1 #define ADD_1_1 2 #define ADD(x, y) ADD##_##x##_##y ADD(1, 0) // expands to 1 ADD(1, 1) // expands to 2 

但实际上,没有理由这样做,这样做会很愚蠢(你必须定义大量的宏才能使它更加有用)。

将宏扩展为可由编译器评估的整数常量表达式会更为明智:

 #define ADD(x, y) ((x) + (y)) ADD(1, 1) // expands to ((1) + (1)) 

编译器将能够评估1 + 1表达式。

我知道它不是预处理器,但如果有帮助,你可以用模板来做。 也许你可以将它与宏结合使用来实现你所需要的。

 #include  using namespace std; template  struct Add { static const int Value = N + M; }; int main() { cout << Add<4, 5>::Value << endl; return 0; } 

很有可能在预处理器中进行有界整数加法。 并且,它实际上需要的次数比人们真正希望的要多,即在程序中只有((2) + (3))的替代方法不起作用。 (例如,你不能有一个名为x((2)+(3))的变量。 这个想法很简单:将增加转换为增量,你不介意(太多)将它们列出来。 例如,

 #define INC(x) INC_ ## x #define INC_0 1 #define INC_1 2 #define INC_2 3 #define INC_3 4 #define INC_4 5 #define INC_5 6 #define INC_6 7 #define INC_7 8 #define INC_8 9 #define INC_9 10 INC(7) // => 8 

现在我们知道如何添加到最多1。

 #define ADD(x, y) ADD_ ## x(y) #define ADD_0(x) x #define ADD_1(x) INC(x) ADD(0, 2) // => 2 ADD(1, 2) // => 3 

要添加更大的数字,您需要某种“递归”。

 #define ADD_2(x) ADD_1(INC(x)) #define ADD_3(x) ADD_2(INC(x)) #define ADD_4(x) ADD_3(INC(x)) #define ADD_5(x) ADD_4(INC(x)) #define ADD_6(x) ADD_5(INC(x)) #define ADD_7(x) ADD_6(INC(x)) #define ADD_8(x) ADD_7(INC(x)) #define ADD_9(x) ADD_8(INC(x)) #define ADD_10(x) ADD_9(INC(x)) ADD(5, 2) // => 7 

但是,必须要小心。 例如,以下内容不起作用。

 #define ADD_2(x) INC(ADD_1(x)) ADD(2, 2) // => INC_ADD_1(2) 

对于此类技巧的任何扩展使用,Boost预处理器是您的朋友。

显然,你可以。 如果你看看Boost预处理器库,你可以用预处理器,甚至整数加法来做各种各样的事情。

C预处理器可以评估包含整数运算的条件。 它不会替代算术表达式并将结果传递给编译器,但编译器将对编译时常量进行算术运算并将结果发送到二进制文件中,只要您没有重载正在使用的运算符。

预处理器宏不能真正进行算术运算,但它们可以有效地利用枚举进行数学运算。 一般的技巧是有一个调用其他宏的宏,并且可以使用其他宏的不同定义重复调用。

例如,类似于:

 #define MY_THINGS \
   a_thing(FRED,4)\
   a_thing(GEORGE,6)
   a_thing(哈里,5)
   a_thing(HERMIONE,8)
   a_thing(RON,3)\
   //这一行留空了 

 #define a_thing(name,size)EN _ ## name}; 枚举{EN_SIZE _ ## name =(size),EN_BLAH _ ## name = EN _ ## name +(size-1),
枚举{EN_FIRST_THING = 0,MY_THINGS EN_TOTAL_SIZE};
 #undef a_thing

这将允许人们为例如arrays中的每件事物“分配”一定量的空间。 数学不是由预处理器完成的,但枚举仍然被视为编译时常量。

我很确定C / C ++预处理器只是复制和粘贴 – 它实际上并没有评估任何表达式。 表达式评估由编译器完成。

为了更好地回答您的问题,您可能希望发布您要完成的内容。