2010-08-18 10 views
5

J'essaie de transmettre un tableau de chaînes de caractères (chaînes de style C) à une fonction. Cependant, je ne veux pas placer une taille maximale sur la longueur de chaque chaîne entrant dans la fonction, et je ne veux pas allouer les tableaux dynamiquement. Voici le code que j'ai écrit d'abord:Passer un tableau de chaînes de caractères à la fonction

#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 

void fun(char *s[]) 
{ 
    printf("Entering Fun\n"); 
    printf("s[1]=%s\n",(char *)s[1]); 
} 

int main(void) 
{ 
    char myStrings[2][12]; 

    strcpy(myStrings[0],"7/2/2010"); 
    strcpy(myStrings[1],"hello"); 
    fun(myStrings); 

    return(0); 
} 

Je suis une faute de seg lorsqu'il est exécuté et l'avertissement suivant du compilateur: stackov.c: En fonction « principale »: stackov.c: 17: avertissement: passer l'argument 1 de 'fun' du type pointeur incompatible stackov.c: 5: note: attendu 'char **' mais l'argument est de type 'char (*) [12]'

Cependant, quand je change le principal() au suivant cela fonctionne:

int main(void) 
{ 
    char myStrings[2][12]; 
    char *newStrings[2]; 

    strcpy(myStrings[0],"7/2/2010"); 
    strcpy(myStrings[1],"hello"); 
    newStrings[0]=myStrings[0]; 
    newStrings[1]=myStrings[1]; 
    fun(newStrings); 

    return(0); 
} 

Est-ce que array [2] [12] n'est pas la même chose qu'un tableau de pointeurs de caractères quand il est passé à une fonction?

Répondre

7

Non, char array[2][12] est un tableau à deux dimensions (tableau de tableaux). char *array[2] est un tableau de pointeurs.

char array[2][12] ressemble:

7/2/2010\0\x\x\xhello\0\x\x\x\x\x\x 

où \ 0 est NUL et \ x est indéterminée.

tandis

char *array[2] est:

0x CAFEBABEDEADBEEF 

(en supposant que 32 bits)

Le premier a 24 caractères contigus, le second a deux pointeurs (aux débuts de cordes d'ailleurs).

2

Est-ce que array [2] [12] n'est pas la même chose qu'un tableau de pointeurs de caractères quand il est passé à une fonction?

Non, il s'agit d'un tableau à deux dimensions. La différence est qu'un tableau de pointeurs contient des pointeurs, mais array[2][12] est en réalité un tableau de tableaux - pas de pointeurs impliqués.

vous pourriez BTW faire:

char* mystrings[2]={"aha", "haha"}; 
fun(mystrings); 
+0

Cela a l'avantage de stocker uniquement le nombre réel de caractères requis pour les chaînes. L'inconvénient est qu'un pointeur (supplémentaire) est également alloué pour chaque chaîne. Mais la facilité d'utilisation des pointeurs est le principal avantage. –

+0

Oui, je sais que cela a fonctionné, mais pour l'application réelle, je n'ai pas pu initialiser le tableau au moment de la compilation. – Mike

+0

@Mike: Lorsque vous l'utilisez dans une fonction, le tableau est réellement initialisé au moment de l'exécution. – jpalecek

0

Votre tableau est déclaré comme un tableau 2-D, mais vous voulez passer à la fonction comme si elle est un tableau 1-D de pointeurs de chaîne.

La réponse de Tom est correcte, vous pouvez omettre la taille de la première dimension des déclarations de tableaux multidimensionnels pour les paramètres de fonction.

Votre deuxième solution fonctionne car elle transmet explicitement un tableau de pointeurs de chaîne à la fonction.Bien sûr, il nécessite le surcoût supplémentaire du tableau de pointeurs en plus du tableau de chaînes 2-D original.

1

char myStrings[2][12]; déclare myStrings en tant que tableau de tableaux de caractères. Cela signifie que myStrings est stockée comme 24 octets

7/2/2010.???hello.?????? 
‘——————————’‘——————————’ 
myStrings[0]myStrings[1] 

. représente un caractère nul et ? représente un octet non initialisé.

char *newStrings[2]; déclare newStrings en tant que tableau de pointeurs vers des caractères. Cela signifie que newStrings est stocké en tant que 2 × sizeof(char*) octets

[..][..] 

[..] représente un objet de pointeur (non encore initialisé).

Si vous souhaitez transmettre des chaînes de différentes longueurs à votre fonction, vous devez passer un tableau de pointeurs, pas un tableau de tableaux. Comme vous pouvez le voir ci-dessus, ce sont des mises en page différentes.

Conseil général: lorsque vous êtes autour de pointeurs, dessiner des diagrammes (sur tableau blanc ou tableau noir si vous le pouvez, sinon sur papier) montrant les différents objets en mémoire, avec des flèches indiquant ce qui pointe où. Il y a deux sortes de programmeurs en C: ceux qui dessinent de tels diagrammes quand ils rencontrent des pointeurs, et ceux qui sont vraiment expérimentés qui dessinent les diagrammes dans leur tête.

+0

Je suis confus par votre instruction: "Notez que vos appels suivants à strcpy essaient d'écrire sur un pointeur qui n'a pas été initialisé, ce qui était une mauvaise chance que le programme ait donné le résultat que vous vouliez. Que voulez-vous dire? De plus, qu'est-ce que vous obtenez par "pointeur qui n'a pas été initialisé"? Merci – Mike

+0

@Mike: Désolé, ce morceau était une erreur de ma part (j'ai mal interprété votre code). – Gilles

+0

Pas de problème. Je voulais juste m'assurer que je ne manquais pas quelque chose. – Mike

Questions connexes