[C] Anfängerproblem mit Struct, Prototypen & Header

steffischwein

Grünschnabel
Hallo liebe C/C++-Gemeine,

ich bin neu in C und hab ein kleines Problem, das ich lösen muss. Leider schaffe ich es alleine nicht, da mir noch das Hintergrundwissen zu einigen grundlegenden Sprachkonstrukten in C und deren Anwendung fehlt - daher muss ich um eure Hilfe bitten. In meinem Buch und im Internet konnte ich leider keine passenden Programmierbeispiele finden, die mir auf die Sprünge geholfen haben.

Und zwar habe ich drei Klassen: eine Main-Klasse, die nur die Methodenaufrufen enthalten soll, eine Header-Klasse und eine Klasse, welche die Prototypenfunktionen aus dem Header "implementieren" muss.

Bisher steht alles in der Main-Klasse (siehe unten) und ich wollte euch fragen, wie ich das ganze Refactoren muss:
- die Struct-Definition aus der Main.c muss in den Header Test.h
- die drei Methoden read, average und print müssen in Test.c
Als Laie möchte man meinen, dass es reicht, diese Methoden und die Struct-Definition einfach zu verschieben, allerdings kommen da Fehler beim compilieren, mit denen ich leider nichts anfangen kann.

Code:
 Main.c
#include <stdio.h>
#include <stdlib.h>
#include <Test.h>

typedef struct Test  {
   int value1;
   int value2;
 } Test;

Test read() {
    int value1, value2;
    value1 = -1;
    value2 = -1;
    
    printf("Please enter something!\n");
    printf ("value1:\n");
    scanf ("%d",&value1);
    printf ("value2:\n");
    scanf ("%d",&value2);
    printf ("Values: %02d:%02d\n\n\n", value1, value2);
    
    Test newTest = { value1, value2 };
    return newTest;
}

Test average(Test t1, Test t2) {
    int test1 = t1.value1 / 2;
    int test2 = t2.value2 / 2;
    
    Test averageTestNew = { test1, test2 };
    return averageTestNew;
}

void print(Test t1, Test t2, Test t3) {
    printf ("Test 1: %02d %02d\n", t1.value1, t1.value2);
    printf ("Test 2: %02d %02d\n", t2.value1, t2.value2);
    printf ("Average: %02d %02d\n", t3.value1, t3.value2);
}

int main(int argc, char** argv)  {    
    Test t1 = read();
    Test t2 = read();
    Test t3 = average(t1, t2);
    print(t1, t2, t3);
}


Code:
 Test.c
#include <Test.h>

//hier müssen die drei Methoden read, average und print rein


Code:
 Test.h
#ifndef _TEST_H
#define	_TEST_H

#ifdef	__cplusplus
extern "C" {
#endif

Test read();
Test average(Test t1, Test t2);
void print(Test t1, Test t2, Test t3);
        
//in diesen Header muss die Definition des Structs rein 

#ifdef	__cplusplus
}
#endif
#endif	/* _TEST_H */

Vielleicht kann mir ja jemand helfen, das wäre sehr nett. Vielen Dank schonmal im Voraus.

Edit: Includes für stdio und stdlib in die Main und fehlende Semikolons bei den Prototypen eingebaut.
 
Zuletzt bearbeitet:
andas Ende von Funktions Prototypem setztmanein Semikolon.
undwie verschiebtsduesnichteinfachdasmüsstegehn wassinddenndeinefehler Meldungen?
Achund duhast keine einzige Klasse.
noch etwas meine leertaste ist kaputt -.-
 
Hallo,

Danke erstmal für deine Antwort, das mit den Semikolon bei den Prototypen stimmt natürlich und ist gefixt. Außerdem sind in der Main.c die Includes #include <stdio.h> und #include <stdlib.h> enthalten (die hab ich gerade noch in den Eingangspost reineditiert).


Zu den Fehlermeldungen:

Angenommen ich verschiebe nur die Methode read() in die Datei Test.c
Code:
Test.c:5: error: parse error before "read"
//Zeile 5 = Test read() 
Test.c: In function `read':
Test.c:21: error: `Test' undeclared (first use in this function)
Test.c:21: error: (Each undeclared identifier is reported only once
Test.c:21: error: for each function it appears in.)
Test.c:21: error: parse error before "newTest"
Test.c:22: error: `newTest undeclared (first use in this function)
//Zeile 21 = Test newTest = { value1, value2 };




Angenommen ich verschiebe nur den Struct in die Datei Heade.h:
Code:
Main.c:5: error: parse error before "read"
//Zeile 5 = Test read()

Main.c: In function `read':
Main.c:17: error: `Test' undeclared (first use in this function)
Main.c:17: error: (Each undeclared identifier is reported only once
Main.c:17: error: for each function it appears in.)
Main.c:17: error: parse error before "newTest"
Main.c:18: error: `newTest' undeclared (first use in this function)
//Zeile 17= Test newTest = { value1,value2 };

Main.c: At top level:
Main.c:21: error: parse error before "average"
Main.c:21: error: parse error before "t1"
//Zeile 21= Test average(Test t1, Test t2)

Main.c: In function `average':
Main.c:22: error: `t1' undeclared (first use in this function)
Main.c:22: error: `t2' undeclared (first use in this function)
Main.c:25: error: `Test' undeclared (first use in this function)
Main.c:25: error: parse error before "averageTestNew"
Main.c:25: error: `averageTestNew' undeclared (first use in this function)

Main.c: At top level:
Main.c:30: error: parse error before "t1"
//Zeile 30= void print(Test t1, Test t2, Test t3)

Main.c: In function `print':
Main.c:31: error: `t1' undeclared (first use in this function)
Main.c:32: error: `t2' undeclared (first use in this function)
Main.c:33: error: `t3' undeclared (first use in this function)

Main.c: In function `main':
Main.c:38: error: `Test' undeclared (first use in this function)
Main.c:38: error: parse error before "t1"
Main.c:41: error: `t1' undeclared (first use in this function)
Main.c:41: error: `t2' undeclared (first use in this function)
Main.c:41: error: `t3' undeclared (first use in this function)
//Zeile 38 =  Test t1 = read();

Als Compiler nehme ich cygwin her.

Was genau meinst du mit den Klassen? Ich schätze den Begriff gibt es in C nicht, da es ja keine OOP ist, oder? :)
 
Zuletzt bearbeitet:
Code:
Main.c
#include "Test.h"


int main(int argc, char** argv)  {    
    Test t1 = read();
    Test t2 = read();
    Test t3 = average(t1, t2);
    print(t1, t2, t3);

    return 0;
}

Code:
Test.h
#include <stdio.h>
#include <stdlib.h>


typedef struct Test  {
   int value1;
   int value2;
 } Test;

Test read();

Test average(Test t1, Test t2);

void print(Test t1, Test t2, Test t3);

Code:
Test.c
#include "Test.h"

Test read(){
    int value1, value2;
    value1 = -1;
    value2 = -1;
    
    printf("Please enter something!\n");
    printf ("value1:\n");
    scanf ("%d",&value1);
    printf ("value2:\n");
    scanf ("%d",&value2);
    printf ("Values: %02d:%02d\n\n\n", value1, value2);
    
    Test newTest = { value1, value2 };
    return newTest;
}

Test average(Test t1, Test t2) {
    int test1 = t1.value1 / 2;
    int test2 = t2.value2 / 2;
    
    Test averageTestNew = { test1, test2 };
    return averageTestNew;
}

void print(Test t1, Test t2, Test t3) {
    printf ("Test 1: %02d %02d\n", t1.value1, t1.value2);
    printf ("Test 2: %02d %02d\n", t2.value1, t2.value2);
    printf ("Average: %02d %02d\n", t3.value1, t3.value2);
    system("pause");
}

Dein Fehler lag einfachbei #include <Test.h>
was #include "Test.h"
heißen muss oder hast du die header im Compiler Ordner?
int main gibt einen Wert zurück
 
Danke für die Hilfe, das war es :)

#include "Time.h" anstelle von #include <Time.h>.

Mit dem Rückgabewert der main-Methode hast du natürlich auch recht, das war Schlamperei von mir. Komisch dass der Compiler da nicht meckert, wenn er sogar vor fehlenden Leerzeilen am Ende warnt ;)

Echt peinlich, da es so ein einfaches und triviales Problem war. Als ich das Kapitel über Header im Buch gelesen hab, habe ich die "" einfach überlesen, da der Unterschied in dem einen Programmierbeispiel nicht explizit erwähnt worden ist und alle anderen Header immer mit <> eingebunden worden sind.
 
Hi.
Mit dem Rückgabewert der main-Methode hast du natürlich auch recht, das war Schlamperei von mir. Komisch dass der Compiler da nicht meckert, wenn er sogar vor fehlenden Leerzeilen am Ende warnt ;)
Der Compiler meckert nicht, weil es in C++ und C99 völlig legitim ist die "return 0;" Anweisung in der Haupteinsprungsroutine wegzulassen. Diese Anweisung wird dann trotzdem implizit ausgeführt.

Gruß
 
@ deepthroat legitim?
eher nicht. Jeder microsoft und auchandere Compiler meckern bei keinem Rückgabewert.
 
So ich hab es nach gelesen.
Die "main"-Funktion ist die einzige Funktion mit Rückgabewert, in der man laut (C++) Standard ein return-statement weglassen darf.
Hattest doch recht. Bin ich aberauchnoch nie brüber gestolpert.
Und dann frag ich mich glatt wieso microsoft das anders macht -.- bei meinem Kompiler geht das nicht.
 
Zuletzt bearbeitet:
Und dann frag ich mich glatt wieso microsoft das anders macht -.- bei meinem Kompiler geht das nicht.
Naja, die Compiler von Microsoft hatten noch nie den Ruf besonders standardkonform zu sein. Gerade wenn du noch Visual C++ 6 verwendest... :eek:

Die neueren Microsoft Compiler sind da aber deutlich besser. Obwohl ich jetzt aus dem Hut nicht weiß ob Microsoft den "neuen" C Standard von 1999 schon unterstüzt... ;-]

Gruß
 
Zurück