Guten Morgen Alle zusammen! ich hätte da ein paar "Urschleimfragen" zu C und AVR-GCC. 1. kann mir jemand sagen, warum die letzte Version vom AVR-GCC immer die Funktion void main(void); anmeckert und einen int Rückgabewert haben möchte? Ich habe mir, als ich mit C und Atmel angefangen habe, mal eingeprägt, daß ein Mikrocontrollerprogramm nichts zurückgeben kann. Wohin auch? Sowas wie z.B. ein Bios ist ja nicht da und da die Verarbeitung ja meist in einer Endlosschleife endet, wird ja ein return (x) auch nie erreicht. Bisher scheint das gestimmt zu haben, jetzt bekomme ich immer eine Warnung. 2. eine Funktion gibt 2 Strings zurück. Unter http://abraham.informatik.fh-lausitz.de/profs/robel/faq/callByReference.html habe ich eine prima Erklärung zu Call by Referenz gefunden... Dann hab ich es so probiert: in meine.c: void Funktion(char *String1, char *String2); //Deklaration einer Funktion //Rückgabe 2x Zeiger auf Str void Funktion(char *String1, char *String2) { ... *String1="ist"; //zum Test einfach was zuweisen *String2="egal"; } in main.c: #include meine.c char[5] Ausgabe1; //String anlegen mit platz für 'i s t \ 0' char[6] Ausgabe2; void main(void) { Funktion(&Ausgabe1,&Ausgabe2); putLCD(Ausgabe1); ... } geht so aber nicht... Im Buch "C für Mikrocontroller" Seite 233 sind Datentypen aufgeführt. Danach ist char[] ein Zeiger auf ein String (Str). Hab ich's also so probiert: void Funktion(char []String1, char []String2); geht auch nicht... Heute Nacht fiel mir ein, geht das überhaupt? C kennt ja den Datentyp "String" gar nicht. Geht der Datenaustausch da evt. nur direkt über eine globale Variable? Schon mal vielen Dank, daß es mir einer erklärt... Gruß Holger
Holger Gerwenat wrote: > Guten Morgen Alle zusammen! > > ich hätte da ein paar "Urschleimfragen" zu C und AVR-GCC. > > 1. kann mir jemand sagen, warum die letzte Version vom AVR-GCC immer die > Funktion > void main(void); > anmeckert und einen int Rückgabewert haben möchte? Weil C seit Anbeginn der Welt von main() fordert, dass es einen int zurückgeben muss. Es waren lediglich einige Compiler (speziell die Micorosoft Compiler) die anfingen void main() zu akzeptieren. Vorgesehen war das nie. Und irgendwann haben sich die Macher von gcc entschlossen, dies zu einer Fehlermeldung zu machen um die abtrünnigen Programmierer wieder auf den Pfad der Tugend zurückzuführen. > Ich habe mir, als ich mit C und Atmel angefangen habe, mal eingeprägt, > daß ein Mikrocontrollerprogramm nichts zurückgeben kann. Wohin auch? Spielt keine Rolle. Der Returntyp von main() ist int. Punkt. Steht so in der Sprachdefinition. > 2. eine Funktion gibt 2 Strings zurück. Unter > http://abraham.informatik.fh-lausitz.de/profs/robel/faq/callByReference.html > habe ich eine prima Erklärung zu Call by Referenz gefunden... > Dann hab ich es so probiert: > > in meine.c: > void Funktion(char *String1, char *String2); //Deklaration einer > Funktion > //Rückgabe 2x Zeiger auf > Str > > void Funktion(char *String1, char *String2) > { > ... > *String1="ist"; //zum Test einfach was zuweisen > *String2="egal"; > } > > in main.c: > > #include meine.c > > char[5] Ausgabe1; //String anlegen mit platz für 'i s t \ 0' > char[6] Ausgabe2; > > void main(void) > { > Funktion(&Ausgabe1,&Ausgabe2); > putLCD(Ausgabe1); > ... > } > > geht so aber nicht... Logisch. Strings kann man in C nicht zuweisen. Deine Zuweisung da oben macht ganz was anderes. Die Pointervariable, die die Funktion erhält (in C gibt es nämlich in Wirklichkeit keinen Call by Referenz, alles wird immer per Value übergeben) wird auf die Startadresse deiner konstanten Strings gesetzt. Das hilft dir aber nicht viel, weil diese Poitnervariable ja nur während der Laufzeit der Funktion existiert und nach Beendigung der FUnktion wieder zerstört wird. Was du erreichen willst, geht so void Funktion(char *String1, char *String2) { strcpy( String1, "ist" ); //zum Test einfach was zuweisen strcpy( String2, "egal" ); } int main(void) { Funktion( Ausgabe1, Ausgabe2 ); putLCD(Ausgabe1); ... } Beachte auch, dass die & im Aufruf unsinnig sind. Arrays werden sowieso immer an Funktionen übergeben, indem die Adresse des ersten Elements übergeben wird. Leider akzeptieren viele Compiler die Schreibweise &Array an dieser Stelle als Ersatz für die korrekte Schreibweise ohne & > Hab ich's also so probiert: > void Funktion(char []String1, char []String2); > > geht auch nicht... Ist auch klar. Das ist nur eine andere Schreibweise für einen Pointer. Meine persönliche Meinung: vergiss diese Notation wieder. Sie bringt nur Konfusion. Man könnte es in deinem speziellen Fall auch so machen void Funktion(const char **String1, const char **String2) { *String1="ist"; //zum Test einfach was zuweisen *String2="egal"; } int main() { const char* pStr1, const char* pStr2; Funktion( &pStr1, &pStr2); putLCD( pStr1 ); } Dann ist allerdings die Funktion dafür verantwortlich, den Speicher zur Verfügung zu stellen, in dem die tatsächlichen Character gespeichert sind. Dieser Speicher muss auch nach Beendigung der Funktion noch existieren! Im Regelfall geht dies nur wenn * der String, so wie in deinem Fall, ein String-Literal ist * der String in einem globalen Array residiert * mit malloc() und free() gearbeitet wird. > Heute Nacht fiel mir ein, geht das überhaupt? C kennt ja den Datentyp > "String" gar nicht. Geht der Datenaustausch da evt. nur direkt über eine > globale Variable? http://www.mikrocontroller.net//articles/FAQ#Wie_funktioniert_String-Verarbeitung_in_C.3F
Holger Gerwenat wrote: > Guten Morgen Alle zusammen! > > ich hätte da ein paar "Urschleimfragen" zu C und AVR-GCC. > > 1. kann mir jemand sagen, warum die letzte Version vom AVR-GCC immer die > Funktion > void main(void); > anmeckert und einen int Rückgabewert haben möchte? In ANSI-C ist main() nunmal vom Typ int, und der GCC-C-Compiler ist ein ANSI-Compiler und meckert deshalb zu Recht. Das war auch bei bisherigen GCC-Versionen nicht anders. > Ich habe mir, als ich mit C und Atmel angefangen habe, mal eingeprägt, > daß ein Mikrocontrollerprogramm nichts zurückgeben kann. Wohin auch? > Sowas wie z.B. ein Bios ist ja nicht da und da die Verarbeitung ja meist > in einer Endlosschleife endet, wird ja ein return (x) auch nie erreicht. > Bisher scheint das gestimmt zu haben, jetzt bekomme ich immer eine > Warnung. Es gibt kommerzielle Compiler, die tatsächlich void als Typ für main akzeptieren, was dann aber nicht mehr durch den ANSI-Standard abgedeckt ist. Es ist aber auch keine Fehlermeldung, sondern nur eine Warnung, die Dich darauf hinweisen soll, dass da etwas steht, was evtl. anders gemeint sein könnte... > #include meine.c Da fehlt was, außerdem sollte man keine C-Dateien direkt includen. > char[5] Ausgabe1; //String anlegen mit platz für 'i s t \ 0' Der Nullterminator '\0' ist ein Zeichen... > char[6] Ausgabe2; > > void main(void) > { > Funktion(&Ausgabe1,&Ausgabe2); Die '&' sind falsch. Bei Arrays gilt: Der Name des Arrays repräsentiert die Adresse des ersten Array-Elements (array = &array[0]). Du versuchst, die Adresse der Adresse des ersten Elements zu übergeben, und das geht schief. Lass die Adress-Operatoren weg. > Heute Nacht fiel mir ein, geht das überhaupt? C kennt ja den Datentyp > "String" gar nicht. Geht der Datenaustausch da evt. nur direkt über eine > globale Variable? Nein, C kennt keinen Datentyp "string". Aber mit Arrays funktioniert es auch, wenn man die Elemente einzeln verarbeitet oder Funktionen wie strncpy() aus der string.h verwendet.
Danke Karl-Heinz, Danke Johannes! Ich hab ja meine Frage kaum getippt.....schon Antwort da. Wie geht das? :-))) Gut, ne Menge gelernt: 1. Main ist ab jetzt immer ein int! 2. Klar, #include *.c hab ich nur der Einfachheit halber geschrieben, in Wirklichkeit wird natürlich korrekt eine *.h eingebunden ;-) 3. Oh! \0 ist ein Zeichen -> nicht gewußt -> gemerkt 4. Meine Aufgabe werde ich so wie beschrieben lösen... Nochmals Danke, für Eure Hilfe. Gruß Holger
Holger Gerwenat wrote:
> 3. Oh! \0 ist ein Zeichen -> nicht gewußt -> gemerkt
Wenn ein Zeichen mit \ beginnt, dann gehört immer noch ein
zweites Zeichen dazu. \ ist das Fluchtsymbol, welches dem
Compiler sagt, dass das nächste Quellcode-Zeichen anders zu
interpretieren ist
\n ist ein Line Feed
\r ist ein Carriage Return
\f ist ein Form Feed (neue Seite am Drucker)
\t ist ein Tabulator
\b ist ein Backspace
\a ist das Bell-Symbol (die Glocke. Hat heute keine
Bedeutung mehr und kommt noch aus der Zeit als
Terminals noch auf Papier schrieben und nicht auf
einem Monitor. Manche Terminals beepen noch, wenn sie
dieses Zeichen empfangen)
\" ist ein " Zeichen in einem String
\0 ist der Null-Terminator eines Strings
\\ ist dann letztendlich ein einzelner \
Aber: Auch wenn du 2 Tastendrücke dafür brauchst, aus Sicht des
Compiler ist das immer ein einzelnes Zeichen.
Karl heinz Buchegger wrote:
> Fluchtsymbol
Würg! Ist das jetzt die 1:1 Übersetzung von Escape-Character oder gibt's
das so wirklich auf deutsch? ;)
Simon K. wrote: > Würg! Ist das jetzt die 1:1 Übersetzung von Escape-Character oder gibt's > das so wirklich auf deutsch? ;) Also ich find die Übersetzung klasse...
Simon K. wrote: > Karl heinz Buchegger wrote: >> Fluchtsymbol > > Würg! Ist das jetzt die 1:1 Übersetzung von Escape-Character oder gibt's > das so wirklich auf deutsch? ;) Ich hatte schon die Finger über Escape. Hab aber dann schnell umdirigiert um eine Verwechslung mit dem Escape-Character 0x1B zu vermeiden. Ich glaube den Terminus Fluchtsymbol tatsächlich das erste mal in einer deutschen Version von K&R gelesen zuhaben :-) Ansonsten: ja natürlich - Würg auch hier bei mir.
Den Begriff (auch "Fluchtzeichen") habe ich schon öfters gehört. Das ist tatsächlich die gängigste Übersetzung. Sie zeigt, daß manche Begriffe besser unübersetzt bleiben.
"Fluchtsequenz" wurde in Modemhandbüchern gerne genutzt (V42.bis als Bsp). Nein kein DSL-Modem-Handbuch ;-) Gruß Michael
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.