2010-03-24 8 views
0

Je me demande quelle est la différence entre sample1 et sample2. Pourquoi parfois je dois passer la structure comme argument et parfois je peux le faire sans le passer dans la fonction? et comment cela se passerait-il si la fonction samplex avait besoin de plusieurs structures pour fonctionner? Souhaitez-vous passer plusieurs structs comme argument?C Struct comme argument

struct x 
{ 
    int a; 
    int b; 
    char *c; 
}; 

void sample1(struct x **z;){ 
    printf(" first member is %d \n", z[0]->a); 
} 

void sample2(){ 
    struct x **z; 
    printf(" first member is %d \n", z[0]->a); // seg fault 
} 

int main(void) 
{ 
    struct x **z; 

    sample1(z); 
    sample2(); 

    return 0; 
} 
+0

Great!Merci pour l'info! J'étais un peu confus avec ça! – Brian

Répondre

1

Tout d'abord, votre type d'argument est struct pas, mais un pointeur vers un pointeur sur struct (ou un tableau de pointeurs sur struct - ce sont sémantiquement équivalentes du point de vue de l'appelé, sauf que l'adresse de un tableau ne peut pas être changé).

Dans le deuxième cas, vous utilisez une variable locale totalement indépendante de celle portant le même nom dans main. Comme il n'est pas initialisé, vous obtenez une erreur seg en essayant d'accéder à un de ses membres. (Celui de main n'est pas initialisé non plus, mais son accès semble fonctionner par hasard en sample1).

Vous devez initialiser vos variables avant de les utiliser, sinon vous entrez dans le champ undefined behavior. Par exemple.

void sample1(struct x **z){ 
    printf(" first member is %d \n", z[0]->a); 
} 

void sample2(){ 
    struct x z[1]; 
    z[0].a = 1; 
    ... 
    printf(" first member is %d \n", z[0].a); 
} 

int main(void) 
{ 
    struct x z[1]; 

    z[0].a = 1; 
    ... 
    sample1(z); 
    sample2(); 

    return 0; 
} 
0

Les deux ne sont pas valides et accèdent à une mauvaise mémoire. Les résultats ne sont pas définis, donc les deux résultats sont corrects.

0

Les langages C et C ont un concept de "portée". Voir toutes ces accolades ({ et })? Ce sont des "blocs". Ils enveloppent essentiellement tout le code entre eux dans des paquets qui sont indépendants de tous les autres blocs au même niveau. Toute variable que vous créez dans ce bloc n'est accessible que dans ce bloc - vous ne pouvez pas le référencer ailleurs.

Vous pouvez créer un bloc imbriqué. Par exemple:

int f() { 
    int x; 
    scanf("%d", &x); 
    if (x == 3) { 
     return 7; 
    } 
    else { 
     return x; 
    } 
} 

Comme vous pouvez le voir, le bloc else est imbriqué dans le bloc de la fonction, et peut donc accéder à variables de la fonction.

Lorsque vous déclarez struct x **z dans les deux main et sample2, vous créez en fait deux variables, à la fois appelé z. Ceux-ci sont totalement indépendants - ils ne sont pas du tout la même variable. Ils ne sont pas liés. La seule chose qu'ils ont en commun est leur nom et leur type: la valeur réelle est différente. La seule façon d'utiliser la même variable dans les deux est de passer, comme vous le faites dans sample1.

Bien sûr, actuellement, votre pointeur z est corrompu - vous n'avez rien alloué. Je vous recommande de stocker quelque chose avant d'essayer de le déréférencer.

0

Votre déclaration

struct x **z; 

crée simplement un pointeur vers un pointeur vers une structure de type x. Vous n'êtes pas en train d'initialiser les pointeurs, c'est-à-dire de les pointer n'importe où.

Essayez quelque chose comme

struct x z; 
struct x *pZ = &z; 

sample1(&pZ); 

(je ne suis pas tout à fait sûr de ce que vous essayez réellement de réaliser, bien que!)