2009-11-05 7 views
2
typedef struct Value{ 
    int id; 
    char type; 
    char a; 
} Value; 

void fooV(Value v){ 
    v.id = 10; 
    v.type = 'L'; 
    v.a = 'R'; 
} 

int main(void){ 
    Value v; 
    Pointer p; 
    int id = 5; 
    char type = 't'; 
    char a = 'a'; 

    printf("id: %d, type: %c, a: %c \n",id,type,a); 

    v.a = a; 
    v.id = id; 
    v.type = type; 
    fooV(v); 
    printf("id: %d, type: %c, a: %c \n",id,type,a); 

} 

sur l'appel fooV, valeur de la variable locale est créée ... donc pas de données dans l'appelant sera mis à jour Mais si je veux retourner les valeurs de fooV? Que devrais-je ajouter à fooV? Mercivaleurs de retour d'une struct

+2

Juste une note: structs, comme tout le reste en C, sont transmis par valeur. La valeur d'une structure peut être énorme (en termes de 'sizeof struct') donc passer des pointeurs vers des structures est une bonne habitude à prendre en compte. – pmg

Répondre

10

Yo u besoin de passer v dans par référence, qui se fait à l'aide des pointeurs en C:

void fooV(Value* v) 
{ 
    (*v).id = 10; 
    (*v).type = 'L'; 
    (*v).a = 'R'; 
} 

Ou utilisez l'opérateur -> sténographie:

void fooV(Value* v) 
{ 
    v->id = 10; 
    v->type = 'L'; 
    v->a = 'R'; 
} 

Et ne pas oublier de passer l'adresse de v :

fooV(&v); 
+1

Comme alternative, vous pourriez retourner une structure 'Value' de' fooV() ':' Valeur fooV (Valeur v); 'mais c'est probablement moins efficace. –

+0

Je l'ai eu au travail !!!! mais pourriez-vous expliquer la différence entre (* v) .id = 10; et * (v) .id = 10; pour une raison quelconque, je pense qu'ils sont les mêmes ... – user133466

+1

@metashockwave: L'opérateur "." a une priorité supérieure à celle de l'opérateur "*", donc "* (v) .id" et "* v.id" seront tous deux interprétés comme "* (v.id)". Pour obtenir la signification voulue, c'est-à-dire suivre d'abord le pointeur en utilisant "*", et ALORS obtenir le champ "id" dans la structure, vous devez écrire "(* v) .id" ou "v-> id" . –

5

Si vous voulez juste avoir une fonction fooV qui renvoie un « construit » struct Value, vous pouvez réécrire fooV comme suit:

Value fooV() { 
    Value v; 
    v.id = 10; 
    v.type = 'L'; 
    v.a = 'R'; 
    return v; 
} 

et vous appelez cette fonction comme:

Value v = fooV(); 

Sinon, si vous avez besoin d'une fonction qui modifie une struct Value que vous avez déjà, vous avez deux options: vous devez soit changer le type de retour de fooV:

Value fooV(Value v){ 
    v.id = 10; 
    v.type = 'L'; 
    v.a = 'R'; 
    return v; 
} 

dans ce cas, vous l'appelez comme:

v = fooV(v); 

ou changer fooV d'accepter un pointeur vers une Value:

void fooV(Value* v){ 
    v->id = 10; 
    v->type = 'L'; 
    v->a = 'R'; 
} 

dans ce cas, vous l'appelez comme:

fooV(&v); 
+0

Votre premier exemple ne créerait-il pas Value v sur la pile? Cela pourrait avoir des effets secondaires vraiment désagréables ... –

+0

@Robert: Oui, 'v' existe sur la pile. Je ne vois pas pourquoi cela compte, cependant, puisque 'v' n'existe que jusqu'à la fin de la fonction et qu'il n'y a pas de pointeurs ou de références à' v' dans la fonction, il n'y a aucun moyen d'y accéder une fois la fonction revenue. –

+0

Droit, mon mauvais. J'ai écrit trop de Java dernièrement :) –

1

Et changer la deuxième printf d'utiliser les valeurs de v, pas la variable id, type, a.

printf("id: %d, type: %c, a: %c \n",v.id,v.type,v.a);