使用预处理器定义指针

Using preprocessor to define pointers

在我的程序中,我使用一次分配分配了五个 NxN 矩阵。 NxN doubles 的每一段都被视为一个单独的矩阵。当我第一次写代码时,我定义了指向每个矩阵的指针。

#define MAX_N 1024 // could be anything
double* matricies = aligned_alloc(32, 5 * MAX_N * MAX_N * sizeof(double));
double* MA = matricies;
double* MB = matricies + MAX_N * MAX_N;
double* MC1 = matricies + 2 * MAX_N * MAX_N;
double* MC2 = matricies + 3 * MAX_N * MAX_N;
double* MC3 = matricies + 4 * MAX_N * MAX_N;

想了想,由于每个矩阵的偏移量可以在编译时确定,所以写了这段代码。

double* matricies = aligned_alloc(32, 5 * MAX_N * MAX_N * sizeof(double));

#define MA (matricies)
#define MB (matricies + MAX_N * MAX_N)
#define MC1 (matricies + 2 * MAX_N * MAX_N)
#define MC2 (matricies + 3 * MAX_N * MAX_N)
#define MC3 (matricies + 4 * MAX_N * MAX_N)

这些标识符在程序的其余部分用作指针。我的问题是这是否是一种好的做法?我感觉这不会扩展,因为标识符可能会与源代码中的其他文本发生冲突。您当然可以 #undef 根据需要,但它可能会变得笨重。

whether or not this is a good practice?

#define MC3 (matricies + 4 * MAX_N * MAX_N) 不是一个好主意。代码隐藏不寻常的编码方法导致更高的维护成本。


请注意 5 * MAX_N * MAX_N 的一个问题。它是用 int 数学完成的,但数组索引和大小调整最好用 size_t 数学完成。当 MAX_N > 21000 建议 1) 与 sizeof(double) 进行前导乘法和 2) 在 #define MAX_N 1024u 等大小常量上使用 u 时,原始代码可能会溢出 3) 不要执行此宏技巧

这主要取决于您是否会使用一种方式或另一种方式。 "defines" 方法将节省一点内存,因为您不需要指针变量。但是,编译器可能会优化代码中的变量,所以......也许无论如何都没有保存任何东西。在我看来,"defines" 方法使代码更难理解和维护,因此我不会使用定义。

您的代码的重要问题 然而,它并没有按照您所说的那样执行。你说你想要 NxN 矩阵,但你的代码不允许我们那样使用它。示例:

#define MAX_N 1024

int main(){
    double* matricies = aligned_alloc(32, 5 * MAX_N * MAX_N * sizeof(double));
    double* MA = matricies;
    double* MB = matricies + MAX_N * MAX_N;

    MA[0][3] = 42.1;          // error
    MB[2][1] = 123.8;         // error

    printf("%f\n", MA[0][3]); // error  
    printf("%f\n", MB[2][1]); // error  

    return 0;
}

此代码会导致编译器错误,例如:

main.cpp:12:10: error: subscripted value is neither array nor pointer nor vector
     MA[0][3] = 42.1;

因为 MA 是一个指向双精度数的指针。要使用 MA[..][..] 访问数据,您需要 MA 的不同类型。那可能是 "a pointer to an array of double"。喜欢:

#define MAX_N 1024

int main(){
    void* matricies = aligned_alloc(32, 5 * MAX_N * MAX_N * sizeof(double));
    double (*MA)[MAX_N] = matricies;
    double (*MB)[MAX_N] = MA + MAX_N;


    MA[0][3] = 42.1;
    MB[2][1] = 123.8;

    printf("%f\n", MA[0][3]);  
    printf("%f\n", MB[2][1]);  

    return 0;
}

这段代码编译没有错误,并且可以像预期的那样访问 NxN 矩阵。最后,IMO 也比你原来的更容易阅读和理解 "defines approach"。