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
Hast du irgendwo die möglichkeit codezeilen zur verfügung zu stellen?
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)
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 ;)
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.
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)
ÄH Kollega, ab i scho ghabt... had nix gebracht. selber idiota Kannst mehr als schlau blubbern?
Warume du mache an Wolferam? Er gebbe gude Inforemazion. Du mache was Wolferam sage. Und du nixe habbe gehabt, sons funktionira.
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
prototyp: void callbyref(unsigned char *ref); funktion void callbyref(unsigned char *ref) { .. code .. *ref=255; .. }
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
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.
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.
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...
"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
>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. ;-)
progammer's notepad macht da immer so schöne senkrechte Linien...
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.
>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.
>>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
> 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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.