Hallo, ich hab mal eine Frage zu Rückgabewerten von Funktionen. Kann man auch irgend wie einen String mit "return" zurück geben, ohne globale Variablen zu verbraten? Ich habe z.B. eine Funktion geschrieben, der ein Char übergeben wird. Die Funktion wandelt die Zahl in einen String mit 3 Stellen + String-Abschluß-Null (0x00) z.B. 0x87 (135 dezimal) in "1", "3", "5" und 0x00 Bisher verwende ich einen globalen String hierfür, den ich im Unterprogramm entsprechend modifiziere: string[0] = 0x31; // 1 string[1] = 0x33; // 3 string[2] = 0x35; // 5 string[3] = 0x00; // String-Abschluß Solche Strings habe ich etliche im Programm (auch ein paar größere) die zusammen sehr viel RAM verbraten. Kann man einen lokalen String eines Unterprogramms irgend wie an die aufrufende Funktion übergeben? Oder ist es generell erforderlich, einen globalen String hierfür zu verwenden? Habs schon mal mit return(string), return(*string) usw. probiert. Geht aber nicht... Martin
mit nem char *func(void) { char *ret = malloc(sizeof("Hallo!")); ret = "Hallo!"; return ret; } int main() { printf("asd%sasd",func()); } solltes gehen (an free() denken)
Für nur 4 Bytes malloc/free aufrufen ist Nonsens. Es reicht völlig, wenn der Aufrufer einen entsprechend lange Stringvariable anlegt und deren Adresse übergibt. Globale Variablen sollte man nur dann verwenden, wenn sie auch wirklich die gesamte Programmdauer erhalten bleiben müssen. Peter
Hallo, "Es reicht völlig, wenn der Aufrufer einen entsprechend lange Stringvariable anlegt und deren Adresse übergibt." Das kann in die Hose gehen wenn der String nicht "static" ist (und dann hat man ja nichts gewonnen). Dangling reference heißt das. Die lokale Variable der Funktion wird nach return ja verworfen d.h. die Adresse, auf die der Pointer zeigt kann schon wieder für was anderes verwendet sein. Ich deklariere zu diesem Zweck eine globale scratch variable, die von allen Funktionen benutzt werden kann. Reiner
@Reiner, "Die lokale Variable der Funktion wird nach return ja verworfen" Wird sie eben nicht, da sie ja der Aufrufer anlegt und nicht die aufgerufene Funktion. Der Aufrufer kann sie also bequem verwenden, da sie erst ungültig ist, wenn er selber endet:
1 | void f1( char *p) |
2 | {
|
3 | p[0] = '1'; |
4 | p[1] = '2'; |
5 | p[2] = '3'; |
6 | p[3] = 0; |
7 | }
|
8 | |
9 | void f2(void) |
10 | {
|
11 | char x[4]; // anlegen |
12 | |
13 | f1( x ); // Adresse übergeben |
14 | |
15 | printf("%s\n", x ); // Ergebnis verwenden |
16 | }
|
Peter
>> "Es reicht völlig, wenn der Aufrufer einen entsprechend lange >> Stringvariable anlegt und deren Adresse übergibt." > Das kann in die Hose gehen wenn der String nicht "static" ist (und > dann hat man ja nichts gewonnen). peter dannegger schrieb vom Aufrufer, nicht von der aufgerufenen Funktion.
P.S.: Man kann aber auch mit typedef sich eine Typ definieren, der 4 Byte lang ist und den dann als Returntyp angeben. Wird z.B. gemacht, wenn man mehrere Returnwerte in einer struct zurückgeben will. Letztendlich legt dabei aber auch der Aufrufer den entsprechenden Speicherplatz an. Peter
@Peter Hast recht! Das mit dem Aufrufer hatte ich überlesen ):- Reiner
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.