Satan 0 Posted January 11, 2015 Share Posted January 11, 2015 Vingrinājuma programma, kurā rekursīva funkcija stringā nomaina visus "pi" uz "3.14"ar komentāriem kodā atzīmētas jautājumu vietas:1. Kā ir labāk , iekopēt temp stringā vienu char un atgriezt temp, vai atgriezt pointeri uz pirmo elementu, vai vēl kāds labāks risinājums kad funkcijai ir jāatgriež viens char?2. un 3. Kāpēc nestrādā temp atgriešana ( neizprintējas pēdējais "3.14", kad printē st2), bet sāk strādāt kad pašā funkcijā pirms temp atgriešanas tiek izsaukts printf temp?4. Kāpēc neizvadās pareizi stringi ja visus mēģina izvadīt uz reiz bet izvadās pareizi, ja katru izvada atsevišķi? // uzdevums no http://codingbat.com/java/Recursion-1 #include <stdio.h> #include <string.h> char *changePi(char *string) { char temp[256] = ""; if(strlen(string) == 0) return "\0"; if(strlen(string) == 1) { //1. kaa ir labaak //strncpy(temp, string, 1); //return temp; return &string[0]; } if(strlen(string) == 2) { if(string[0] == 'p' && string[1] == 'i') { /* 2 .kaapeec nestraadaa? strcpy(temp,"3.14"); //kaapeec saak straadaat kad pieliek sho? //printf("temp is %s\n", temp); return temp; */ /* 3 kaapeec nestraadaa? temp[0] = '3'; temp[1] = '.'; temp[2] = '1'; temp[3] = '4'; temp[4] = '\0'; //kaapeec saak straadaat kad pieliek sho? //printf("temp is %s\n", temp); return temp; */ //ar sho straadaa return "3.14"; } else return strncpy(temp, string, 2); } else { if(string[0] == 'p' && string[1] == 'i') { strcpy(temp,"3.14"); return strcat(temp, changePi(string +2)); } else { strncpy(temp, string, 1); return strcat(temp, changePi(string +1)); } } } int main (void) { char st1[] = "a", st2[] = "pi what is pi", st3[] = ""; /* 4 kaapeec nestraadaa printf("original string - modified string\n%s - %s\n%s - %s\n%s - %s\n", st1, changePi(st1),st2, changePi(st2), st3, changePi(st3)); */ printf("original string - modified string\n%s - %s\n", st1, changePi(st1)); printf("%s - %s\n", st2, changePi(st2)); printf("%s - %s\n", st3, changePi(st3)); getchar(); return 0; } Quote Link to post Share on other sites
Salmo 3 Posted January 11, 2015 Share Posted January 11, 2015 (edited) char *changePi(char *string){ char temp[256] = ""; //šie dati funkcijas beigās "pazūd". return strcat(temp, changePi(string +1)); //šeit funkcija atgriež pointeri uz datiem, kas funkcijas beigās "pazūd" } Viens risinājums ir izdalīt atmiņu dinamiski: char *temp = (char *) malloc(sizeof(char) * 256); Šeit aprakstīts tavs gadījums un sniegts viens risinājums kā darīt. http://stackoverflow.com/questions/14416759/return-char-string-from-a-function Edited January 11, 2015 by Salmo Quote Link to post Share on other sites
MarisO 10 Posted January 11, 2015 Share Posted January 11, 2015 ja kodē iekš C, tad ir jāizprot, kuri mainīgie tiek izvietoti stekā (kas "iet bojā" pēc f-jas return) Quote Link to post Share on other sites
Satan 0 Posted January 12, 2015 Author Share Posted January 12, 2015 Paldies par palīdzību, sapratu kļūdu, palasīju par stack un heap un uzrakstīju šo funkciju šādi: Vai pareizi saprotu, ka būs vairākas reizes izveidoti neatkarīgi pointeri *out, katrs savā rekursīvajā izsaukšanas reizē savādāks, un aizņemtais atmiņas daudzums būs visu *out summa, kura tiks atbrīvota tikai tad, kad aiztaisīs programmu. Vai tomēr ir iespēja to atbrīvot bez programmas aizvēršanas, ja nu gadījumā būtu nepieciešams? #define MAX_STRING_SIZE 256 #include <stdio.h> #include <string.h> char *changePi(char *string) { char temp[MAX_STRING_SIZE], *out; int stringSize; out = ( char *) malloc ( 5 * sizeof (char) ); out[0] = '\0'; out[1] = '\0'; if(strlen(string) == 0) return out; if(strlen(string) == 1) { out[0] = string[0]; return out; } if(strlen(string) == 2) { if(string[0] == 'p' && string[1] == 'i') return strcpy(out, "3.14"); else return strncpy(out, string, 2); } else { if(string[0] == 'p' && string[1] == 'i') { strcpy(out,"3.14"); strcpy(temp, changePi(string +2)); stringSize = (strlen(temp) + 5) * sizeof (char); out = ( char *) realloc (out, stringSize); return strcat(out, temp); } else { strncpy(out, string, 1); strcpy(temp, changePi(string +1)); stringSize = (strlen(temp) + 2) * sizeof (char); out = ( char *) realloc (out, stringSize); return strcat(out, temp); } } } int main (void) { char st1[] = "", st2[] = "a", st3[] = "pi what is pi"; printf("original string - modified string\n%s - %s\n%s - %s\n%s - %s\n", st1, changePi(st1),st2, changePi(st2), st3, changePi(st3)); getchar(); return 0; } Quote Link to post Share on other sites
nevertell 33 Posted January 12, 2015 Share Posted January 12, 2015 Paskaties, kas ir funkcija strtok(), šķiet ar to ļoti smuki rekursīvu funkciju var uztaisīt. Quote Link to post Share on other sites
Satan 0 Posted January 13, 2015 Author Share Posted January 13, 2015 Vai strtok() spēj kā vienu delimiteru pieņemt "pi" ? Pēc maniem eksperimentiem iznāk ka viņš ņem divus atsevišķus delimiterus 'p' un 'i', ja ievada "pi" ka delimitera parametru. Quote Link to post Share on other sites
nevertell 33 Posted January 14, 2015 Share Posted January 14, 2015 Nē, bet tu iebaro strtok lielo stringu un tokenu, un pēc tam velc ārā pa vārdam. Tas, ko tev vajag, ir kā tokenu lietot tukšumu, jebšu ' '. Un tad rekursīvā funkcija velk no strtok() ārā kamēr kautkas nāk ārā un konkrētos stringus no sākuma salīdzini pēc garuma strlen. Ja garums atbilst tad varēsi salīdzināt pa burtam. Protamistiski, ir arī strcmp(). Quote Link to post Share on other sites
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.