如何使用预处理程序缩短这些行?

时间:2019-04-16 06:59:08

标签: c c-preprocessor

我的代码中包含这些行,并在考虑使用预处理器生成这些行(0到31)的某种好方法。

    Mem_type MEM_0[MAX_NUM_MEM];
    Mem_type MEM_1[MAX_NUM_MEM];
    Mem_type MEM_2[MAX_NUM_MEM];
    Mem_type MEM_3[MAX_NUM_MEM];
    Mem_type MEM_4[MAX_NUM_MEM];
    Mem_type MEM_5[MAX_NUM_MEM];
    ...
    Mem_type MEM_30[MAX_NUM_MEM];
    Mem_type MEM_31[MAX_NUM_MEM];

    Mem_type *MEM[NUM_BANKS];

    MEM[0] = MEM_0;
    MEM[1] = MEM_1;
    MEM[2] = MEM_2;
    MEM[3] = MEM_3;
    MEM[4] = MEM_4;
    MEM[5] = MEM_5;
    ...
    MEM[30] = MEM_30;
    MEM[31] = MEM_31;

例如,类似:

    #define Gen(n) MEM[n] = MEM_n
    #for (k=0; k<32; k++) Gen(k);

(之所以不喜欢以下内容,是因为我发现我的机器具有一些最大的连续数组大小限制,因此我尝试将其拆分为单独的数组,以便可以拥有更大的聚合MEM大小。)

    Mem_type MEM[NUM_BANKS][MAX_NUM_MEM];

5 个答案:

答案 0 :(得分:3)

网上有关于预处理阶段的符号计算的文章,一个典型的例子是http://jhnet.co.uk/articles/cpp_magic

如果定义的机制对您来说太多了,并且您不太在意生成的代码的美观性,则可以使用便宜的替代方法,例如(未经测试的):

#define ONE_MEM(i, a) MemType mem_ ## a[MAX_MEM]; mem[i] = mem_ ## a
#define MEM_1(i, a) ONE_MEM(i, a); ONE_MEM(i + 1, a ## 1)
#define MEM_2(i, a) MEM_1(i, a); MEM_1(i + 2, a##2)
#define MEM_4(i, a) MEM_2(i, a); MEM_2(i + 4, a##4)

依此类推,现在已定义的宏数量为对数。

(尚未测试,实际定义可能需要一个或两个concat间接访问。)

可以进行改进,例如声明一个宏参数来代替mem等。

答案 1 :(得分:3)

使用boost / preprocessor / repeat / repeat.hpp

#include <boost/preprocessor/repetition/repeat.hpp>
class Mem_type {};

#define MAX_NUM_MEM  5
#define NUM_BANKS    5

#define MEM_DECL(z, n, text)  Mem_type MEM_## n[MAX_NUM_MEM];
#define MEM_MEMB(z, n, text)  MEM_## n,

// expands to `Mem_type MEM_?[MAX_NUM_MEM];`
BOOST_PP_REPEAT(NUM_BANKS, MEM_DECL, ())

Mem_type *MEM[NUM_BANKS] = {
    // expands to `MEM_?,`
    BOOST_PP_REPEAT(NUM_BANKS, MEM_MEMB, ())
};

答案 2 :(得分:2)

栈非常有限,不应该用于分配像here那样的大型数据结构。而是尝试使用new[]分配内存。如果确实需要多维数组,则可以使用指针数组,该指针数组指向指向您的结构的数组,如here所述。

尽管您最初的意图是拥有一个数组,但不需要预处理器就可以解决问题:

Mem_type* MEM = new Mem_type[MAX_NUM_MEM]; // MAX_NUM_MEM is multiplied by NUM_BANKS here
// do things [...]
delete[] MEM;
MEM = nullptr;

将其包装在一个类中,在构造函数中分配,如果分配失败并在析构函数中取消分配,则抛出异常是一个好主意。

答案 3 :(得分:1)

通过STL向量使用动态分配:

Vue-Cli

答案 4 :(得分:1)

您可以将X Macro与令牌串联一起使用

#define LIST_OF_MEMS    \
X(0)                    \   
X(1)                    \
X(2)                    \
X(3)                    \
X(4)                    \
X(5)                    \
...                     \
X(30)                   \
X(31)                   \

现在,您每次要对所有MEM执行任何操作时都可以使用它。请注意,将所有大写字母用作变量名是一个好主意

// declaration
#define X(num) Mem_type mem_##num[MAX_NUM_MEM];
LIST_OF_MEMS
#undef X

// assignment
#define X(num) MEM[num] = mem_##num;
LIST_OF_MEMS
#undef X