我正在将C代码块转换为Java,我遇到了一些我无法理解的语法。第一个使用#define
来创建一个函数。我个人还没有见过#define
之前创建函数。我也刚刚在这篇文章中发现这真的是一个macro
。下面你将看到我试图用Java解释这段代码。这是C代码:
#define mat_elem(a, y, x, n) (a + ((y) * (n) + (x)))
然后我在Java中转换为这个:
public double mat_elem(double a, int y, int x, int n){
return (a + ((y) * (n) + (x)));
}
现在真正的问题是这个代码块也使用#define
。 C中的代码:
#define A(y, x) (*mat_elem(a, y, x, n))
我还没有转换成Java,因为我不太确定发生了什么。
我首先想到#define A(y, x)
创建的数据类型等于(*mat_elem(a, y, x, n))
中返回的任何数据类型。但是,他们在mat_elem
前面使用的指针让我失望。
我想在Java中做这样的事情:
public double[] fillA(double y, double x){
double [] A = new double [100];
for(int i = 0; i < some_var; i++){
A[i] = mat_elem(a, y, x, n);
}
return A;
}
我确信这样的东西会起作用,但是我主要关注的是理解C代码到底在做什么,以及如果我的不完美代码等同于C中的代码。
我不喜欢那个C代码,但是你可以使用你所拥有的东西。
当你得到这样的东西时,把C翻译成Java的最好的办法就是注释掉包含的标题并通过预处理器运行它并翻译预处理的C代码。有关如何调用预处理器的信息,请参阅此答案:How do I run the GCC preprocessor to get the code after macros like #define are expanded?
事实上,你只想做一次,然后弄清楚它正在做什么,并智能地完成其余的替换,应用代码的逻辑含义而不是直接含义。
在此,它扩展到*(a + ((dia) * (n) + (dia))
。 ((dia) * (n) + (dia)
是一个整数,指针加一个整数是一个指针。因此,它将此复杂表达式广告到指针并对其进行解引用。更常见地写为[((dia)*(n)+(dia)]。
看起来原来的C程序员试图构建一个二维数组,其中第二维不是常数。数组数组是惯用的,但实际上在大多数处理器上都会更快。
mat_elem
和A
都是所谓的函数式宏。
宏是简单的文本替换。如果你定义一个宏
#define FOO a + b
然后,当代码通过预处理器运行时,源代码中的每个FOO
实例都将替换为文本a + b
。
类似函数的宏是类似的,除了你可以传递参数以进行扩展。如果您编写mat_elem(my_matrix, i, j, rows)
,那么当代码被预处理时将被替换为文本
(my_matrix + ((rows) * (i) + (j))
请注意,宏参数不像函数参数那样计算 - 它们只是简单地扩展。 mat_elem(mat, i++, j+2, rows)
将扩大到
(mat + ((rows) * (i++) + (j+2))
宏可以调用其他宏。 A(i, j)
扩展到(*mat_elem(a, y, x, n))
,后者又扩展到
(*(a +((n) * (y) + (x)))
Java AFAIK中没有等效的工具 - 你必须编写方法来完成同样的事情。