C宏用于计算一堆定义的最大数量

时间:2013-11-26 15:11:03

标签: c macros

我需要在55个值之间的宏中找到Max值,这些值也被定义为宏定义。我的意思是

#define VALUE1 56
#define VALUE2 76
...
#define VALUE55 14

#define MAX_BEETWEEN_VALUES (...) ...

宏函数MAX_BEETWEEN_VALUES应该返回76作为结果。 我无法弄清楚这个宏应该如何编码。

感谢您的帮助

6 个答案:

答案 0 :(得分:2)

这是在编译时找到最大值的另一个C kludge。假设枚举对你来说和#defines一样有效,并且值是小的正整数(尽管其他域的解决方法更糟)。

union value_set_t {
#   define V(name, value) char name##_[value];
#   include "values.h"
#   undef V
};

enum {
#   define V(name, value) name = value,
#   include "values.h"
#   undef V
    MAX_BETWEEN_VALUES = sizeof(union value_set_t)
};

使用values.h:

V(VALUE1, 56)
V(VALUE2, 76)
V(VALUE55, 14)

答案 1 :(得分:1)

硬代码

#define MAX(X, Y) ((X>Y)?(X):(Y))

#define MAX_BEETWEEN_VALUES MAX(VALUE1,  \
                            MAX(VALUE2,  \
                            MAX(VALUE3,  \
                            ...          \
                            MAX(VALUE54, \
                                VALUE55))) ... )
                                       ~~~~~~~~~ 54 close parenthesis 

可能超出编译器的限制。

答案 2 :(得分:1)

我在上面回答的评论代码:https://stackoverflow.com/a/20221017/2963099

V1到V58未显示

#define V59 1
#define V60 33
#define V61 1
#define V62 2
#define V63 1
#define V64 2

#define MAX2(a,b) ((a>b)?(a):(b))
#define MAX4(a,b,c,d) MAX2(MAX2(a,b), MAX2(c,d))
#define MAX8(a,b,c,d,e,f,g,h) MAX2(MAX4(a,b,c,d),MAX4(e,f,g,h))
#define MAX64(a1,a2,a3,a4,a5,a6,a7,a8, \
    b1,b2,b3,b4,b5,b6,b7,b8, \
    c1,c2,c3,c4,c5,c6,c7,c8, \
    d1,d2,d3,d4,d5,d6,d7,d8, \
    e1,e2,e3,e4,e5,e6,e7,e8, \
    f1,f2,f3,f4,f5,f6,f7,f8, \
    g1,g2,g3,g4,g5,g6,g7,g8, \
    h1,h2,h3,h4,h5,h6,h7,h8) MAX8(\
    MAX8(a1,a2,a3,a4,a5,a6,a7,a8), \
    MAX8(b1,b2,b3,b4,b5,b6,b7,b8), \
    MAX8(c1,c2,c3,c4,c5,c6,c7,c8), \
    MAX8(d1,d2,d3,d4,d5,d6,d7,d8), \
    MAX8(e1,e2,e3,e4,e5,e6,e7,e8), \
    MAX8(f1,f2,f3,f4,f5,f6,f7,f8), \
    MAX8(g1,g2,g3,g4,g5,g6,g7,g8), \
    MAX8(h1,h2,h3,h4,h5,h6,h7,h8))

int main(int, char**)
{
    int x= MAX64(V1,V2,V3,V4,V5,V6,V7,V8,V9,V10,V11,V12,V13,V14,V15,V16,V17,V18,V19,V20,V21,V22,V23,V24,V25,V26,V27,V28,V29,V30,V31,V32,V33,V34,V35,V36,V37,V38,V39,V40,V41,V42,V43,V44,V45,V46,V47,V48,V49,V50,V51,V52,V53,V54,V55,V56,V57,V58,V59,V60,V61,V62,V63,V64);

    return x;
}

编写得非常快(并且有33个正确答案)

答案 3 :(得分:0)

可能有一种标准化的方式,但如果不是这样,只要你愿意采用“更好的C”路线就足够了。

#include <cstdio>

template<int a, int ...list> struct greatest_of { 
        static const int value = a > greatest_of<list...>::value
                                 ? a : greatest_of<list...>::value;
};
template<int a> struct greatest_of<a> {
        static const int value = a;
};

int main()
{
        printf("%d\n",greatest_of<1,2,3>::value);
}

(编辑:printf)。

答案 4 :(得分:0)

生成具有多个/最大宏的新颖(且相当邪恶)的方法可能是生成它们。

示例Python脚本:

def minmax(a, expr):
    t = "("
    t = t + ("(%s%s%s)?" % (a[0], expr, a[1]))
    if len(a) == 2:
        r_a = a[0]
        r_b = a[1]
    else:
        r_a = minmax((a[0],) + a[2:], expr)
        r_b = minmax(a[1:], expr)

    t = t + ("%s:%s" % (r_a, r_b))
    return t + ")"

for i in range(2, 8):
    args = tuple([("v%d" % j) for j in range(i)])
    print(("    #define MIN%d(%s) " % (i, ",".join(args)) + minmax(args, "<")))
    print(("    #define MAX%d(%s) " % (i, ",".join(args)) + minmax(args, ">")))

生成这个......

#define MIN2(v0,v1) ((v0<v1)?v0:v1)
#define MAX2(v0,v1) ((v0>v1)?v0:v1)
#define MIN3(v0,v1,v2) ((v0<v1)?((v0<v2)?v0:v2):((v1<v2)?v1:v2))
#define MAX3(v0,v1,v2) ((v0>v1)?((v0>v2)?v0:v2):((v1>v2)?v1:v2))
#define MIN4(v0,v1,v2,v3) ((v0<v1)?((v0<v2)?((v0<v3)?v0:v3):((v2<v3)?v2:v3)):((v1<v2)?((v1<v3)?v1:v3):((v2<v3)?v2:v3)))
#define MAX4(v0,v1,v2,v3) ((v0>v1)?((v0>v2)?((v0>v3)?v0:v3):((v2>v3)?v2:v3)):((v1>v2)?((v1>v3)?v1:v3):((v2>v3)?v2:v3)))
#define MIN5(v0,v1,v2,v3,v4) ((v0<v1)?((v0<v2)?((v0<v3)?((v0<v4)?v0:v4):((v3<v4)?v3:v4)):((v2<v3)?((v2<v4)?v2:v4):((v3<v4)?v3:v4))):((v1<v2)?((v1<v3)?((v1<v4)?v1:v4):((v3<v4)?v3:v4)):((v2<v3)?((v2<v4)?v2:v4):((v3<v4)?v3:v4))))
#define MAX5(v0,v1,v2,v3,v4) ((v0>v1)?((v0>v2)?((v0>v3)?((v0>v4)?v0:v4):((v3>v4)?v3:v4)):((v2>v3)?((v2>v4)?v2:v4):((v3>v4)?v3:v4))):((v1>v2)?((v1>v3)?((v1>v4)?v1:v4):((v3>v4)?v3:v4)):((v2>v3)?((v2>v4)?v2:v4):((v3>v4)?v3:v4))))
#define MIN6(v0,v1,v2,v3,v4,v5) ((v0<v1)?((v0<v2)?((v0<v3)?((v0<v4)?((v0<v5)?v0:v5):((v4<v5)?v4:v5)):((v3<v4)?((v3<v5)?v3:v5):((v4<v5)?v4:v5))):((v2<v3)?((v2<v4)?((v2<v5)?v2:v5):((v4<v5)?v4:v5)):((v3<v4)?((v3<v5)?v3:v5):((v4<v5)?v4:v5)))):((v1<v2)?((v1<v3)?((v1<v4)?((v1<v5)?v1:v5):((v4<v5)?v4:v5)):((v3<v4)?((v3<v5)?v3:v5):((v4<v5)?v4:v5))):((v2<v3)?((v2<v4)?((v2<v5)?v2:v5):((v4<v5)?v4:v5)):((v3<v4)?((v3<v5)?v3:v5):((v4<v5)?v4:v5)))))
#define MAX6(v0,v1,v2,v3,v4,v5) ((v0>v1)?((v0>v2)?((v0>v3)?((v0>v4)?((v0>v5)?v0:v5):((v4>v5)?v4:v5)):((v3>v4)?((v3>v5)?v3:v5):((v4>v5)?v4:v5))):((v2>v3)?((v2>v4)?((v2>v5)?v2:v5):((v4>v5)?v4:v5)):((v3>v4)?((v3>v5)?v3:v5):((v4>v5)?v4:v5)))):((v1>v2)?((v1>v3)?((v1>v4)?((v1>v5)?v1:v5):((v4>v5)?v4:v5)):((v3>v4)?((v3>v5)?v3:v5):((v4>v5)?v4:v5))):((v2>v3)?((v2>v4)?((v2>v5)?v2:v5):((v4>v5)?v4:v5)):((v3>v4)?((v3>v5)?v3:v5):((v4>v5)?v4:v5)))))
#define MIN7(v0,v1,v2,v3,v4,v5,v6) ((v0<v1)?((v0<v2)?((v0<v3)?((v0<v4)?((v0<v5)?((v0<v6)?v0:v6):((v5<v6)?v5:v6)):((v4<v5)?((v4<v6)?v4:v6):((v5<v6)?v5:v6))):((v3<v4)?((v3<v5)?((v3<v6)?v3:v6):((v5<v6)?v5:v6)):((v4<v5)?((v4<v6)?v4:v6):((v5<v6)?v5:v6)))):((v2<v3)?((v2<v4)?((v2<v5)?((v2<v6)?v2:v6):((v5<v6)?v5:v6)):((v4<v5)?((v4<v6)?v4:v6):((v5<v6)?v5:v6))):((v3<v4)?((v3<v5)?((v3<v6)?v3:v6):((v5<v6)?v5:v6)):((v4<v5)?((v4<v6)?v4:v6):((v5<v6)?v5:v6))))):((v1<v2)?((v1<v3)?((v1<v4)?((v1<v5)?((v1<v6)?v1:v6):((v5<v6)?v5:v6)):((v4<v5)?((v4<v6)?v4:v6):((v5<v6)?v5:v6))):((v3<v4)?((v3<v5)?((v3<v6)?v3:v6):((v5<v6)?v5:v6)):((v4<v5)?((v4<v6)?v4:v6):((v5<v6)?v5:v6)))):((v2<v3)?((v2<v4)?((v2<v5)?((v2<v6)?v2:v6):((v5<v6)?v5:v6)):((v4<v5)?((v4<v6)?v4:v6):((v5<v6)?v5:v6))):((v3<v4)?((v3<v5)?((v3<v6)?v3:v6):((v5<v6)?v5:v6)):((v4<v5)?((v4<v6)?v4:v6):((v5<v6)?v5:v6))))))
#define MAX7(v0,v1,v2,v3,v4,v5,v6) ((v0>v1)?((v0>v2)?((v0>v3)?((v0>v4)?((v0>v5)?((v0>v6)?v0:v6):((v5>v6)?v5:v6)):((v4>v5)?((v4>v6)?v4:v6):((v5>v6)?v5:v6))):((v3>v4)?((v3>v5)?((v3>v6)?v3:v6):((v5>v6)?v5:v6)):((v4>v5)?((v4>v6)?v4:v6):((v5>v6)?v5:v6)))):((v2>v3)?((v2>v4)?((v2>v5)?((v2>v6)?v2:v6):((v5>v6)?v5:v6)):((v4>v5)?((v4>v6)?v4:v6):((v5>v6)?v5:v6))):((v3>v4)?((v3>v5)?((v3>v6)?v3:v6):((v5>v6)?v5:v6)):((v4>v5)?((v4>v6)?v4:v6):((v5>v6)?v5:v6))))):((v1>v2)?((v1>v3)?((v1>v4)?((v1>v5)?((v1>v6)?v1:v6):((v5>v6)?v5:v6)):((v4>v5)?((v4>v6)?v4:v6):((v5>v6)?v5:v6))):((v3>v4)?((v3>v5)?((v3>v6)?v3:v6):((v5>v6)?v5:v6)):((v4>v5)?((v4>v6)?v4:v6):((v5>v6)?v5:v6)))):((v2>v3)?((v2>v4)?((v2>v5)?((v2>v6)?v2:v6):((v5>v6)?v5:v6)):((v4>v5)?((v4>v6)?v4:v6):((v5>v6)?v5:v6))):((v3>v4)?((v3>v5)?((v3>v6)?v3:v6):((v5>v6)?v5:v6)):((v4>v5)?((v4>v6)?v4:v6):((v5>v6)?v5:v6))))))

宏添加了每个参数的长度加倍,所以我不建议大型数组使用它。但是,如果所有值都是文字,编译器可能会为您解析结果。

答案 5 :(得分:0)

Here是一种采用任意数量参数的解决方案。

计算{args的数量取决于PP_NARG

用法示例:

MAX(1, 2, 3) // == 3
MIN(1, 2, 3, 4, 5) // == 1