Struktur an Funktion übergeben

Lesezeit: 6 Minuten

Benutzeravatar von Daniel Del Core
Daniel DelCore

Ich bin ein neuer C-Programmierer und wollte wissen, wie ich einen bestehen kann struct bis hin zu einer Funktion. Ich erhalte eine Fehlermeldung und kann die korrekte Syntax dafür nicht herausfinden. Hier ist der Code dafür….

Struktur:

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

struct student person;

Anruf:

addStudent(person);

Prototyp:

void addStudent(struct student);

und die eigentliche Funktion:

void addStudent(person)
{
    return;
}

Compilerfehler:

Zeile 21: Warnung: fragwürdige Tag-Deklaration: struct student
Zeile 223: Argument #1 ist mit Prototyp nicht kompatibel:

  • Wo deklarierst du deine Struktur? Wo befindet sich in Ihrer eigentlichen Implementierungsdatei Ihre struct student { /* ... */ }; Code? Es sieht so aus, als ob es sich im falschen Bereich befindet (wie in Ihrer main Funktion oder was auch immer Sie aufrufen möchten addStudent aus…

    – Jason Coco

    29. April 2012 um 6:04 Uhr

  • ja, es ist in meinem Funktionsumfang

    – Daniel DelCore

    29. April 2012 um 6:06 Uhr

Benutzeravatar von Donnell
Donell

So übergeben Sie die struct per Referenz. Das bedeutet, dass Ihre Funktion auf die zugreifen kann struct außerhalb der Funktion und ändern Sie ihre Werte. Dazu übergeben Sie der Funktion einen Zeiger auf die Struktur.

#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;
}

So passieren Sie die struct nach Wert, sodass Ihre Funktion eine Kopie der erhält struct und kann nicht auf die äußere Struktur zugreifen, um sie zu modifizieren. Mit außen meine ich außerhalb der Funktion.

#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;
}

  • prägnant. Ziemlich ordentlich.

    – Raynal Göbel

    7. Dezember 2015 um 5:43 Uhr

  • Absolut perfekt !

    – StrohHara

    24. März 2016 um 19:27 Uhr

  • Ein bisschen spät zu fragen, aber warum die Struktur auf den gleichen Namen (aber mit einem Großbuchstaben) schreiben? Ich frage mich auch, warum Sie einen Zeiger auf die Struktur erstellen müssen (*cptr), verwenden Sie diese dann, um an die Funktion zu übergeben, wenn Sie die ursprüngliche Kartenstruktur als Referenz übergeben könnten &c. Ich bin neu in Strukturen in C, also suche ich wirklich nach Feedback.

    – Matt K

    4. August 2021 um 16:59 Uhr

  • Ordentlicher Code, ausgezeichnete Erklärung.

    – Arjuna Deva

    17. November 2021 um 14:34 Uhr

  • @MattK Typdefing auf denselben Namen würde es uns ermöglichen, später Instanzstrukturen ohne die zu definieren struct Stichwort. ZB dieses Beispiel ohne die Typedef: struct card card1 = {...};. Mit typedef: card card1 = {...};. Der Großbuchstabe und die Zeigererstellung sind beide nur Vorlieben (Konvention/Lesbarkeit) AFAIK.

    – Wadite RK

    23. Februar um 20:31 Uhr

Benutzeravatar von MByD
MByD

Die Linienfunktionsimplementierung sollte sein:

void addStudent(struct student person) {

}

person kein Typ, sondern eine Variable ist, können Sie ihn nicht als Typ eines Funktionsparameters verwenden.

Stellen Sie außerdem sicher, dass Ihre Struktur vor dem Prototyp der Funktion definiert ist addStudent wie der Prototyp es verwendet.

  • Eine gute Idee ist es, den Strukturtyp zu “benennen”, um dieses Problem zu vermeiden, indem man typedef verwendet. Sehen en.wikipedia.org/wiki/Struct_(C_programming_language)

    – Jouni Aro

    29. April 2012 um 5:58 Uhr


  • Bedeutet das, dass ich die gesamte Struktur aus meiner Funktion nehmen und in meine Header-Datei einfügen muss, wo sich die Prototypen befinden?

    – Daniel DelCore

    29. April 2012 um 6:04 Uhr


  • @DanielDC – Ich hatte Angst, das zu fragen. Ja, die Struktur sollte in einem globalen Gültigkeitsbereich deklariert werden, da sie auch von anderen Funktionen verwendet wird.

    – MByD

    29. April 2012 um 6:06 Uhr

  • ohk, ich dachte, du könntest es genauso verwenden wie ints und chars. ;( wie peinlich… danke für deine hilfe

    – Daniel DelCore

    29. April 2012 um 6:09 Uhr

  • Gern geschehen, nimm es nicht zu schwer, es ist nicht trivial, wenn du mit der Sprache anfängst.

    – MByD

    29. April 2012 um 6:10 Uhr

Benutzeravatar von tom1990
tom1990

Wenn Sie eine Struktur an eine andere Funktion übergeben, ist es normalerweise besser, wie von Donnell oben vorgeschlagen zu handeln und sie stattdessen als Referenz zu übergeben.

Ein sehr guter Grund dafür ist, dass es die Dinge einfacher macht, wenn Sie Änderungen vornehmen möchten, die widergespiegelt werden, wenn Sie zu der Funktion zurückkehren, die die Instanz davon erstellt hat.

Hier ist ein Beispiel für die einfachste Möglichkeit, dies zu tun:

#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;
}

In diesem Beispiel ist das Argument für die addStudent() Funktion ist ein Zeiger auf eine Instanz von a student Struktur – student *s. Im main()erstellen wir eine Instanz der student struct und übergeben Sie dann einen Verweis darauf an unsere addStudent() Funktion mit dem Referenzoperator (&).

In dem addStudent() Funktion können wir den Pfeiloperator (->), um den Zeiger zu dereferenzieren und auf eines seiner Mitglieder zuzugreifen (funktional äquivalent zu: (*s).age).

Alle Änderungen, die wir in der vornehmen addStudent() Funktion wird widergespiegelt, wenn wir zu zurückkehren main()weil der Zeiger uns einen Verweis darauf gab, wo sich im Speicher die Instanz von befindet student struct wird gespeichert. Veranschaulicht wird dies durch die printf()was in diesem Beispiel “10” ausgibt.

Hätten Sie keine Referenz übergeben, würden Sie tatsächlich mit einer Kopie der Struktur arbeiten, die Sie an die Funktion übergeben haben, was bedeutet, dass Änderungen nicht wiedergegeben würden, wenn Sie zu ihr zurückkehren main – es sei denn, Sie haben eine Möglichkeit implementiert, die neue Version der Struktur zurück an main oder etwas in dieser Richtung zu übergeben!

Obwohl Zeiger auf den ersten Blick abschreckend erscheinen mögen, werden sie Ihnen, sobald Sie verstehen, wie sie funktionieren und warum sie so praktisch sind, zur zweiten Natur, und Sie fragen sich, wie Sie jemals ohne sie zurechtgekommen sind!

Sie müssen einen Personentyp angeben:

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

Außerdem können Sie Ihre Struktur typdefinieren, um zu vermeiden, dass Sie sie jedes Mal eingeben müssen, wenn Sie sie verwenden:

typedef struct student{
...
} student_t;

void addStudent(student_t person) {
...
}

Anstatt von:

void addStudent(person)
{
    return;
}

Versuche dies:

void addStudent(student person)
{
    return;
}

Da Sie bereits eine Struktur mit dem Namen “Student” deklariert haben, müssen Sie dies nicht unbedingt in der Funktionsimplementierung angeben, wie in:

void addStudent(struct student person)
{
    return;
}

  • Ich glaube nicht. Ohne typedef geht es auf Fehler.

    – Abdillah

    21. Juli 2014 um 0:47 Uhr

  • Ich glaube nicht. Ohne typedef geht es auf Fehler.

    – Abdillah

    21. Juli 2014 um 0:47 Uhr

1412760cookie-checkStruktur an Funktion übergeben

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy