使用预处理器定义指针
Using preprocessor to define pointers
在我的程序中,我使用一次分配分配了五个 NxN 矩阵。 NxN double
s 的每一段都被视为一个单独的矩阵。当我第一次写代码时,我定义了指向每个矩阵的指针。
#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"。
在我的程序中,我使用一次分配分配了五个 NxN 矩阵。 NxN double
s 的每一段都被视为一个单独的矩阵。当我第一次写代码时,我定义了指向每个矩阵的指针。
#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"。