Funktion wird nicht ausgeführt; Pointer & Strukturen



  • Hey, hab jetzt genug Stunden verzweifelt und bemühe Euch 🙂 , wäre klasse, wenn mir da jemand helfen kann. Ja, ich bin Newbee!
    Mein Skript wird so wie es jetzt ist korrekt und komplett durchlaufen. Bis auf die Kleinigkeit, dass die Funktion print() nicht ausgeführt wird. Alle anderen Funktionen laufen eigentlich ganz gut nur die eben nicht. Kann gut sein, dass das am Pointer-Struct-Aufbau liegt, welchen ich übergeben (ist leider meine Aufgabe das so zu machen). Vielleicht hat ja jemand einen Tipp für mich. Falls ich zu wenig Code poste gebe ich gerne mehr 😉

    typedef struct vector {
    	double x;
    	double y;
    } vector;
    
    typedef struct vector_p_s {
    	vector position;
    	vector speed;
    	double betragv;
    	double time;
    } vector_p_s;
    
    /* Prototypes */
    int print(vector_p_s *status, unsigned long schritte);
    
    int main(int argc, char *argv[])
    {
    

    [...]

    vector_p_s *status =  malloc(sizeof(vector_p_s) * schritte); /* struct array initialisieren*/
    
    	status[0].position.x = 0;
    	status[0].position.y = 2;
    	status[0].speed.x = cos(a)*v0;
    	status[0].speed.y = sin(a)*v0;
    	//status[0].betragv = v0;
    
    	/*Werte berechnen*/
    	for(int i=0;i<(schritte-1);++i){
    		status[i+1].position.x = status[i].position.x + status[i].speed.x * DELTAt;
    		status[i+1].position.y = status[i].position.y + status[i].speed.y * DELTAt
    								- 0.5 * G * (DELTAt*DELTAt);
    		status[i+1].speed.x = status[i].speed.x;
    		status[i+1].speed.y = status[i].speed.y - G * DELTAt;
    		//status[i+1].betragv = sqrt((status[i+1].speed.x * status[i+1].speed.x) + 
    								  // (status[i+1].speed.y * status[i+1].speed.y));
    		status[i+1].time = status[i].time + (double)DELTAt;
    		}
    	int print(vector_p_s *status, unsigned long schritte);
    	prin(3);
    	return EXIT_SUCCESS;
    
    }
    /* Tabelle Ausgabe */
    int print(vector_p_s *status, unsigned long schritte){
    	printf(" Leapfrog:\n");
    	printf(" Wurfweite: %f\n", status[schritte].position.x);
    	printf(" t , x(t) , y(t) , v(t) ");
    
    	for(int i=0;i<schritte;i++){
    		printf(" %6.3f , %6.3f , %6.3f , %6.3f", status[i].time,status[i].position.x,status[i].position.y,status[i].betragv);
    	}
    	return EXIT_SUCCESS;
    }
    

    Makefile (größtenteils vom Prof übernommen)

    CC     = gcc
    
    # einige Parameter für den compiler
    CFLAGS = -g -std=c99 -O2 -Wall -Werror -Wstrict-prototypes \
             -Wmissing-prototypes -mtune=native
    
    # Libraries für meinen Code
    LIB    = -lm
    
    # abhaengige files (include, Makefile etc.)
    DEPS = Makefile
    
    # das soll alles erzeugt werden 
    EXE    = ../bin/leapfrog 
    
    # das ist der Einsprung für MAKE
    all: $(EXE)
    
    ../bin/leapfrog: leapfrog.o $(DEPS)
    	$(CC)  $(CFLAGS) $(LIB) leapfrog.o -o $@
    
    # das ist ein alternativer aber üueblicher Einsprung
    clean:
    	rm -f *.o $(EXE) *~
    

    Ich danke Euch schon mal im voraus



  • Zeile 20 ist eine Funktionsdeklaration, kein Funktionsaufruf.

    Was sagt denn der Compiler dazu? Irgendwelche Warnungen?



  • So sagt der kompilier nix.
    Hab ich auch gedacht, soll heißen dass ich das einfach ohne die typdefs machen soll?

    int print( *status, schritte);
    

    Dann meckert er nämlich:

    make
    gcc -g -std=c99 -O2 -Wall -Werror -Wstrict-prototypes -Wmissing-prototypes -mtune=native   -c -o leapfrog.o leapfrog.c
    leapfrog.c: In Funktion »main«:
    leapfrog.c:83:12: Fehler: expected declaration specifiers or »...« before »*« token
    leapfrog.c:83:21: Fehler: expected declaration specifiers or »...« before »schritte«
    make: *** [leapfrog.o] Fehler 1
    

    Zeile 83 entspricht Zeile 20 im 2. Codesegment



  • Gibst du bei printf den Rückgabetyp an, wenn du es aufrufst? Nein. Warum tust du es also bei print?



  • also void print() ? hat auch zu fehlern geführt (gleiche wie im vorherigen post)

    aber die declaration hab ich ja eigentlich mit dem prototyp oben erledigt, oder?



  • Nein, du sollst die richtigen Parameter übergeben.
    D.h. du musst schon wissen was du tust.

    Bsp. der Prototyp von printf sieht so aus:

    int printf ( const char * format, ... );
    

    Rückgabewert ist ein int und als erster Parameter wird ein Zeiger auf ein char (-Array) erwartet. Die ... sagen, es können noch beliebige Parameter folgen.

    Wie nutzt du es:

    printf(" Wurfweite: %f\n", status[schritte].position.x);
    

    Der Rückgabewert interessiert dich nicht und du übergibst ein Stringliteral (Das ist schon der Zeiger auf char)
    Da steht kein int vor dem Funktionsnamen, und da sind auch keine Typangaben in den Parametern. Da stehen Variablen oder Konstanten.

    Dein Prottyp von print:

    int print(vector_p_s *status, unsigned long schritte);
    

    sagt dir, das der erste Parameter ein Zeiger auf vector_p_s sein muss.
    *status ist es nicht, da der Zeiger status durch das * dereferenziert wird und somit schon ein Elemnt ist.

    status reicht aus:

    print(status, schritte);
    

    Wobei die Namensgleichheit der Variablen im Prototyp und beim Aufruf nicht nötig ist (das wäre ja auch extrem blöd).

    ⚠ Du musst schon wissen was du tust.
    Mit rumraten kommst du nicht weit.
    Das Wissen steht in Büchern.



  • Das mit dem Rumraten verstehe ich sehr gut und ich habe vorher auch auf zig Seiten Funktionsdefinitionen und übergaben mir durchgelesen und auch in 2 Büchern und den Unterlagen meines profs geschaut.

    Nun geht es, herzlichen Dank!



  • Und dir ist nicht aufgefallen, das beim Aufruf der Funktion kein Variablentyp dabei steht?

    Und der Rückgabewert einer Varaiblen zugewiesen wird ?
    😕 🙄

    Bei der Deklaration brauchen noch nicht einmal Variablennamen dabei stehen.
    Bei der Definition müssen sie dabei sein, denn du willst ja in der Funktion darauf zugreifen.

    // Deklaration:
    int print(vector_p_s *, unsigned long );
    
    // Definition
    int print(vector_p_s *status, unsigned long schritte)
    { .... }
    
    // Aufruf
    vector_p_s vect[100];
    unsigned long anz;;
    ...
    print(vect, anz);
    // oder
    print(vect, 5);  // hier wandelt der Copiler die 5 automatisch in ein unsigned long, wenn er den Prottypen (durch die Deklaration oder Definition) kennt
    


  • Am Anfang habe ich ja noch lange versucht "analytisch" die Fehler zu finden. Aber irgendwann kam dann der Punkt, an dem die Ideen ausgingen, wo der Fehler sein könnte und ich angefangen habe tatsächlich "rumzuraten" (allerdings auch erst spät).

    DirkB schrieb:

    Bei der Deklaration brauchen noch nicht einmal Variablennamen dabei stehen.

    Hatte ich gemacht, aber wieder rückgängig gemacht, da keine Veränderung.

    DirkB schrieb:

    Und dir ist nicht aufgefallen, das beim Aufruf der Funktion kein Variablentyp dabei steht?

    Hatte ich auch gemacht (siehe Post 2 von mir), aber da es danach schlimmer wurde mit den Fehlermeldungen, hab ich das wieder rückgängig gemacht...

    DirkB schrieb:

    Und der Rückgabewert einer Varaiblen zugewiesen wird ?
    😕 🙄

    wenn du das int print(...); im Aufruf meinst, ja, das war mir echt einfach nicht aufgefallen.

    Vielen Dank, super Zusammenfassung.



  • MDede schrieb:

    DirkB schrieb:

    Bei der Deklaration brauchen noch nicht einmal Variablennamen dabei stehen.

    Hatte ich gemacht, aber wieder rückgängig gemacht, da keine Veränderung.

    Lass sie drin. Gut gewählt Variablennamen erleichtern das Verständnis / die Doku.


Anmelden zum Antworten