C 如何使用预处理器缩短这些行?

C 如何使用预处理器缩短这些行?,c,c-preprocessor,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]; ...

我的代码中有这些行,我想可能有一些很好的方法可以使用预处理器生成这些行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);

网上有关于预处理阶段符号计算的文章,一个典型的例子是

如果定义的机制对您来说太多,而您不太关心生成代码的美观,那么您可以使用便宜的替代方案,例如未经测试:

定义一个MEMi,一个MemType mem\ua[MAX\u mem];mem[i]=mem_ua 定义MEM_1i,一个ONE_MEMi,一个;一个成员+1,一个1 定义MEM_2i,一个MEM_1i,一个;成员1+2,a2 定义MEM_4i,MEM_2i,a;MEM_2i+4,a4 以此类推,现在定义的宏数量是对数的

如果没有测试,实际的定义可能需要一个或两个concat间接寻址


还有一些改进,比如声明一个宏参数来代替mem等。

网上有关于预处理阶段符号计算的文章,一个典型的例子是

如果定义的机制对您来说太多,而您不太关心生成代码的美观,那么您可以使用便宜的替代方案,例如未经测试:

定义一个MEMi,一个MemType mem\ua[MAX\u mem];mem[i]=mem_ua 定义MEM_1i,一个ONE_MEMi,一个;一个成员+1,一个1 定义MEM_2i,一个MEM_1i,一个;成员1+2,a2 定义MEM_4i,MEM_2i,a;MEM_2i+4,a4 以此类推,现在定义的宏数量是对数的

如果没有测试,实际的定义可能需要一个或两个concat间接寻址


可以进行改进,例如声明宏参数以替换mem等。

使用boost/preprocessor/repeation/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, ())
};

使用boost/preprocessor/repeation/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, ())
};

堆栈非常有限,不应该像前面讨论的那样用于分配巨大的数据结构。相反,请尝试使用分配内存。如果确实需要多维数组,则可以使用指针数组,这些指针数组指向指向所述结构的数组

但是,由于您最初的目的是使用单个数组,因此无需预处理器即可实现此目的:

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

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

堆栈非常有限,不应像前面讨论的那样用于分配巨大的数据结构。相反,请尝试使用分配内存。如果确实需要多维数组,则可以使用指针数组,这些指针数组指向指向所述结构的数组

但是,由于您最初的目的是使用单个数组,因此无需预处理器即可实现此目的:

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

将其封装在一个类中,在构造函数中分配,如果分配失败则抛出异常,并在析构函数中取消分配。使用STL向量的动态分配:

#include <vector>

class Mem_type {};
const int MAX_NUM_MEM = 5;
const int NUM_BANKS   = 5;

// allocates NUM_BANKS vectors with MAX_NUM_MEM objects of Mem_type
std::vector<std::vector<Mem_type>> MEM(NUM_BANKS, std::vector<Mem_type>(MAX_NUM_MEM));

使用STL向量的动态分配:

#include <vector>

class Mem_type {};
const int MAX_NUM_MEM = 5;
const int NUM_BANKS   = 5;

// allocates NUM_BANKS vectors with MAX_NUM_MEM objects of Mem_type
std::vector<std::vector<Mem_type>> MEM(NUM_BANKS, std::vector<Mem_type>(MAX_NUM_MEM));
可以将标记与连接标记一起使用

#define LIST_OF_MEMS    \
X(0)                    \   
X(1)                    \
X(2)                    \
X(3)                    \
X(4)                    \
X(5)                    \
...                     \
X(30)                   \
X(31)                   \
现在,您可以在每次想用所有MEMs做任何事情时使用它。请注意,对变量名使用所有大写字母是个坏主意

// 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
可以将标记与连接标记一起使用

#define LIST_OF_MEMS    \
X(0)                    \   
X(1)                    \
X(2)                    \
X(3)                    \
X(4)                    \
X(5)                    \
...                     \
X(30)                   \
X(31)                   \
现在,您可以在每次想用所有MEMs做任何事情时使用它。请注意,对变量名使用所有大写字母是个坏主意

// 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

Mem_类型Mem[NUM_BANKS][MAX_NUM_Mem]@tkausl我本来就是这么做的。但我认为我的机器似乎有一些最大的连续数组大小限制,所以我决定拆分“MEM”并分散,这样我就可以有更大的聚合MEM大小。@KayK。这将有助于在问题中提及;不使用堆栈,您可以尝试为数组分配新的。堆有更多的空间。或者,您可以尝试使用类似向量的东西,而不是数组。如果数组大小仍然是一个问题,它不应该根据这个问题,那么您可以通过编程将新的、较小的数组推送到向量,而不是使用一个较大的数组。据我所知,没有Linux机器会有这样的连续数组大小限制。最有可能的情况是,您的内存堆栈大小不足,仅将阵列拆分为多个阵列对您没有帮助。Mem_type Mem[NUM_BANKS][MAX_NUM_Mem]@tkausl我本来就是这么做的。但我认为我的机器似乎有一些最大的连续数组大小限制,所以我决定拆分“MEM”并分散,这样我就可以有更大的聚合MEM大小。@KayK。这将有助于在问题中提及;不使用堆栈,您可以尝试为数组分配新的。堆有更多的空间。或者,您可以尝试使用类似向量的东西,而不是数组。如果数组大小仍然是一个问题,它不应该依据这个问题,那么您可以通过编程将新的、更小的数组推送到向量,而不是使用on
我知道没有Linux机器会有这样的连续数组大小限制。最有可能的情况是,您的内存堆栈大小已用完,仅将阵列拆分为多个阵列对您没有帮助。谢谢。使用2的幂是一个有趣的想法。我不在乎变量名中的实际编号,所以我认为这可能对我有用。简单地说,就是一个经典的分而治之法-谢谢使用2的幂是一个有趣的想法。我不在乎变量名中的实际编号,所以我认为这可能对我有用。简单地说,就是一个经典的分而治之法-谢谢这正是我想要的。谢谢。这正是我想要的。谢谢。我试试看。一个问题是,“new”能否返回空指针分配失败?我这样问是因为“如果”的说法。顺便说一句,虽然我认为这个答案实际上对我有帮助,但我觉得我需要接受另一个答案,因为那就是回答关于预处理器的原始问题。对此很抱歉。根据new抛出异常,除非您另有指定。如果我没有记错的话,它在旧的C++标准中返回失败的空指针。CThanks中没有新的关键字。我试试看。一个问题是,“new”能否返回空指针分配失败?我这样问是因为“如果”的说法。顺便说一句,虽然我认为这个答案实际上对我有帮助,但我觉得我需要接受另一个答案,因为那就是回答关于预处理器的原始问题。对此很抱歉。根据new抛出异常,除非您另有指定。在旧的C++标准中,如果返回错误,它返回空指针,如果我没有记错的话,C中没有新关键字。