Как преобразовать этот код C, который использует "#define" для макросов в Java? - PullRequest
1 голос
/ 29 апреля 2019

Я конвертирую блоки кода на 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.

Ответы [ 2 ]

1 голос
/ 29 апреля 2019

И 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 нет эквивалентного средства - вам придется писать методы для достижения того же самого.

1 голос
/ 29 апреля 2019

Мне не очень нравится этот код на C, но вы работаете с тем, что у вас есть.

Когда вы получаете что-то подобное, лучше всего переводить C на Java - комментировать заголовок, включающийи запустить его через препроцессор и перевести предварительно обработанный код C.Посмотрите этот ответ, чтобы узнать, как вызвать препроцессор: Как запустить препроцессор GCC, чтобы получить код после расширения таких макросов, как #define?

На самом деле вы хотите сделать это только один раззатем выясните, что он делает, и сделайте остальную часть замен разумно, применяя логический смысл кода, а не прямой смысл.

В этом он расширяется до *(a + ((dia) * (n) + (dia)).((dia) * (n) + (dia) - это целое число, указатель плюс целое число - это указатель.Поэтому он объявляет это сложное выражение в указателе и разыменовывает его.Чаще всего записывается как [((dia) * (n) + (dia)].

Похоже, что оригинальный программист C пытался создать двумерный массив, где второе измерение не было константой.Массивы массивов идиоматичны, но на самом деле это будет быстрее на большинстве процессоров.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...