Forum: Mikrocontroller und Digitale Elektronik PROZEDUR aus Prozedur aus aufrufen


von LPTKING (Gast)


Lesenswert?

Hallo Leute,

nach langer Abstinenz hat michs mal wieder vor den AVR compiler
verschlagen.

Und prompt hat ich ein Problem:
wie ruft man eine Prozedur von einer anderen Prozedur aus auf?? Mein
WIN AVR frisst es nicht.

Ferner laufen jede Menge warnings runter :

warning: function isn't a prototype

das komische : bei manchen Funktionen gibts die Warning, bei anderen
die eigentlich gleich deklariert sind, gibts die Warning nicht.

Ausgangspunkt war ein .h File, in dem ich die Funktionen deklariert und
gleich implementiert hab, schließlich hab ichs noch mit aufteilen in .h
und .c File versucht - ohne Erfolg...

Kann mir jemand helfen?

Vielen Dank schon im voraus!

LPTKING

von Niels H. (monarch2)


Lesenswert?

Hast du irgendwo die möglichkeit codezeilen zur verfügung zu stellen?

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

In C können Funktionen beliebig aus anderen Funktionen heraus aufgerufen
werden. Damit der Compiler aber nicht nörgelt, ist die Angabe eines
Funktionsprototyp (Pascal-Lingo "Vorwärtsdeklaration") erforderlich.

Geschachtelte Funktionen (die also nur innerhalb einer Funktion
überhaupt definiert sind) gibt es hingegen nicht.

Ansonsten ist bei Fragen in diesem Forum der Hinweis von Niels zu
beachten.


Literaturhinweis:
Kernighan & Ritchie, Programmieren in C, Hanser Verlag, zweite Auflage
(oder neuer)

von LPTKING (Gast)


Angehängte Dateien:

Lesenswert?

Hallo Leute,

danke für die prompte Beantwortung. Tja was soll ich sagen, als ich
wie gefordert ein Codebeispiel generieren wollte passierte es:
es funzte einfach....

Schlimmer noch im eigentlichen Projektchen funzte es auch...

Das einzige was von dem Problemchen noch über ist, sind die Warnings:


In file included from MultiProc.c:4:
./Grundmodule.h:1: warning: function declaration isn't a prototype
./Grundmodule.h:13: warning: function declaration isn't a prototype
./Grundmodule.h:26: warning: function declaration isn't a prototype
./Grundmodule.h:38: error: parse error before '&' token
./Grundmodule.h:38: warning: function declaration isn't a prototype
MultiProc.c:7: warning: return type of 'main' is not `int'
make.exe: *** [MultiProc.o] Error 1

> Process Exit Code: 2

Im beigefügten Source Code habe ich ferner noch gleich eine Neuerung
eingeführt: Anstatt ein Call by Reference via Pointer würd ichs
gern "normal" machen, also beim Übergabeparameter ein &
mitanflanschen.

Allerdings will er das nicht. Könnte mir da jemand einen Tip geben? Wär
einfach bequemer als mit den Zeigern rum zu biegen..

BVielen Dank schon mal im Vorhinein, und sorry für das wohl vorschnelle
Alarm schlagen ;)

von Harry (Gast)


Lesenswert?

Kollega, du musse DEKLARATION in Header File unde DEFINITION in C-File.

Du nur habbe DEFINITION in Header File. Idiota!

Unde deine Formatierunge sehe scheisse au.

von Wolfram (Gast)


Lesenswert?

oder in Deutsch formuliert,
in ein Header .h File gehört kein Code der kommt ins .c file.
Du gibst keine prototypen für die Funktionen an, deshalb nölt der
Compiler und du bekommtst probleme wenn du eine Funktion aufrufen
willst die weiter unten erst im Programm deklariert ist.

Vielleicht solltest du doch erstmal das angegebene Buch lesen
>Literaturhinweis:
>Kernighan & Ritchie, Programmieren in C, Hanser Verlag, zweite
Auflage
>(oder neuer)

von LPTKING (Gast)


Lesenswert?

ÄH Kollega,

ab i scho ghabt... had nix gebracht.

selber idiota

Kannst mehr als schlau blubbern?

von Harry (Gast)


Lesenswert?

Warume du mache an Wolferam? Er gebbe gude Inforemazion. Du mache was
Wolferam sage.

Und du nixe habbe gehabt, sons funktionira.

von LPTKING (Gast)


Lesenswert?

Also noch mal für die die nur Kaudawelsch von sich geben, und für die
die was taugen (z.B. Wolfram):

Forwarding war sicher nicht das ursprüngliche Problem, da ich ja meine
Funktionen kausal richtig deklariere und halt auch gleich definiere.

Trennung in Definition und Deklaration hat ich schon mal, hat damals
nichts gebracht - werds nochmal checken.

Ursprüngliches Problem hat sich erledigt, weil geht (trotz Definition
und Deklaration in .h)  - weshalb? Gute Frage...


Verbleibendes Problemchen: wie kann ich anstatt via Zeiger einen Call
by Reference machen?  Eigentlich mittels DATENTYP Funktionsname
(DATENTYP& VARNAME).

Kann mir da jemand helfen?

Danke - selbst wenn die Hilfe vom leicht beschränkten Harry kommt

von Wolfram (Gast)


Lesenswert?

prototyp:
void callbyref(unsigned char *ref);

funktion
void callbyref(unsigned char *ref)
{
..
code
..
*ref=255;
..
}

von LPTKING (Gast)


Lesenswert?

Ok, also via Zeiger? So hab ichs schon. bloß dann bild ich mir ein,
ich muß im main, oder in der aufrufenden Instanz folgende Zeilen
haben:

uint8_t Variable;
uint8_t *ZeigerVariable;
ZeigerVariable=&Variable;

um beim Aufruf einer CBR Funktion einen Zeiger übergeben zu können.


Und diese drei Zeilen gehts mir : Interpretiert der AVR Compiler etwa
das * Argument automatisch wie ein & wenn kein Zeiger übergeben wird?
Das wäre aber gewagt...

jedenfalls danke wolfram

von inoffizieller WM-Rahul (Gast)


Lesenswert?

schon mal was von "return ;" gehört?

von Peter D. (peda)


Lesenswert?

Also nochmal ganz langsaaam:

1.
- man deklariert jede Funktion vor ihrer ersten Verwendung

2.
- man definiert alle Funktionen am Anfang, bevor überhaupt Code
geschrieben wird

3.
- man macht zu jedem Modul (*.c) ein h-File, indem alle Funktionen
definiert werden, die extern benötigt werden.
- jedes Modul welches eine externe Funktion aufruft, bindet das
gleichnamige *.h ein.


Irgendwann benutzt man ausschließlich Methode 3


Peter


P.S.:
Warnungen sollte man nie ignorieren, auch wenn es scheinbar läuft.

Und Harry hat recht bezüglich Formatierung, C-Programmierer arbeiten
mit Einrückungen um unterschiedliche Ausführungsebenen zu kennzeichnen.

von Harry (Gast)


Lesenswert?

LPTKING:

Du nixe kapire! Stupido!

von Wolfram (Gast)


Lesenswert?

Hauptprogramm
...
unsigned char Variable;
...
callbyref(&Variable);

deine Fragen betreffen C-Grundlagen,
wenn dir das empfohlene Buch nicht gefällt, würde es auch jedes andere
C-Buch ab 100 Seiten tun.

von LPTKING (Gast)


Lesenswert?

Ok ok, schön schön, den Programmierstil hab ich nicht erfunden, und
werd ich auch nicht...

aber um das hier abzuschließen: Das verbleibende Problemchen
- wie vermeidet man den doppelten Variablenhaushalt- aus der Welt
zu räumen is mir grad wieder die Lösung eingefallen:

Einfach beim Aufruf &Variablenname statt nur Variablenname übergeben..

Schön langsam dämmerts wieder mit dem C....

Gruß
an alle

PS: In Zukunft werd ich alles einrücken, und formatieren, damits auch
die Harrys dieser Welt lesen können - selbst wenns nur lächerliche
zehn Zeilen sind...

von Peter D. (peda)


Lesenswert?

"selbst wenns nur lächerliche zehn Zeilen sind..."

Es sieht auch schon bei nur 10 Zeilen Scheiße aus.

Ich machs schon ab 4 Zeilen:
1
void foo( void )
2
{
3
  // irgendwas
4
}


Peter

von Wolfram (Gast)


Lesenswert?

>Und Harry hat recht bezüglich Formatierung, C-Programmierer arbeiten
>mit Einrückungen um unterschiedliche Ausführungsebenen zu
kennzeichnen.
Also ich hab da schon schlimmeres gesehen.
Besser sollte man formulieren:
Wenn man will, dass andere den Code durchschauen, sollte man mit
Einrückungen unterschiedliche Ausführungsebenen kennzeichnen.
Dem C-Compiler ist das egal.
Allerdings muss ich auch sagen, dass ein Programmtext der keine
Formatierung hatte, meist auch ein Programm enthielt das keine Struktur
hatte.
Es gibt auch Formatierungstools, die sowas im nachhinein machen. Die
Formatierung, nicht die Struktur. ;-)

von inoffizieller WM-Rahul (Gast)


Lesenswert?

progammer's notepad macht da immer so schöne senkrechte Linien...

von Markus (Gast)


Lesenswert?

1) Dein Problem mit "manchmal tuts" liegt daran, in welcher
Reihenfolge Du die Funktionen definiert hast. Wenn Du in Funktion B die
Funktion A aufrufen willst, dann muss A vorher definiert sein. Der
Compiler parst jede Datei nur einmal und wenn er gerade Funktion B
verarbeitet, dann muss er den Funktionskopf von A bereits kennen, sonst
kommen die Fehlermeldungen. Das wird dann bei mehreren Funktionen aber
beliebig umständlich. Deswegen trennt man Deklaration und Definition
der Funktionen in .h und .c und dann hat man das Problem nicht.

2) In C gibts kein Call by Reference, deswegen behilft man sich halt
mit Pointern auf Variablen. Das mit dem "&" vor der Variable hast Du
ja schon erkannt. Hat man allerdings schon einen Pointer (z.B. bei
Strings), dann braucht man das allerdings normalerweise nicht.

3) Wenn Du schon 10 Zeilen nicht richtig formatierst, dann wirst Du es
vermutlich auch bei 20 oder 50 Zeilen nicht tun.

von inoffizieller WM-Rahul (Gast)


Lesenswert?

>In C gibts kein Call by Reference
Und wozu macht man dann das Spielchen mit den Pointern?
So läuft das halt in C - in anderen Programmierprachen läuft es anders.

von Markus (Gast)


Lesenswert?

>>In C gibts kein Call by Reference
>Und wozu macht man dann das Spielchen mit den Pointern?
>So läuft das halt in C - in anderen Programmierprachen läuft es
anders.

Nein. C kann es nicht, deswegen bildet man die Funktionalität eben von
Hand nach. Genauso wie z.B. die AVRs nicht dividieren können. Das
bedeutet auch nicht, dass man damit keine Division berechnen könnte,
sondern nur, dass man dafür extra Aufwand treiben muss. Da würde ja
auch keiner sagen, das sei die Art, wie AVRs dividieren.

Markus

von Karl heinz B. (kbucheg)


Lesenswert?

> Und wozu macht man dann das Spielchen mit den Pointern?

Das ist aber immer noch kein 'call per reference'.
Das du mit dem Pointer ein Mittel in der Hand hast
um aus der Funktion auf Variablen ausserhalb der Funktion
zuzugreifen ändert nichts daran, dass der Pointer
'per value' übergeben wird.

In C gibt es schlicht und ergreifend kein 'call per reference'.
Anders in C++

void foo( int& i )
{
  i = 5;
}

int main()
{
  int j;
  foo( j );
  // j hat den Wert 5
}

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.