Header und Quelldateien und externe Variablen

Schnelle objektorientierte, kompilierende Programmiersprache.
forumnewbie
Beiträge: 80
Registriert: Di Jan 15, 2013 9:02 pm

Header und Quelldateien und externe Variablen

Beitrag von forumnewbie » Fr Mär 22, 2013 9:28 pm

Hallo!

ich habe versucht mein Projekt bzw. Beispiel in mehrere Dateien aufzuteilen, was auch geklappt hat.

Quelldatei: aufteilen.cpp

Code: Alles auswählen

#include <iostream>
#include "viereck.hpp"

using namespace std;


int main()
{
	//cout << berechneFlaeche(A, B);
	cout << berechneFlaeche(10, 20) << endl;		
	return 0;
}
Quelldatei: viereck.cpp

Code: Alles auswählen

//extern int A, B;

#include "viereck.hpp"

int berechneFlaeche(int a, int b)
{
	//A = 10;
	//B = 20;
	return a*b;
}
Headerdatei: viereck.hpp

Code: Alles auswählen

int berechneFlaeche(int a, int b);
Dazu habe ich einige Fragen:
1. Was sind genau Objektdateien bzw. warum werden sie erzeugt?
2. Warum muss in der Quelldatei viereck.cpp nochmal die Headerdatei viereck.hpp mit den Funktionsprototypen eingebunden werden? Sie wurde ja bereits in der Quelldatei aufteilen.cpp eingebunden.
3. Wie kann man eine externe globale Variable richtig erzeugen, damit ich auf diese in anderen Quelldateien zugreifen kann? Ich habe es versucht, aber es hat nicht funktioniert. Diese Stellen habe ich im Quellcode auskommentiert. (Ich weiß, dass man mit globalen Variablen nicht arbeiten sollte. Ich möchte nur sehen wie es funktioniert).

Danke!

Benutzeravatar
Xin
nur zu Besuch hier
Beiträge: 8862
Registriert: Fr Jul 04, 2008 11:10 pm
Wohnort: /home/xin
Kontaktdaten:

Re: Header und Quelldateien und externe Variablen

Beitrag von Xin » Fr Mär 22, 2013 10:02 pm

forumnewbie hat geschrieben:Dazu habe ich einige Fragen:
1. Was sind genau Objektdateien bzw. warum werden sie erzeugt?
Objektdateien enthalten die maschinenlesbare Übersetzung der .cpp Datei.
forumnewbie hat geschrieben: 2. Warum muss in der Quelldatei viereck.cpp nochmal die Headerdatei viereck.hpp mit den Funktionsprototypen eingebunden werden? Sie wurde ja bereits in der Quelldatei aufteilen.cpp eingebunden.
Jede .cpp-Datei wird alleine für sich übersetzt. Der Compiler weiß bei viereck.cpp also nichts davon, was bei aufteilen.cpp passiert.
forumnewbie hat geschrieben: 3. Wie kann man eine externe globale Variable richtig erzeugen, damit ich auf diese in anderen Quelldateien zugreifen kann? Ich habe es versucht, aber es hat nicht funktioniert. Diese Stellen habe ich im Quellcode auskommentiert. (Ich weiß, dass man mit globalen Variablen nicht arbeiten sollte. Ich möchte nur sehen wie es funktioniert).
Du hast die Variablen nur deklariert, aber nirgendwo definiert.

Du kannst den Quelltext also kompilieren, aber der Linker findet die beiden Variablen nicht, wenn er aus den einzelnen Objektfiles ein Programm zusammenstellt. Du musst sie also irgendwo auch definieren:

Code: Alles auswählen

int A, B
Merke: Wer Ordnung hellt ist nicht zwangsläufig eine Leuchte.

Ich beantworte keine generellen Programmierfragen per PN oder Mail. Dafür ist das Forum da.

forumnewbie
Beiträge: 80
Registriert: Di Jan 15, 2013 9:02 pm

Re: Header und Quelldateien und externe Variablen

Beitrag von forumnewbie » Sa Mär 23, 2013 12:30 am

Danke.
Antwort auf meine Frage 3 verstehe ich noch nicht ganz.

Wo liegt der genaue Unterschied zwischen Deklaration und Definition bei Variablen? Ich verstehe unter Deklaration -> Namen geben, und unter Definition -> Speicherplatz zuteilen. Und Speicherplatz wird bei Variablen automatisch zugeteilt, wenn ich es richtig verstanden habe. Ich dachte deshalb, dass ich mit der Zeile

Code: Alles auswählen

extern int A, B;
die Variablen deklariere und definiere.

Benutzeravatar
Xin
nur zu Besuch hier
Beiträge: 8862
Registriert: Fr Jul 04, 2008 11:10 pm
Wohnort: /home/xin
Kontaktdaten:

Re: Header und Quelldateien und externe Variablen

Beitrag von Xin » Sa Mär 23, 2013 9:29 am

forumnewbie hat geschrieben:Danke.
Antwort auf meine Frage 3 verstehe ich noch nicht ganz.

Wo liegt der genaue Unterschied zwischen Deklaration und Definition bei Variablen? Ich verstehe unter Deklaration -> Namen geben, und unter Definition -> Speicherplatz zuteilen. Und Speicherplatz wird bei Variablen automatisch zugeteilt, wenn ich es richtig verstanden habe. Ich dachte deshalb, dass ich mit der Zeile

Code: Alles auswählen

extern int A, B;
die Variablen deklariere und definiere.
Nein, wenn Du extern davor schreibst, deklarierst Du die Variablen nur. Es wird also kein Speicherplatz dafür reserviert, weil die Definition (der Speicherplatz) ja bereits irgendwo extern vorliegt.

Da Du aber keine Definition in keiner der .cpp-Dateien hast, wird Dir der Linker etwas von 'unknown reference' für die beiden Variablen erzählen.
Merke: Wer Ordnung hellt ist nicht zwangsläufig eine Leuchte.

Ich beantworte keine generellen Programmierfragen per PN oder Mail. Dafür ist das Forum da.

forumnewbie
Beiträge: 80
Registriert: Di Jan 15, 2013 9:02 pm

Re: Header und Quelldateien und externe Variablen

Beitrag von forumnewbie » So Mär 24, 2013 4:05 pm

Hi,

klappt leider noch nicht ganz.

Wo genau (als globale oder in den Funktionen) und wie muss ich diese externe Variable definieren? Wenn ich diese in der Datei viereck.cpp definiere, dann kennt die Datei aufteilen.cpp sie nicht. Wenn ich das in beiden tue, dann kommt es zu einem Fehler, da sie mehrmals definiert wurde.
Ich habe in dem Beispiel unten die Variable nur in der Datei aufteilen.cpp definiert, so dass der Compiler keine Fehler meldet. Ich erhalte jedoch als Ergebnis eine 0 - statt 200.

viereck.cpp:

Code: Alles auswählen

extern int A, B;

#include "viereck.hpp"

int berechneFlaeche(int a, int b)
{
	A = 10;
	B = 20;
	return a*b;
}
viereck.hpp:

Code: Alles auswählen

int berechneFlaeche(int a, int b);
aufteilen.cpp

Code: Alles auswählen

#include <iostream>
#include "viereck.hpp"

using namespace std;

int A, B;

int main()
{
	cout << berechneFlaeche(A, B) << endl;
	return 0;
}
Was mache ich falsch?

GilbertDur
Beiträge: 105
Registriert: Fr Mär 01, 2013 10:31 am

Re: Header und Quelldateien und externe Variablen

Beitrag von GilbertDur » So Mär 24, 2013 4:49 pm

Ich verstehe gerade nicht, warum du es überhaupt so kompliziert machst. Warum zum Beispiel nicht einfach so?

Code: Alles auswählen

#include <iostream>

using namespace std;

int berechneFlaeche(int a, int b)
{
   return a*b;
}

int main()
{
	int ergebnis = berechneFlaeche(10,20);
	cout << "Ergebnis: " << ergebnis << endl;
	return 0;
}

forumnewbie
Beiträge: 80
Registriert: Di Jan 15, 2013 9:02 pm

Re: Header und Quelldateien und externe Variablen

Beitrag von forumnewbie » So Mär 24, 2013 5:12 pm

Weil ein größeres Projekt nicht nur aus einer einzigen Datei besteht.

Benutzeravatar
Xin
nur zu Besuch hier
Beiträge: 8862
Registriert: Fr Jul 04, 2008 11:10 pm
Wohnort: /home/xin
Kontaktdaten:

Re: Header und Quelldateien und externe Variablen

Beitrag von Xin » So Mär 24, 2013 5:31 pm

forumnewbie hat geschrieben:Ich habe in dem Beispiel unten die Variable nur in der Datei aufteilen.cpp definiert, so dass der Compiler keine Fehler meldet. Ich erhalte jedoch als Ergebnis eine 0 - statt 200.
Ich hoffe, das ist ein Übungsbeispiel, ein Experiment, denn das geht als Programmiercode ist das ziemlich daneben.

Die Frage ist eher, warum solltest Du 200 bekommen?
Du übergibst willkürliche Werte, nämlich A und B, an die Funktion berechneFlaeche. Diese willkürlichen Werte werden nach a und b kopiert. Anschließend werden in der Funktion A und B mit 10 bzw. 20 initialisiert und als Rückgabe wird das Produkt aus den beiden kopierten, willkürlichen Werten berechnet. Mindestens eine der willkürlichen Werte scheint also 0 zu sein.
forumnewbie hat geschrieben:Was mache ich falsch?
Du verwendest globale Variablen, ohne einen (sehr, sehr) triftigen Grund.
Merke: Wer Ordnung hellt ist nicht zwangsläufig eine Leuchte.

Ich beantworte keine generellen Programmierfragen per PN oder Mail. Dafür ist das Forum da.

forumnewbie
Beiträge: 80
Registriert: Di Jan 15, 2013 9:02 pm

Re: Header und Quelldateien und externe Variablen

Beitrag von forumnewbie » So Mär 24, 2013 7:04 pm

Danke!
Ich habe keine Ahnung, warum ich dieses Beispiel so gemacht habe. Das war ein anderes Beispiel und ich wollte das mit der externen Variable testen und habe alles durcheinander gebracht :). Bei return wollte ich die globalen Variablen verwenden, habe aber die lokalen Parameter/Variablen noch aus einem alten Beispiel benutzt (statt A ->a und statt B ->b). Und die Funktion braucht in meinem Beispiel auch keine Parameter. Und ich hatte keine Idee, wie ich das am besten testen soll.


Das ist ein Experiment. In dem Buch, was ich gerade lese, wird erwähnt, dass es so etwas gibt. Aber dort steht auch, dass man darauf verzichten sollte und es gibt dazu deshalb auch kein Beispiel. Ich bin neugierig und wollte sehen wie das funktioniert.

So funktioniert das nun richtig:

Code: Alles auswählen

int berechneFlaeche();

Code: Alles auswählen

extern int A, B;

#include "viereck.hpp"

int berechneFlaeche()
{
	return A*B;
}

Code: Alles auswählen

#include <iostream>
#include "viereck.hpp"

using namespace std;

int A, B;

int main()
{
	A = 10, B = 20;
	cout << berechneFlaeche() << endl;
	return 0;
}
Ausgabe: 200

GilbertDur
Beiträge: 105
Registriert: Fr Mär 01, 2013 10:31 am

Re: Header und Quelldateien und externe Variablen

Beitrag von GilbertDur » So Mär 24, 2013 7:55 pm

Ist mir schon klar, dass ein größeres Projekt nicht aus einer einzigen Datei besteht. Anhand von dem Code denke ich aber, dass du noch ziemlich neu in der Programmierung bist und daher mit kleineren Beispielen anfangen solltest. Entweder verstehe ich nicht, was du genau vorhast, oder du willst eine Funktion haben, die eine Berechnung durchführt und zwar anhand von zwei Zahlen. Wenn du das bereits in mehrere Dateien aufteilen willst, könntest du es doch so lösen.

Header:

Code: Alles auswählen

int berechneFlaeche(int, int);
viereck.cpp:

Code: Alles auswählen

#include "viereck.hpp"

int berechneFlaeche(int a, int b)
{
	return a*b;
}
main.cpp:

Code: Alles auswählen

#include <iostream>
#include "viereck.hpp"

using namespace std;

int main()
{
	int ergebnis = berechneFlaeche(10,20);
	cout << "Ergebnis: " << ergebnis << endl;

	cin.get();
	return 0;
}
Oder noch besser: Da du anscheinend C++ machst, am besten gleich eine Klasse schreiben.

Antworten