Forum: PC-Programmierung Variable soll nicht gelöscht werden beim zyklischen aufrufen


Announcement: there is an English version of this forum on EmbDev.net. Posts you create there will be displayed on Mikrocontroller.net and EmbDev.net.
von Toni E. (johny123)


Lesenswert?

ich habe ein main Funktion die zyklisch aufgerufen wird, diese ruft 
zyklisch modul1 auf und dort modul2 welches mir einen wert berechnet. 
Dieser wert soll in Modul1 zur verfügung stehen und bei jedem Aufruf von 
modul2 kommt x dazu. Das heißt der Wert davor darf nicht gelöscht 
werden.

wie mache ich nun das Ganze? Lege ich eine Globale Variable in der 
header von modul2 an? Oder mache ich das mit static in modul1?
1
int main(void)
2
{
3
   // modul2Parameter g_mod2Par; hier global anlegen oder in modul 1?
4
5
6
modul1();
7
}
8
9
10
11
modul1()
12
{
13
  //hier als static anlegen?? static modul2Parameter mod2par;
14
  ergebis =  modul2(); // ergebnis soll in modul1 und modul zwei nicht immer bei 0 anfangen sondern den wert +x bekommen, bis die variable auf 0 in modul 2 gesetzt wird.
15
}
16
17
18
19
//modul 2 .h-Datei
20
{
21
    typedef struct
22
    {
23
        bool gestartet;
24
        int zeit;
25
    }modul2Parameter;
26
27
    extern modul2Parameter; // ODER So machen und in main von diesem Typ eine Variable anlegen?
28
}

von Hadmut F. (hadmut)


Lesenswert?

Schreib die deklaration von ergebis ausserhalb von main()

von Toni E. (johny123)


Lesenswert?

Das Ergebnis wird aber auch in einer Struktur von modul1 gespeichert. 
Hier habe ich einfach in "Ergebnis" zur Vereinfachung geschrieben.


Modul1 sieht so aus:
1
modul1.h
2
typedef struct
3
{
4
 int Ergebnis;
5
}mod1Parameter;
in der Main habe ich mit mod1Parameter g_module1; eine globale Variable 
angelegt.

von Klaus H. (klummel69)


Lesenswert?

Du solltest globale Variablen möglichst vermeiden. Je größer Projekte 
werden, desto höher das Risiko dass es dadurch zu Problemen kommt 
(mehrere Module verändern ungewollt den Inhalt...).

Deine Beschreibung ist etwas wirr.

Wenn ich recht verstehe liefert Modul2 einen (Zeit?)Wert den du an 
Modul1 übergibst? Oder willst Du eine ganze Struktur (modul2Parameter) 
zurückgeben?
Modul1 soll den Wert auf eine Summenvariable aufaddieren, es sei denn es 
kommt ein Wert 0 vom Modul2 zurück. Ist der Zahlenwert aus Modul2 eine 
Zeitdifferenz oder eine absolute Zeit?

Egal was die Aufgabe des Programmes ist: Versuche dir eine 
"verständliche" Schnittstelle ohne globale Variablen zu definieren.
Codezeile wie "ergebis =  modul2();" ist unverständlich. Versuche 
beschreibende Namen zu nutzen.

von Florian L. (muut) Benutzerseite


Lesenswert?

Wie ist das zu verstehen dass die main zyklisch aufgerufen wird?
Typischer Weise wird ein Programm beendet, wenn die main verlassen wird. 
Dabei wäre es guter Stil, einen sinnvollen Return Wert an das 
Betriebssystem zurückzugeben.

Wenn du die Unterfunktion zyklisch aufrufen willst, kannst du eine 
Schleife in der Main einbauen. Dann könntest du deine Daten als lokale 
variable in der Main verwalten.

von Bruno V. (bruno_v)


Lesenswert?

Ja, mit static.

Eine Variable in einer Funktion oder tieferem Block ist ohne static bei 
jedem Aufruf unbestimmt. Mit static wird sie praktisch zur globalen 
variable, die nur innerhalb dieses Blocks bekannt ist

von Oliver S. (oliverso)


Lesenswert?

Allerdings wurden kurz nach dem Pleistozän der 
Programmiersprachenentwicklung sowas wie Funktionsparameter und 
Rückgabewerte erfunden. Die eignen sich für viele Aufgabenstellungen 
ganz vorzüglich.

Oliver

von Monk (roehrmond)


Lesenswert?

Was genau ist hier ein "Modul"?

Mir scheint, dass eine Funktion gemeint ist. Aber warum nennst du sie 
dann "Modul"?

Wie gesagt kannst du innerhalb einer Funktion eine Variable als static 
kennzeichnen, damit sie ihren Wert bei Verlassen der Funktion nicht 
vergisst.

Möchtest du, dass eine Gruppe von Funktionen Zugriff auf dazu gehörige 
Daten hat? Dazu kann man eine globale Variable verwenden. Wenn diese als 
static gekennzeichnet ist, dann ist sie nur von Funktionen in der selben 
Quelltext Datei erreichbar. Um sie von außen lesbar zu machen böte sich 
eine getter-Funktion an.

Wenn du mehrere Instanzen dieser globalen Variablen brauchst, informiere 
dich über objektorientierte Programmierung. Dazu muss es micht zwingend 
C++ sein. Man kann auch in C objektorientiert programmieren. Jede 
Objektfunktion bekommt als ersten Parameter eine Struktur mit den 
Zustandsdaten der Objekt-Instanz übergeben.

von Bruno V. (bruno_v)


Lesenswert?

Toni E. schrieb:
> Das Ergebnis wird aber auch in einer Struktur von modul1 gespeichert.

Ganz generell: Schreibe einen Code, der möglichst einfach genau Dein 
Problem schildert. Lass unnötige Kommentare weg, kürze lange Namen, aber 
mach es "rund", also prinzipiell lauffähig. Es ist (in diesem Fall) auch 
egal, ob es in einer oder n Dateien verteilt ist (Header und deren 
Verwendung sind ein Thema für sich).

Meinst Du z.B. so?
1
int modul2(int par)
2
{
3
   if(par == ... // verarbeite par
4
   ...
5
   return 2; // irgendein Rückgabewert
6
}
7
8
void modul1(void)
9
{
10
static int ergebnis;
11
12
   ergebnis += modul2(ergebnis);  
13
   if(ergebnis ... // was auch immer 
14
}
15
16
int main(void)
17
{
18
   for(;;)
19
   {
20
      modul1();
21
   }
22
}
Je nach Deiner eigentlichen Aufgabe kannst du auch einen Pointer 
verwenden. Oder (auch wenn man es nicht soll) eine globale Variable.

von Toni E. (johny123)


Lesenswert?

Danke für die Tipps.

Eigentlich soll es quasi Objektorientiert sein, also Struktur wird als 
Pointer übergeben usw. Mein Problem ist wo lege ich die Struktur 
variable an in der while(1) schleife, in Modul 1? Und wird sie global 
angelegt oder wie?
1
typedef struct
2
{
3
 int zeit;
4
 int Ergebnis;
5
}zeitModul;
6
int modul2(int par)
7
{
8
   if(par == ... // verarbeite par
9
   ...
10
   return 2; // irgendein Rückgabewert
11
}
12
void modul1(Zeitmodul *zeiten)
13
{
14
static int ergebnis;
15
   Zeiten.Ergebnis += modul2(Zeiten.Ergebnis);  
16
   if(ergebnis ... // was auch immer 
17
}
18
int main(void)
19
{
20
 zeitmodul Zeiten; // hier oder in Modul 1?
21
   for(;;)
22
   {
23
      modul1(&Zeiten);
24
   }
25
}

: Bearbeitet durch User
von Harald K. (kirnbichler)


Lesenswert?

Toni E. schrieb:
> // hier oder in Modul 1?

Da Deiner bizarrerweise als "modul1" bezeichneten Funktion ein Pointer 
auf diese Variable übergeben wird, ganz offenkundig hier.

von Klaus H. (klummel69)


Lesenswert?

Toni, du solltest etwas mehr Sorgfalt auch in solchen "Überlegungscode" 
stecken.
Drei Schreibweisen für "zeitModul". In C wird Groß-/Kleinschreibung 
beachtet, also achte darauf.
Unten habe ich Deinen "Überlegungscode" kommentiert. Das sind einige 
Macken drin..

Achtung, du hast das Risiko eines "Seiteneffekts", wenn du eine Variable 
als Zeiger übergibst und den Rückgabewert wieder auf diese Variable 
speicherst.

Zur ursprünglichen Frage:
>"wie mache ich nun das Ganze? Lege ich eine Globale Variable in der
>header von modul2 an? Oder mache ich das mit static in modul1?"

Welches ist die oberste Ebene auf der du die Variable benötigst?
Wenn der höchste Geltungsbereich die Funktion "main" ist, dann reicht es 
sie innerhalb von main zu deklarieren. Brauchst Du sie noch in anderen 
Funktionen dieses Sourcecodes, dann halt auf Dateiebene.

Regeln:
* Der Geltungsbereich einer Variablen sollte so klein als möglich 
gewählt werden.
* Globale Variablen über Dateigrenzen hinweg nur im Notfall. Dann besser 
Zugriffsfunktionen.
1
typedef struct
2
{
3
   int zeit;
4
   int Ergebnis;  // Tipp: eimal groß, einmal klein --> sei gleich ordentlich und nutze eine Schreibweise...
5
} zeitModul;
6
7
int modul2(int par)
8
{
9
   if(par == ...)
10
   ...
11
   return 2; 
12
}
13
14
void modul1(Zeitmodul *zeiten) // ⚠️ Schreibfehler: "zeitModul"
15
{
16
   static int ergebnis;
17
   // ⚠️ Tippfehler: Der Parameter "zeiten" wird nicht genutzt. 
18
   // Es wird  eine globale "Zeiten" (großgeschrieben) Variable genutzt, die aber noch nicht bekannt ist...
19
   // ⚠️ Hier fehlt der Adressoperator "&Zeiten.Ergebnis"
20
   // ⚠️ Alarm: Seiteneffekt: Ergebnis könnte in Funktion "modul2" verändert werden. 
21
   Zeiten.Ergebnis += modul2(Zeiten.Ergebnis);  
22
23
   if(ergebnis ...) // ⚠️ ergebnis wird hier nicht genutzt...
24
}
25
26
int main(void)
27
{
28
   zeitmodul Zeiten; // ⚠️ Schreibfehler: "zeitModul"
29
   // ⚠️ Error: Variable ggf. falsch initialisiert
30
   for (;;)
31
   {
32
      modul1(&Zeiten);
33
   }
34
}

: Bearbeitet durch User
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.