2010-01-10 3 views
1

dans ma phase de (ré) apprentissage C, je suis souvent confronté à des problèmes de tableaux et de structures (et de pointeurs). C'est un petit test que j'ai écrit.C: Structs and array - vue d'ensemble et aide nécessaire

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

typedef struct { 
    char name[10]; 
} man; 

int main (int argc, const char * argv[]) { 
    int i; 
    man john; 
    strcpy(john.name, "john"); 

    // array of structures 
    man men[10]; 
    strcpy(men[3].name, "john"); 
    printf("*** %s ***\n", men[3].name); 

    // dynamic array of structures 
    man *men2; 
    men2 = malloc(10 * sizeof(man)); 
    strcpy(men2[3].name, "john"); 
    printf("*** %s ***\n", men2[3].name); 

    // multidimensional array of structures 
    man men3[10][10]; 
    strcpy(men3[3][3].name, "john"); 
    printf("*** %s ***\n", men3[3][3].name); 

    // dynamic multidimensional array of structures 
    man **men4; 
    men4 = malloc(10 * sizeof(man*)); 
    for (i = 0; i < 10; i++) 
     men4[i] = malloc(10 * sizeof(man*)); 
    strcpy(men4[3][3].name, "john"); 
    printf("*** %s ***\n", men4[3][3].name); 

    // array of pointer to structure 
    man *men5[10]; 
    men5[3] = &john; 
    printf("*** %s ***\n", men5[3]->name); 

    // dynamic array of pointers to structure 
    man **men6; 
    men6 = malloc(10 * sizeof(*men6)); 
    men6[3] = &john; 
    printf("*** %s ***\n", men6[3]->name); 

    // dynamic multidimensional array of pointers to structures 
    /* ? */ 

    return 0; 
} 

Pouvez-vous:

  1. me dire si tout est correct
  2. expliquer pourquoi hommes4 j'utilise sizeof(man*) mais hommes6 il est sizeof(*men6) (position astérisque)
  3. expliquer comment faire tableau multidimensionnel dynamique de pointeurs vers des structures (dernier point)
  4. Expliquez-moi men4? cela fonctionne, mais il me semble plus d'un tableau de pointeurs à structure qu'un tableau multidimensionnel de structures!

Merci d'avance.

Répondre

1

Tout d'abord, vos ces deux cas

// dynamic multidimensional array of structures 
man **men4; 
men4 = malloc(10 * sizeof(man*)); 
for (i = 0; i < 10; i++) 
    men4[i] = malloc(10 * sizeof(man*)); 

et

// dynamic array of pointers to structure 
man **men6; 
men6 = malloc(10 * sizeof(*men6)); 
men6[3] = &john; 
printf("*** %s ***\n", men6[3]->name); 

sont conceptuellement le même. Dans les deux cas, vous avez un pointeur vers un pointeur vers man. Vous utilisez ces pointeurs différemment. En outre, le premier a une erreur. Au lieu de:

men4[i] = malloc(10 * sizeof(man*)); 

vous devriez avoir écrit:

men4[i] = malloc(10 * sizeof(man)); 

parce que chaque men4[i] est de type "pointeur vers man".Cette erreur est la raison pour laquelle je préfère habituellement mes malloc() appelle à être de la forme:

a = malloc(N * sizeof *a); 

Ainsi, votre appel serait devenu:

men4[i] = malloc(10 * sizeof *men4[i]); 

Ceci est moins sujette aux erreurs. Donc, la réponse à votre question (2) est que vous devriez utiliser sizeof(man *) uniquement lorsque vous attribuez men4, mais pas à l'intérieur de la boucle. (Ou bien, vous savez maintenant une meilleure façon d'appeler malloc(), donc l'appel intransportables la boucle devient men4 = malloc(10 * sizeof *men4);.)

  1. Il est tout correct, à l'exception de l'appel malloc() comme mentionné ci-dessus.
  2. Voir ci-dessus.
  3. Vous voulez un tableau de pointeurs struct. Pour obtenir un tableau, vous avez besoin de [], puisqu'il s'agit d'un pointeur vers un pointeur que vous voulez (multidimensionnel), vous voulez deux . Donc, vous obtenez: man **(men7[10]);, mais depuis [] se lie plus étroitement que * de toute façon, vous pouvez l'écrire comme man **men7[10];.
  4. men4 n'est pas un tableau multidimensionnel ni un tableau de pointeurs. C'est un pointeur vers un pointeur vers man. Lorsque vous allouez de la mémoire pour men4, vous allouez de l'espace pour 10 pointeurs à man. Ensuite, chaque pointeur reçoit un espace pour 10 man. Le fait que vous pouvez indexer men4 comme un tableau multidimensionnel est le résultat d'une telle allocation. Dans votre boucle, chaque men4[i] aurait pu recevoir de l'espace pour un nombre différent de valeurs man si vous l'aviez souhaité, ce qui est impossible avec les tableaux multidimensionnels.

Les pointeurs ne sont pas des matrices. Les tableaux ne sont pas des pointeurs. Veuillez lire toutes les questions et réponses au section 6 of the C FAQ pour plus de détails.

0
  1. sémantiquement correct
  2. Il IS un tableau de pointeurs, donc vous devez affecter des éléments de taille pointeur, et la taille du pointeur est sizeof(void*) qui est égal à sizeof(man*)
  3. man ***men;
  4. Oui, ça l'est. Devrait être man **men[10];
1
  • 2: Ce sont deux exemples qui font la même chose: sizeof(*men6) == sizeof(man*)!
  • 3: Identique à l'exemple men5, mais multidimensionnel.
  • 4: L'exemple men4 n'est pas tout à fait correct. Pour autant que je comprends ce qu'il faut dire, cet exemple doit lire:

man ***men4; // 10x10 multidimensional 
men4 = malloc(10 * sizeof(man**)); 
for (i = 0; i < 10; i++) 
{ 
    men4[i] = malloc(10 * sizeof(man*)); 
    for(j = 0; j < 10; ++j) 
     men4[i][j] = malloc(sizeof(man)); 
}  
strcpy(men4[3][3]->name, "john"); 
printf("*** %s ***\n", men4[3][3]->name);