2011-01-31 2 views
3

J'ai une question très simple.Passer un pointeur vers un tableau int à une fonction c

Quel est le problème avec cet appel?

int params[2] = {1, 1}; 
return strcmp95((char*)buffer1, (char*)buffer2, (long)stringLength, &params); 

La fonction est définie comme suit:

double strcmp95(char *ying, char *yang, long y_length, int *ind_c[]) 

{... 

Quand je compilez XCode, je reçois l'avertissement suivant:

avertissement: Argument passage 4 'strcmp95' de pointeur incompatible type

Désolé d'être imprécis. Voici la description de la fonction:

/* Arguments: ying et le yang sont des pointeurs vers les 2 chaînes à comparer. Les chaînes n'ont pas besoin d'être des chaînes à terminaison NUL car la longueur est dépassée. y_length est la longueur des chaînes. ind_c est un tableau qui est utilisé pour définir si certaines options doivent être activées. Une valeur non nulle indique que l'option est désactivée.
Les options sont les suivantes: ind_c [0] Augmente la probabilité d'une correspondance lorsque le nombre de caractères correspondants est grand. Cette option permet un peu plus de tolérance lorsque les chaînes sont grandes. Il n'est pas un test approprié lors de la comparaison des champs de longueur fixe tels que les numéros de téléphone et de sécurité sociale. ind_c [1] Tous les caractères minuscules sont convertis en majuscules avant la comparaison. Désactiver cette caractéristique signifie que le "code" ne sera pas reconnu comme étant le même que le cas "CODE". En outre, l'ajustement pour les caractères similaires s'applique uniquement aux caractères majuscules caractères. Les valeurs suggérées sont toutes des zéros pour les chaînes de caractères telles que . */

+0

Voulez-vous dire que cela ne compile pas ailleurs? C'est à dire que c'est xcode spécifique? – dcousens

+0

Je ne savais pas, c'est pourquoi j'ai ajouté l'étiquette. Pourrait avoir été quelque chose manquait dans XCode. –

+0

Merci, les gars, pour toutes les bonnes réponses. :) –

Répondre

4

params est un int [2], qui se désintègre à un int * lorsqu'il est passé à une fonction, et les fonctions Prenez int [] s car les paramètres prennent vraiment int * s dans les coulisses. Malheureusement, &params est un int(*)[2], qui est plus proche d'un int * que le int ** (identique à int *[] dans un paramètre de fonction) dont vous avez besoin.

Votre meilleure option est de changer votre fonction:

double strcmp95(char *ying, char *yang, long y_length, int *ind_c) 

Et supposer que l'appelant toujours passer un willl int[2]. Ou vous pouvez demander explicitement un int(*)[2] - un pointeur sur un tableau de 2 int s:

double strcmp95(char *ying, char *yang, long y_length, int (*ind_c)[2]) 

Mais cela semble inutile de garantir que deux int s sont passés, et si vous devez tenir compte de la possibilité de plus que deux int s dans la matrice ne conviennent pas. Une meilleure façon est:

double strcmp95(char *ying, char *yang, long y_length, int *ind_c, size_t len) 

size_t est un type entier non signé garanti pour être en mesure de tenir la taille d'un objet ou un index de tableau, et dans ce cas, le paramètre len est la longueur de votre tableau ((sizeof params/sizeof params[0]) si vous voulez être fantaisie/avant de penser, 2 si vous ne le faites pas). C'est la route la plus sûre. Par ailleurs, votre paramètre y_length doit également être une variable size_t. long est signé, et je détesterais avoir à gérer une chaîne de -1 longueur. Même si vous utilisez unsigned long, il n'y a aucune garantie que long sera suffisant pour gérer les tailles d'un système (ou, inversement, qu'une valeur erronée de long sera trop importante pour votre système et causera de la confusion).

+0

Non, '& params' n'est pas la même chose que' params'. Les adresses qu'ils contiennent sont les mêmes mais '& params' a le type' int (*) [2] '. –

+0

J'ai opté pour int (* ind_c) [2]. La fonction est seulement appelée par moi-même, et seulement dans un endroit. Cela ne changera jamais. Donc cette option semble très sûre dans ce scénario. –

+0

@Jens - C'est ce qui arrive quand vous restez jusqu'à 5 heures du matin après avoir dit "Je vais me coucher tôt ce soir et me réveiller à une heure raisonnable." Fixation. –

2

strcmp95 prend un pointeur vers pointeur vers int (int **), pendant que vous faisant passer un pointeur vers un tableau de deux ints (int (*)[2]).

Vous pouvez modifier strcmp95 de telle sorte que sa signature ressemble à ceci:

double strcmp95(char *ying, char *yang, long y_length, int (*ind_c)[]); 

Le point ici est qu'un pointeur vers un tableau (int (*x)[]) n'est pas identique à un tableau de pointeurs (qui est int *(x[]) et est le même que int *x[])

+0

Uhm ... d'accord. Je vais essayer de comprendre comment changer cela. :) Quels sont les avantages/inconvénients de chaque approche? –

+0

@Joseph Tura: J'ai mis à jour la réponse.'int * x []' est un tableau de pointeurs, pendant que vous passez un pointeur sur un tableau. – peoro

1

Il est difficile de savoir si strcmp95 doit prendre un tableau d'ints comme vous essayez de passer, ou il est censé prendre un tableau de pointeurs int comme les demandes du prototype. Le premier semble probable - si oui, vous devriez changer ...

double strcmp95(char *ying, char *yang, long y_length, int *ind_c[]) 

... à ...

double strcmp95(char *ying, char *yang, long y_length, int *ind_c) 

... ou ... qui revient

double strcmp95(char *ying, char *yang, long y_length, int ind_c[]) 
1

Pourquoi vous passer & params, params seraient suffire, comme un tableau agit comme un pointeur.

return strcmp95((char*)buffer1, (char*)buffer2, (long)stringLength, params); 

Et d'autre part strcmp95 devrait maintenant être attendre un tableau de ints, ce sera bien:

double strcmp95(char *ying, char *yang, long y_length, int ind_c[]) 
1

Aussi je pense que vous passez des params (qui est un pointeur entier en soi) et la fonction strncmp95 attend un pointeur vers un tableau d'entiers i.e int * ind_c [].

Questions connexes