Fragen zum Einbinden weitere Quelldateien
-
Hallo zusammen,
ich könnte etwas Hilfe gebrauchen. Ich kratze hier im Studium ganz oberflächlich das Programmieren mit C++ an und hab entsprechend wenig Durchblick - trotzdem soll ich in der Lage sein gestellte Übungen zu lösenUnd daher kommt auch mein Problem:
Ich soll ein Programm schreiben, dass die Arbeitszeitanhebung für den Renteneintritt in Abhängigkeit vom Geburtsjahr berechnet. Teilweise wurde uns der Quellcode gestellt, das ist was ich soweit habe:
Renteneintrittsalter.cpp
--------------------------------------------------------------------------------// Renteneintritt #include "stdafx.h" #include "Arbeitszeitanhebung.cpp" using namespace std; int Arbeitszeitanhebung(int Geburtsjahr); //------------------------------------------------------------------------------ int main1() { int Geburtsjahr, Monate; cout << "Berechnung der Arbeitszeitanhebung fuer die Jahrgaenge 1946 bis 1970.\n"; cout << "Geben Sie ein Geburtsjahr ein: "; cin >> Geburtsjahr; if ((1946<=Geburtsjahr)&&(Geburtsjahr<=1970)) { Monate = Arbeitszeitanhebung(Geburtsjahr); cout << "Die Arbeitszeit wird um " << Monate << " Monate verlaengert.\n\n"; } else cout << "Das Jahr liegt nicht im Bereich von 1946 bis 1970.\n\n"; return 0; }
--------------------------------------------------------------------------------
Die berechnung der zusätzlichen Arbeitszeit soll in einer weiteren Quelldatei erfolgen, darum:
Arbeitszeitanhebung.cpp
--------------------------------------------------------------------------------// Arbeitszeitanhebung #include "stdafx.h" using namespace std; int main2() { int Arbeitszeitanhebung = 42; return 0; }
--------------------------------------------------------------------------------
Mein erste Versuch war das ganze ersteinmal so zum Laufen zu bringen, dass mir die Funktion egal für welches Geburtsjahr stehts 42 ausgibt.
Dabei bekomme ich folgende Fehlermeldungen:
1>Renteneintrittsalter.obj : error LNK2005: "int __cdecl main2(void)" (?main2@@YAHXZ) ist bereits in Arbeitszeitanhebung.obj definiert. 1>Renteneintrittsalter.obj : error LNK2019: Verweis auf nicht aufgelöstes externes Symbol ""int __cdecl Arbeitszeitanhebung(int)" (?Arbeitszeitanhebung@@YAHH@Z)" in Funktion ""int __cdecl main1(void)" (?main1@@YAHXZ)". 1>MSVCRTD.lib(crtexe.obj) : error LNK2019: Verweis auf nicht aufgelöstes externes Symbol "_main" in Funktion "___tmainCRTStartup".
Ab hier steige ich leider nicht mehr durch...
Wo liegt das Problem an der Funktion main? Wie kann die schon wo anders definiert sein? Habe hier doch einmal int main1() und int main2()?
Und wäre meine Programmierung von der Funktion Arbeitszeitanhebung richtig in diesem Fall?
Ich hoff es ist verständlich wo meine Probleme liegen. Würde mich sehr freuen wenn sich jemand die Zeit nimmt mir zu sagen was ich hier falsch mache
Danke schonmal!
Gruß
/edit pumuckl: cpp-Tags. Nächstesmal bitte selbst machen!
-
Sowas hier
#include "Arbeitszeitanhebung.cpp"
geht leider gar nicht. Damit sorgst du dafür, dass die Implementation aller Funktionen in dieser Datei 2 mal vorhanden ist. Einmal in Arbeitszeitanhebung.cpp und einmal in Renteneintrittsalter.cpp. Das wird dann alles zweimal kompiliert, und der Linker stellt später fest, dass für ein und dieselbe Funktion 2 Versionen existieren. Das mag er nicht.
Normalerweise inkludiert man nur Header-Dateien.
Außerdem fehlt deinem Programm eine Funktion "main". Die ist der Standard-Einsprungspunkt aller C++-Programme. Ohne eine main-Funktion kann vom Linker keine exe-Datei erstellt werden. Dabei interessiert es nicht, ob da main1 oder main2 existieren. Das sind ganz andere Funktionsnamen, es gibt keine main und daher keine exe. Punkt.
-
Schau mal ob du Infos zu:
Projekterstellung auf Console unter VS C++ findest.Abgesehen von Microsoft Sonderwegen sollte in einem C++ Projekt genau einmal
int main()
vorkommen.
int main1()
oder
int main2()
können
int main()
nicht ersetzen.
MfG f.-th.
-
-
Ok, ich verstehe. Schonmal vielen Dank für die Antworten.
Bedeutet das, dass wenn ich in meinem Projekt mehrere Quelldateien hab (ich meine damit nicht die header-Dateien) diese automatisch mit verarbeitet werden wenn ich das dabugging starte oder muss ich das in einem "Hauptprogramm" festlegen, dass noch zusätzlich auf verschiedene Dateien zugegriffen werden muss?
Und könnte mir jemand sagen was für eine Bezeichnung diese Art der Funktion hat:
int Arbeitszeitanhebung(int Geburtsjahr);
Ich weiß nichtmal unter was ich nachschlagen muss wie die Aufgebaut ist bzw wie man damit weiter umgeht.
Danke euch
-
Verbessere mal deine Ausdrucksweise. Was heißt "verarbeiten"? Weißt du, wozu Headerdateien gut sind?
Und was meinst du mit Bezeichnung?
-
Sorry, meine Kenntnisse vom Programmieren und der korrekten Bezeichnung von allem hält sich sehr in Grenzen. Ich versuch mein Bestes.. das ist nicht mein Gebiet
Soweit ich das weiß ist eine Headerdatei unter anderem dazu da, bestimmte für das Programm allgemein gültige Deklarationen und Verweise auf verschiedene Bibliotheken (Z.B. #include <iostream>) zu enthalten. Oder?!
Verarbeiten = Kompilieren, so hab ich das gemeint. Die Frage hat sich ganz grundlegend auf den Compiler bezogen. Laut Aufgabenstellung:
Neue Quelldatei hinzufügen und in dieser die Funktion "Arbeitszeitanhebung" schreiben
Woher weiß "Renteneintrittsalter.cpp", dass in "Arbeitszeitanhebung.cpp" die benötigte Funktion steht. Muss ich das nicht auch noch irgendwie festlegen ("verlinken??")!?
Und wie könnte eine "Funktion" dieser Form
int Arbeitszeitanhebung(int Geburtsjahr);
aussehen? Bzw. wie nennt man so ein Konstrukt? Unter was kann ich da nachschlagen? Ich steh hier völlig ratlos da..
-
Verlinken trifft es am besten - wie du das machst, hängt von deiner Entwicklungsumgebung ab (bei modernen IDEs reicht es, die Dateien in einem Projekt zusammenzufassen).
-
Das nennt man Deklaration und das kommt in den Header (siehe mein Link), damit in dem Source-File bekannt ist, dass es diese Funktion gibt. Sie raussuchen und mit dem Aufruf verknüpfen tut dann der Linker.
-
Im Klartext heißt das Folgendes:
Du hast Funktionen in einer zweiten cpp-Datei. Diese musst du nur dem Projekt hinzufügen, damit sie beim Erstellen des Projekts mitkompiliert wird.
Damit du aber in deiner ersten cpp-Datei die Funktionen der zweiten nutzen kannst, musst du diese bekannt machen. Das macht man mit Funktionsprototypen (das ist das Wort, das du gesucht hast; auch Deklarationen/Bekanntmachungen). Üblicherweise kommen die Definitionen einer Funktion (also die ganze Funktion mit Rumpf) in die cpp-Datei, die Deklarationen/Prototypen in eine h-Datei, also einen Header.
Den Header, der zu deiner zweiten cpp-Datei (Übersetzungseinheit, ÜE) gehört, kannst du nun in der ersten einbinden. Dazu nutzt man das include-Statement. Somit hast du nun alle dort enthaltenen Funktionen bekanntgemacht und das Kompilieren gelingt (sofern keine Syntaxfehler enthalten sind, natürlich). Erst beim Linken kommt es wirklich darauf an, dass die Funktionen auch tatsächlich definiert sind, deren Inhalt also irgendwo in einer Übersetzungseinheit enthalten war und zu einer Objektdatei gemacht wurde (diese werden dann vom Linker zu einer exe/com/dll/ocx/sonstwas-Datei zusammengepanscht).
Bei dieser ganzen Sache darf nichts doppelt vorkommen, weder Deklaration noch Definition. Doppelte Deklarationen verhindert man z.B. durch include guards (=>Google). Doppelte Definitionen verhindert man z.B., indem man keine cpp-Dateien inkludiert.
Mini-Beispiel:
//functions.h //----------- #ifndef MYFUNC_H //include guard #define MYFUNC_H // int MyFunc(int i); //Prototyp/Deklaration #endif //functions.cpp //------------- int myFunc(int i) { //Definition return ((i*i)/5+(49*7))/i; //unglaublich komplexe Berechnungen ;) } //main.cpp //-------- #include "functions.h" //Einbinden des Headers (Funktion ist nun bekannt) int main() { myFunc(123); //Aufruf }
-
_matze schrieb:
Bei dieser ganzen Sache darf nichts doppelt vorkommen, weder Deklaration noch Definition. Doppelte Deklarationen verhindert man z.B. durch include guards (=>Google). Doppelte Definitionen verhindert man z.B., indem man keine cpp-Dateien inkludiert.
Doppelte Deklarationen sind im Allgemeinen kein Problem, die Include Guards verhindern vor allem doppelte Definitionen von Typen (die brauchst du pro Übersetzungseinheit, un etwas damit machen zu können) und Inline-Funktionen.