Satan Ierakstīts Janvāris 11, 2015 Share Ierakstīts Janvāris 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; } Link to comment Share on other sites More sharing options...
Salmo Janvāris 11, 2015 Share Janvāris 11, 2015 (labots) 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 Labots Janvāris 11, 2015 - Salmo Link to comment Share on other sites More sharing options...
MarisO Janvāris 11, 2015 Share Janvāris 11, 2015 ja kodē iekš C, tad ir jāizprot, kuri mainīgie tiek izvietoti stekā (kas "iet bojā" pēc f-jas return) Link to comment Share on other sites More sharing options...
Satan Janvāris 12, 2015 Author Share Janvāris 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; } Link to comment Share on other sites More sharing options...
nevertell Janvāris 12, 2015 Share Janvāris 12, 2015 Paskaties, kas ir funkcija strtok(), šķiet ar to ļoti smuki rekursīvu funkciju var uztaisīt. Link to comment Share on other sites More sharing options...
Satan Janvāris 13, 2015 Author Share Janvāris 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. Link to comment Share on other sites More sharing options...
nevertell Janvāris 14, 2015 Share Janvāris 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(). Link to comment Share on other sites More sharing options...
Recommended Posts
Izveido kontu, vai pieraksties esošajā, lai komentētu
Jums ir jābūt šī foruma biedram, lai varētu komentēt tēmas
Izveidot jaunu kontu
Piereģistrējies un izveido jaunu kontu, tas būs viegli!
Reģistrēt jaunu kontuPierakstīties
Jums jau ir konts? Pierakstieties tajā šeit!
Pierakstīties tagad!