如何将这个使用“#define”作为宏的 C 代码转换为 Java?
How to convert this C code that uses "#define" for macros into Java?
我正在将 C 代码块转换为 Java,我遇到了一些我不太理解的语法。第一个使用 #define
创建一个函数。我个人之前没有见过 #define
创建函数。我也是刚刚在这个post中发现,这真的是一个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))
中返回的任何 get 类型。但是,他们在 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 的最好办法是通过预处理器注释掉头文件 include 和 运行 并翻译预处理的 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 中没有等效的工具 - 您将不得不编写方法来完成同样的事情。
我正在将 C 代码块转换为 Java,我遇到了一些我不太理解的语法。第一个使用 #define
创建一个函数。我个人之前没有见过 #define
创建函数。我也是刚刚在这个post中发现,这真的是一个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))
中返回的任何 get 类型。但是,他们在 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 的最好办法是通过预处理器注释掉头文件 include 和 运行 并翻译预处理的 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 中没有等效的工具 - 您将不得不编写方法来完成同样的事情。