2012-04-29 36 views
36

Jestem nowym programistą C i chciałem wiedzieć, jak mogę przekazać struct do funkcji. Otrzymuję błąd i nie mogę znaleźć poprawnej składni, aby to zrobić. Oto kod dla niego ....Przekazywanie struktury do funkcji

struct:

struct student{ 
     char firstname[30]; 
     char surname[30]; 
    }; 

    struct student person; 

wezwanie:

addStudent(person); 

prototype:

void addStudent(struct student); 

i rzeczywista funkcja:

void addStudent(person) 
{ 
    return; 
} 

błędy kompilatora: realizacja funkcji

line 21: warning: dubious tag declaration: struct student 
line 223: argument #1 is incompatible with prototype: 
+1

Gdzie deklarujesz swoją strukturę? W twoim aktualnym pliku implementacyjnym, gdzie jest twój kod 'struct student {/ * ... * /};? Wygląda na to, że jest w niewłaściwym zakresie (jak zadeklarowano w twojej funkcji "głównej" lub jakiejkolwiek funkcji, którą próbujesz nazwać 'addStudent' od ... –

+0

tak w moim zakresie funkcji –

Odpowiedz

34

Linia powinna być:

void addStudent(struct student person) { 

} 

person nie jest typem, ale zmienna, nie można go używać jako typ funkcji parametr.

Upewnij się również, że struktura jest zdefiniowana przed prototypem funkcji addStudent, ponieważ prototyp jej używa.

+5

Dobrym pomysłem jest" nazwać " typ struktury, aby ominąć ten problem, używając typedef. Patrz http://en.wikipedia.org/wiki/Struct_(C_programming_language) –

+0

@Binyamin sharet, nadal otrzymuję ten sam błąd –

+0

@DanielDC - patrz edytuj – MByD

3

musisz określić typ na osobę:

void addStudent(struct student person) { 
... 
} 

Ponadto, można typedef struct, aby uniknąć konieczności struct wpisać za każdym razem, kiedy go używać:

typedef struct student{ 
... 
} student_t; 

void addStudent(student_t person) { 
... 
} 
75

ten sposób do przekazać struct przez odniesienie. Oznacza to, że twoja funkcja może uzyskać dostęp do funkcji struct poza funkcją i zmodyfikować jej wartości. Robisz to, przekazując wskaźnik do struktury funkcji.

#include <stdio.h> 
/* card structure definition */ 
struct card 
{ 
    int face; // define pointer face 
}; // end structure card 

typedef struct card Card ; 

/* prototype */ 
void passByReference(Card *c) ; 

int main(void) 
{ 
    Card c ; 
    c.face = 1 ; 
    Card *cptr = &c ; // pointer to Card c 

    printf("The value of c before function passing = %d\n", c.face); 
    printf("The value of cptr before function = %d\n",cptr->face); 

    passByReference(cptr); 

    printf("The value of c after function passing = %d\n", c.face); 

    return 0 ; // successfully ran program 
} 

void passByReference(Card *c) 
{ 
    c->face = 4; 
} 

ten sposób można przekazać struct przez wartość, tak aby funkcja otrzymuje kopię struct i nie ma dostępu do struktury zewnętrzne, aby go zmodyfikować. Z zewnątrz mam na myśli poza funkcją.

#include <stdio.h> 


/* global card structure definition */ 
struct card 
{ 
    int face ; // define pointer face 
};// end structure card 

typedef struct card Card ; 

/* function prototypes */ 
void passByValue(Card c); 

int main(void) 
{ 
    Card c ; 
    c.face = 1; 

    printf("c.face before passByValue() = %d\n", c.face); 

    passByValue(c); 

    printf("c.face after passByValue() = %d\n",c.face); 
    printf("As you can see the value of c did not change\n"); 
    printf("\nand the Card c inside the function has been destroyed" 
     "\n(no longer in memory)"); 
} 


void passByValue(Card c) 
{ 
    c.face = 5; 
} 
+0

zwięzła, całkiem schludna –

+0

Absolutnie perfekcyjnie! – StrawHara

6

Podczas przekazywania struct do innej funkcji, zwykle lepiej jest zrobić tak, jak sugerował Donnell powyżej i przekazać ją przez odniesienie.

Bardzo dobrym tego powodem jest to, że ułatwia to, jeśli chcesz wprowadzić zmiany, które zostaną odzwierciedlone po powrocie do funkcji, która stworzyła jego wystąpienie.

Oto przykład najprostszy sposób to zrobić:

#include <stdio.h> 

typedef struct student { 
    int age; 
} student; 

void addStudent(student *s) { 
    /* Here we can use the arrow operator (->) to dereference 
     the pointer and access any of it's members: */ 
    s->age = 10; 
} 

int main(void) { 

    student aStudent = {0};  /* create an instance of the student struct */ 
    addStudent(&aStudent);  /* pass a pointer to the instance */ 

    printf("%d", aStudent.age); 

    return 0; 
} 

W tym przykładzie argument dla funkcji addStudent() jest wskaźnikiem do instancji student struct - student *s.W main() tworzymy instancję struktury student, a następnie przekazujemy odwołanie do niej naszej funkcji addStudent() przy użyciu operatora referencyjnego (&).

W funkcji addStudent() możemy użyć operatora strzałki (->), aby usunąć zaznaczenie wskaźnika i uzyskać dostęp do jego elementów (funkcjonalnie równoważne: (*s).age).

Wszelkie zmiany, które podejmujemy w funkcji addStudent() zostaną uwzględnione, gdy wrócimy do main(), ponieważ wskaźnik dał nam odniesienie do miejsca, gdzie w pamięci wystąpienie student struct jest przechowywany. Jest to zilustrowane przez printf(), który wyświetli "10" w tym przykładzie.

Jeśli nie przekazałeś referencji, faktycznie pracowałbyś z kopią struktury przekazanej do funkcji, co oznacza, że ​​wszelkie zmiany nie zostaną odzwierciedlone po powrocie do main - chyba że zaimplementowałeś sposób przekazywania nowa wersja struktury do głównej lub coś podobnego!

Chociaż wskaźniki na pierwszy rzut oka mogą wydawać się odstręczające, gdy tylko zorientujesz się, jak działają i dlaczego są tak poręczne, stają się drugą naturą i zastanawiasz się, jak poradziłeś sobie bez nich!

0

Zamiast:

void addStudent(person) 
{ 
    return; 
} 

spróbuj tego:

void addStudent(student person) 
{ 
    return; 
} 

Skoro już ogłoszony strukturę zwaną „student” nie koniecznie trzeba określić tak w realizacji funkcji jak w :

void addStudent(struct student person) 
{ 
    return; 
} 
+0

Nie sądzę, bez typedef, to idzie na błąd. – Abdillah

Powiązane problemy