Funktionen, Ausgabe mehrerer Werte



  • Dankeschön! 🙂

    Mit ner Struktur wäre es auch nicht schlecht. Sollte halt die beste Lösung für dieses Problem sein, da unsere Prüfungsaufgaben so aussehen und ich nur begrenzten Platz auf der Prüfung zum schreiben hab.

    Behandelt haben wir schon so ziemlich alles. Bin halt jetzt nur am Üben und ohne gescheites Skript und Buch (ist bestellt) ist halt alles grade was ich so auf Inet Seiten finde, gemischt mit meinem Wissen und viel Experimentierfreudigkeit 😉

    Habs versucht...aber...

    #include <stdlib.h>
    #include <stdio.h>
    
    /* ---Funktionen---*/
    
    void Eingabe(int *jahr, int *monat, int *tag);
    
    /* ---Hauptprogramm--- */
    
    int main(int argc, char *argv[])
    {
    	int j=0,m=0,t=0;
    
    /* Hier hängts bei mir, ich muss doch 3 verschiedene Variablen aus der Funktion rausbekommen, kann da doch nicht einfach Eingabe(j,m,t) machen... */
    
    	printf("Jahr: %d Monat: %d Tag: %d\n",j,m,t);
    }
    
    /* ---Eingabe--- */
    
    void Eingabe(int *jahr, int *monat, int *tag)
    {
    	printf("Jahr\n");
    	scanf("%d", *jahr);
    	printf("Monat\n");
    	scanf("%d", *monat);
    	printf("Tag\n");
    	scanf("%d", *tag);
    	return(0);
    }
    


  • Griever schrieb:

    Dankeschön! 🙂

    Mit ner Struktur wäre es auch nicht schlecht. Sollte halt die beste Lösung für dieses Problem sein, da unsere Prüfungsaufgaben so aussehen und ich nur begrenzten Platz auf der Prüfung zum schreiben hab.

    Dann würde ich vorschlagen, dass du die Variante mit der Struktur als nächstes machst wenn du das mit den Zeiger gerafft hast. Ist nämlich deutlich schöner.

    Griever schrieb:

    /* Hier hängts bei mir, ich muss doch 3 verschiedene Variablen aus der Funktion rausbekommen, kann da doch nicht einfach Eingabe(j,m,t) machen... */
    

    Eigentlich kannst du das analog aus meinem Beispiel oben übernehmen. Was du der Funktion übergeben musst sind Zeiger auf die zu verändernden Werte. Dafür brauchst halt den Adressoperator &.

    Griever schrieb:

    void Eingabe(int *jahr, int *monat, int *tag)
    {
    	printf("Jahr\n");
    	scanf("%d", *jahr);   // hier kein *, das übergebene Argument soll ja ein Zeiger sein. Und mit * wird der ja dereferenziert
    	printf("Monat\n");
    	scanf("%d", *monat);  // dito
    	printf("Tag\n");
    	scanf("%d", *tag);    // dito
    	return(0);
    }
    


  • Ich glaub ich habs jetz 🙂 Kommt mir nur so vor als obs viel zu lang ist, gehts einfacher (mit Zeigern) oder kann mans so lassen.

    #include <stdlib.h>
    #include <stdio.h>
    
    /* ---Funktionen---*/
    
    void Eingabe(int *jahr, int *monat, int *tag);
    
    /* ---Hauptprogramm--- */
    
    int main(int argc, char *argv[])
    {
    	int j=0,m=0,t=0;
    	Eingabe(&j,&m,&t);
    	printf("Jahr: %d Monat: %d Tag: %d\n",j,m,t);
    	system("PAUSE");
    	return(0);
    }
    
    /* ---Eingabe--- */
    
    void Eingabe(int *jahr, int *monat, int *tag)
    {
    	int jahrx,monatx,tagx;
    	printf("Jahr\n");
    	scanf("%d", &jahrx);
    	*jahr = jahrx;
    	printf("Monat\n");
    	scanf("%d", &monatx);
    	*monat = monatx;
    	printf("Tag\n");
    	scanf("%d", &tagx);
    	*tag = tagx;
    }
    


  • Ja, das geht noch kürzer, indem du die Hilfsvariablen weglässt:

    void Eingabe(int *jahr, int *monat, int *tag)
    {
        printf("Jahr\n");
        scanf("%d", jahr);
        printf("Monat\n");
        scanf("%d", monat);
        printf("Tag\n");
        scanf("%d", tag);
    }
    

    (scanf() erwartet Zeiger auf die Variablen, in die es schreiben soll - deswegen brauchst du normalerweise das &, um dir die Adresse deiner Variablen zu holen. Aber hier hast du schon die Zeiger übergeben bekommen und kannst sie direkt weiterreichen)



  • Cool danke 🙂 , ja ich glaub ich habs jetzt einigermaßen mit den Zeigern verstanden... Kommen wir zu Strukturen in Kombination mit Zeigern...

    #include <stdlib.h>
    #include <stdio.h>
    
    /* ---Funktionen & Deklarationen --- */
    
    struct datum {
    	int j;
    	int m;
    	int t;
    }test;
    
    void Eingabe(struct datum *);
    
    /* ---Hauptprogramm--- */
    
    int main(int argc, char *argv[])
    {
    	int j,m,t;
    	Eingabe(&test);
    	printf("Jahr: %d Monat: %d Tag: %d\n",j,m,t);
    	system("PAUSE");
    	return(0);
    }
    
    /* ---Eingabe--- */
    
    void Eingabe(struct datum * werte)
    {
    	printf("Jahr\n");
    	scanf("%d", &werte.j); // hier bekomme ich Fehlermeldungen
    	printf("Monat\n");
    	scanf("%d", &werte.m); // hier bekomme ich Fehlermeldungen
    	printf("Tag\n");
    	scanf("%d", &werte.t); // hier bekomme ich Fehlermeldungen
    }
    

    Wäre schön wenn mir jemand auch dabei helfen könnte. Ich denke sobald ich das auch verstanden hab, sollte ich alleine klar kommen 🙂



  • Wie lautet denn die Fehlermeldung, die du bekommst?
    (btw: du liest das Datum in die globale Variable 'test' ein und überprüfst anschließend den Inhalt einiger lokaler Variablen)

    PS: Übrigens kann man ein struct auch per return weiterreichen:

    struct Datum Eingabe()
    {
      struct Datum res;
      ...
      return res;
    }
    
    ...
    struct Datum test = Eingabe();
    


  • Griever schrieb:

    void Eingabe(struct datum * werte)
    {
    	printf("Jahr\n");
    	scanf("%d", &werte.j); // hier bekomme ich Fehlermeldungen
    	printf("Monat\n");
    	scanf("%d", &werte.m); // hier bekomme ich Fehlermeldungen
    	printf("Tag\n");
    	scanf("%d", &werte.t); // hier bekomme ich Fehlermeldungen
    }
    

    'werte' ist ein pointer auf eine struct. verwende dafür '->'
    beispiel:

    scanf("%d", &werte->j);  // sollte gehen
    


  • Stimmt "test" ist ja dann global...Und das ist ja böse 🙂 Dürfen wir in der Prüfung nicht machen, also Globale Variablen setzen.

    Fehlermeldungen vom Compiler:

    error C2228: Links von ".j" muss sich eine Klasse/Struktur/Union befinden.
    error C2228: Links von ".m" muss sich eine Klasse/Struktur/Union befinden.
    error C2228: Links von ".t" muss sich eine Klasse/Struktur/Union befinden.

    scanf("%d", &werte->j);
    

    So hatte ichs am Anfang sogar... hab da aber bestimmt das & vergessen 🙄 passiert mir bei Scanf immer wieder.



  • Jetzt hab ichs 😃 Danke! 🙂

    #include <stdlib.h>
    #include <stdio.h>
    
    /* ---Funktionen & Deklarationen --- */
    
    struct datum {
    	int j;
    	int m;
    	int t;
    };
    
    void Eingabe(struct datum *);
    
    /* ---Hauptprogramm--- */
    
    int main(int argc, char *argv[])
    {
    	int j,m,t;
    	struct datum test;
    	Eingabe(&test);
    	printf("Jahr: %d Monat: %d Tag: %d\n",test.j,test.m,test.t);
    	system("PAUSE");
    	return(0);
    }
    
    /* ---Eingabe--- */
    
    void Eingabe(struct datum * werte)
    {
    	printf("Jahr\n");
    	scanf("%d", &werte->j);
    	printf("Monat\n");
    	scanf("%d", &werte->m);
    	printf("Tag\n");
    	scanf("%d", &werte->t);
    }
    

    Und was ist jetz der Vorteil an Strukturen, gegenüber der Methode mit Zeigern?

    Was macht sie denn "schöner"? 😕 Oder hab ich jetzt schon wieder unnötiges Zeug mit in den Code geschrieben?



  • Wie der Name schon sagt kannst du mit Strukturen dein Programm strukturieren. Du kannst also theoretisch mehrere Variablen mit dem gleichen Bezeichner haben, aber halt in einer anderen Struktur. Wenn du das ganze jetzt nochmal erweiterst und die Uhrzeit mit hineinnimmst, könntest du z.B. m für Minute nehmen (in einer anderen Struktur, die z.B. Zeit heißt). Dadurch entsteht keine so große Verwirrung 😉



  • Außerdem kannst du Strukturen teilweise leichter weiterreichen (ein struct zählt als einzelner Wert und kann deshalb auch per return durchgereicht werden - siehe der Code-Schnipsel in meinem letzten Beitrag).

    PS: Und noch vielseitiger werden struct's, wenn du mit C++ arbeitest 😉



  • CStoll schrieb:

    PS: Und noch vielseitiger werden struct's, wenn du mit C++ arbeitest

    weil man kein 'typedef' braucht?



  • Nein, weil du einem C++-Struct außer Wertelementen auch Bearbeitungsmethoden mitgeben kannst.



  • CStoll schrieb:

    Nein, weil du einem C++-Struct außer Wertelementen auch Bearbeitungsmethoden mitgeben kannst.

    naja, in C macht man eben:

    void bearbeite_meine_struct (meine_struct *x)
    {
      x->... // egal jetzt
    }
    

    ich seh' da keinen grossen vorteil drin wie's c++ macht...



  • Dazu kommt noch Operator-Overloading, die Möglichkeit, eigene Copy-Konstruktoren und Zuweisungsoperatoren mit beliebiger Semantik zu erzeugen, ... (die ganze Palette von C++ halt)

    (bei skalaren Elementtypen hast du ja keine Probleme. Aber wenn du anfängst mit Zeigern zu hantieren, ist das Verwalten des Speichers in C++ wesentlich eleganter zu lösen)

    PS: Sorry, ich wollte jetzt keine Diskussion C vs. C++ anstoßen.



  • CStoll schrieb:

    ... (die ganze Palette von C++ halt)

    du meinst: 'ne menge meist sinnloser overhead 😃

    CStoll schrieb:

    PS: Sorry, ich wollte jetzt keine Diskussion C vs. C++ anstoßen.

    kein problem, es sind nunmal zwei unabhängige sprachen und man einfach nicht allgemein sagen, dass die eine oder andere 'besser' oder 'schlechter' sei...



  • net schrieb:

    CStoll schrieb:

    ... (die ganze Palette von C++ halt)

    du meinst: 'ne menge meist sinnloser overhead 😃

    Overhead? Möglicherweise.
    Sinnlos? Definitiv nicht (schließlich mußt du einer Klasse nur das auf den Weg geben, was sie deiner Meinung nach auch benötigt).



  • CStoll schrieb:

    Sinnlos? Definitiv nicht...

    doch, total sinnlos. was haben konstruktoren, operatorüberladung und der ganze schnickschnack in structs zu suchen? dafür gibts 'class'.



  • net schrieb:

    CStoll schrieb:

    Sinnlos? Definitiv nicht...

    doch, total sinnlos. was haben konstruktoren, operatorüberladung und der ganze schnickschnack in structs zu suchen? dafür gibts 'class'.

    Wenn du der Meinung bist, keinen Ctor etc. zu brauchen, mußt du auch keinen anlegen. (der Vorteil ist, daß du es machen darfst, wenn du es brauchst)



  • Ich bitte euch...


Anmelden zum Antworten