Неверное значение, возвращаемое ISO_C_binding & ldquo; c_intptr_t & rdquo; в Fortran / Mac OS X

Если вы похожи на меня, когда я впервые начал использовать Java, я хотел использовать оператор «==» для проверки того, были ли два экземпляра String одинаковыми, но к лучшему или худшему это не правильный способ сделать это в Java.

В этом уроке я продемонстрирую несколько разных способов правильно сравнить строки Java, начиная с подхода, который я использую большую часть времени. В конце этого руководства по сопоставлению Java String я также обсужу, почему оператор «==» не работает при сравнении строк Java.

Вариант 1: Сравнение строк Java с методом equals Большая часть (возможно, в 95% случаев). Я сравниваю строки с методом equals класса Java String следующим образом:

if (string1.equals(string2))

Этот метод String равен методу для двух строк Java, и если они содержат точно такую ​​же строку символов, они считаются равными.

Взглянув на быстрый пример сравнения строк с методом equals, если был выполнен следующий тест, две строки не будут считаться равными, поскольку символы не являются точно такими же (случай символов различен):

String string1 = "foo";
String string2 = "FOO";

if (string1.equals(string2))
{
    // this line will not print because the
    // java string equals method returns false:
    System.out.println("The two strings are the same.")
}

Но, когда две строки содержат одну и ту же строку символов, метод equals вернет true, как в этот пример:

String string1 = "foo";
String string2 = "foo";

// test for equality with the java string equals method
if (string1.equals(string2))
{
    // this line WILL print
    System.out.println("The two strings are the same.")
}

Вариант 2: Сравнение строк с методом equalsIgnoreCase

В некоторых строковых сравнительных тестах вы захотите игнорируйте, являются ли строки строчными или строчными. Если вы хотите проверить свои строки на равенство в этом случае нечувствительным образом, используйте метод equalsIgnoreCase класса String, например:

String string1 = "foo";
String string2 = "FOO";

 // java string compare while ignoring case
 if (string1.equalsIgnoreCase(string2))
 {
     // this line WILL print
     System.out.println("Ignoring case, the two strings are the same.")
 }

Вариант 3: сравнение строк Java с методом compareTo

Существует также третий, менее распространенный способ сравнения строк Java, и это с методом сравнения String класса. Если две строки точно совпадают, метод compareTo вернет значение 0 (ноль). Ниже приведен краткий пример того, как выглядит этот метод сравнения строк:

String string1 = "foo bar";
String string2 = "foo bar";

// java string compare example
if (string1.compareTo(string2) == 0)
{
    // this line WILL print
    System.out.println("The two strings are the same.")
}

Пока я пишу об этой концепции равенства в Java, важно отметить, что язык Java включает в себя метод equals в базовый класс Java Object. Всякий раз, когда вы создаете свои собственные объекты, и вы хотите предоставить средства для проверки того, являются ли два экземпляра вашего объекта «равными», вы должны переопределить (и реализовать) этот метод equals в своем классе (точно так же, как язык Java предоставляет это равенство / сравнение в методе String равно).

Вы можете посмотреть на это ==, .equals (), compareTo () и compare ()

2
задан user7698505 13 July 2018 в 11:05
поделиться

2 ответа

Ваша ошибка здесь:

FUNCTION create_pointer() RESULT(c_intptr_t) BIND(C, name = "create_pointer")

Вы должны поместить имя переменной внутри result части объявления функции. Затем вы можете использовать имя, которое вы там помещаете внутри тела функции, а значение, которое оно имеет при завершении функции, будет значением результата, возвращаемым функцией.

В вашем коде вы помещаете имя c_intptr_t, которое совпадает с именем, которое вы только что импортировали из встроенного модуля, и вы фактически перекрываете его. Я не думаю, что это намерение.

Кроме того, как сказал @francescalus, у вас нет implicit none, поэтому вы позволяете умолчанию неявным правилам Fortran выбрать тип вашей переменной результата; и он выбирает реальное значение по умолчанию (поскольку имя переменной начинается с буквы C), поэтому указатель имеет размер 32 бита.

c_intptr_t является константой внутри встроенного модуль iso_c_binding, предназначенный для использования в качестве параметра типа для интероперабельного целого, который получает правильный размер указателя системы.

Вы можете изменить имя переменной внутри результата, например, ptr, и измените объявление функции на это:

function create_pointer() result(ptr) bind(C, name = "create_pointer")
  use, intrinsic :: iso_c_binding, only: c_intptr_t
  implicit none
  integer(c_intptr_t) :: ptr
end function
2
ответ дан Rodrigo Rodrigues 17 August 2018 в 13:05
поделиться
  • 1
    Что касается «эффективного переопределения»: эти два использования не допускаются, а не название результата функции, которое скрывает значение используемого объекта. Но это прекрасно, потому что интерфейс не включен в какой-либо компилируемый код (что мы видим). – francescalus 13 July 2018 в 13:31
  • 2
    Это то, что я имею в виду, переопределяя: прячусь. – Rodrigo Rodrigues 13 July 2018 в 13:36
  • 3
    Но это не законное скрытие: это нарушение требований Фортрана. Вы совершенно правы, чтобы сказать, что это ошибочно, но это совершенно неправильно, а не то, что предназначено. – francescalus 13 July 2018 в 13:37

На основании решения и комментариев выше мне удалось решить проблему, выполнив следующие действия:

integer(c_intptr_t) function create_pointer() bind(C, name = "create_pointer")
    use, intrinsic :: iso_c_binding, only: c_intptr_t
end function
0
ответ дан user7698505 17 August 2018 в 13:05
поделиться
Другие вопросы по тегам:

Похожие вопросы: