почему эти массивы C / Cython определены как символьные, а не целочисленные массивы? - PullRequest
0 голосов
/ 01 августа 2010

в попытке решить вопрос # 3367795 здесь, ТАК, я должен справиться с рядом подзадач.Одним из них является то, что в указанном алгоритме (расстояние Левенштейна) несколько массивов выделяются в памяти и инициализируются строками

cdef char   *m1     = <char *>calloc(   blen + 2,    sizeof( char ) )
cdef char   *m2     = <char *>calloc(   blen + 2,    sizeof( char ) )
cdef char   *m3     = <char *>malloc( ( blen + 2 ) * sizeof( char ) )
#.........................................................................
for i from 0 <= i <= blen:
  m2[ i ] = i
  <...snip...>

blen, здесь относится к длине переменной Python bytes.теперь, насколько я понимаю алгоритм (см. мой оригинальный пост для полного кода) и как ясно показывает код для инициализации m2, эти массивы предназначены для хранения целых чисел, а не символов, поэтому можно было бы подумать, что правильныйассигнования должны выглядеть как

cdef int    *m3     = <int *>malloc( ( blen + 2 ) * sizeof( int ) )

и так далее.Может кто-нибудь с фоном в C объяснить мне, почему char используется?Кроме того, может быть, больше для людей, склонных к Cython, почему есть бросок <char *>?можно подумать, что char *x = malloc( ... ) должно быть достаточно для определения x.

Ответы [ 2 ]

8 голосов
/ 01 августа 2010

Несмотря на вводящее в заблуждение имя, char типы на языке C являются обычными целыми типами, такими же, как short, int, long и такими. * Из всех интегральных типов char имеют наименьший диапазон и занимают наименьший объем памяти. Таким образом, если в вашем приложении важно сохранить как можно больше памяти, имеет смысл использовать char вместо int.

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

2 голосов
/ 01 августа 2010

Проще говоря, для экономии памяти - но, пожалуйста, обратите внимание, что объявление этих массивов как char ограничивает расстояние результата до 127 или 255, в зависимости от того, по умолчанию компилятор C равен signed char или unsigned char соответственно.В C char является целочисленным типом - вам не нужно ord(), чтобы получить его целочисленное значение.

Ваш исходный код не содержит упоминаний об этом ограничении. Обратите внимание, что если char переполняется, он делает это тихо, и код выдаст неверные результаты - 127 + 1 -> -128 (подписано);255 + 1 -> 0 (без знака).

Вы не ответили на мой комментарий к своему первоначальному вопросу: "" "Каковы (a) максимальные (b) средние размеры ваших строк?действительно нужно делать все, что нужно (M * N), если две строки не похожи друг на друга? "" "..... Пожалуйста, ответьте сейчас (отредактируйте свой вопрос);если бы вы сделали это тогда, вы бы ответили на этот вопрос.

Обновление: при повторном чтении исходного сообщения я обнаружил проблему: код, который читает

m1, m2 = m2, m1
strcpy( m3, m2 )

,НЕПРАВИЛЬНО по трем причинам: (1) он не перетасовывает строки должным образом (должен сделать strcpy() перед заменой m1 и m2) (2) strcpy() не будет копировать ничего, кроме первого нуля (нулевого байта)(3) не нужно ничего копировать, просто перетасуйте указатели

m3, m2, m1 = m2, m1, m3
...