2010-07-31 5 views
0

dans un effort pour résoudre la question #3367795 ici sur SO je dois faire face à un certain nombre de sous-problèmes. l'un d'eux est: dans ledit algorithme (distance de Levenshtein), plusieurs matrices sont attribuées dans la mémoire et initialisé avec les lignespourquoi ces tableaux C/Cython sont-ils définis en tant que tableaux de caractères et non en nombres entiers?

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 ici se réfère à la longueur d'une variable Python bytes. maintenant pour autant que je comprends l'algorithme (voir mon message original pour le code complet) et que le code pour l'initialisation de m2 montre clairement, ces tableaux sont destinés à contenir des nombres entiers, pas de caractères, donc on pourrait penser que les allocations correctes devraient ressembler à

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

et ainsi de suite. Quelqu'un peut-il avoir une expérience en C élucider à moi pourquoi char est utilisé? aussi, peut-être plus pour les gens enclins à Cython, pourquoi y a-t-il un casting <char *>? on pourrait penser que char *x = malloc(...) devrait suffire pour définir x.

Répondre

2

Tout simplement, pour sauvegarder la mémoire - mais s'il vous plaît noter soigneusement que déclarant ces tableaux comme char limite la distance de résultat, soit 127 ou 255, selon que les paramètres par défaut du compilateur C à signed char ou unsigned char respectivement. En C, char est un type entier - vous n'avez pas besoin de ord() pour obtenir sa valeur entière.

Votre code d'origine ne contient aucune mention de cette limitation. Notez que si un char déborde, il le fait silencieusement et le code produira des résultats incorrects - 127 + 1 -> -128 (signé); 255 + 1 -> 0 (non signé).

Vous n'avez pas répondu à mon commentaire sur votre question originale: "" "Quelles sont les (a) maximum (b) la taille moyenne de vos cordes? Avez-vous vraiment besoin de faire l'ensemble O (M * N) chose si les deux cordes ne sont rien les unes des autres? "" "..... S'il vous plaît répondez maintenant (éditez votre question); Si vous l'aviez fait alors, vous auriez répondu à cette question.

Mise à jour: En relisant le message original, je l'ai remarqué un problème: Le code qui lit

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

est MAUVAIS sur trois motifs: (1) il ne mélangez pas les lignes correctement (devrait faire strcpy() avant d'échanger m1 et m2) (2) strcpy() ne copiera rien au-delà de la première, il n'y est nulle (zéro octet) (3) besoin de copier quoi que ce soit, juste mélanger les pointeurs

m3, m2, m1 = m2, m1, m3 
+0

thx; Ton commentaire ne m'est pas visible. J'ai ajouté une modification pour répondre à ce point. – flow

+0

@flow: Il est visible pour vous (1) à la fin des commentaires vous verrez "show 1 more comment" (2) vous auriez été averti d'un nouveau commentaire par l'icône de petite enveloppe en haut de la page à côté de votre nom étant surlignée –

+0

vous avez raison. C'est tellement subtil. – flow

8

Malgré son nom trompeur, char types en langage C sont ordinaires types intégrale, tout comme short, int, long et tel. De tous les types intégraux, char ont la plus petite plage et occupent la plus petite quantité de mémoire. Donc, si dans votre application il est important d'enregistrer autant de mémoire que possible, il peut être judicieux d'utiliser char au lieu de int.

Sur certaines plates-formes matérielles, il peut arriver que int types fonctionnent plus rapidement que char types, de sorte que le choix du type spécifique devient une vitesse-vs-mémoire compromis, mais, encore une fois, dans de nombreux cas, lorsque la plage de char est naturellement suffisant, il pourrait être plus logique d'utiliser char au lieu de int.

+1

juste une remarque mineure: Le type int_fast8_t de C99 (et dérivés) laisse le compromis entre la vitesse et la taille à la mise en œuvre. Habituellement, il vous donne le type le plus rapide avec un minimum de 8 bits (un octet sur la plupart des systèmes, c'est-à-dire un 'char') disponible. – RWS

+4

au moins * si * cela doit être considéré comme un petit entier, il ne faut jamais, jamais utiliser 'char' comme type, car sa signature n'est pas définie et peut varier d'une plateforme à l'autre. Utilisez 'char signé ',' char non signé' ou mieux nommé 'int_fast8_t' ou' int8_T' etc. –