UK 18.08.2000 Tehtävä 1 #include int todays(int day, int month, int year) { static int Monthdays[] = {0,31,28,31,30,31,30,31,31,30,31,30,31}; int i, days=0; for (i=1;i max +2p logiikka 7 p karkausvuoden laskeminen 3 p - merkitys 1p - oikea laskeminen 2p kuukausien laskeminen 2p vuosien /päivien laskeminen/erotuksen laskeminen 2 p ############################################################################## UK 18.08.2000 Tehtävä/ Problem 2 #include int main(int argc, char *argv[]) { char table[100]; int i, j, l=0,k=0; char *p, *q; char c; if (argc < 2) { printf("No string to check!\n"); return 0; } /* First move the strings given as arguments to a single table */ for (i=1; i -4 p Yritti siirtoa, mutta ei täysin onnistunut -2p kopioidaan pelkkiin osoittimiin -2p aloitetaan merkkijono ohjelman nimestä -2 p * tehtävän logiikka => palindromin oikea havaitseminen 3 p - osoittimia päivitetään väärin => ei löydetä palindromeja => -2p - käydään turhaan taulukkoa läpi eli lopetetaan vasta, kun alkuun osoittava osoitin on lopussa (tai loppuun osoittava alussa). -1 - palindromin määrittävä ehto hieman väärin -1 p, täysin pielessä -2 p * muut piirteet 2 p puuttuu, vaikka tarvitaan -1p sekavaa ja turhaa -1-2 p ############################################################################### UK18.8.200 Tehtävä 3. #include #include /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/ /* Tässä a-kohdan rakenteet */ typedef struct node { char key; struct node *next; }alkio; typedef struct list { struct node *nodes; }lista; /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/ /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/ /* Tässä b-kohdassa vaadittu tyhjän listan luominen */ lista *perusta_lista() { lista *l; l = (lista *)malloc(sizeof(lista)); if (l==NULL) return NULL; l->nodes= NULL; return l; } /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/ /* Alkion luomista ei pyydetty kokeessa*/ alkio *luo_alkio() { alkio *s; s = (alkio *)malloc(sizeof(alkio)); if (s==NULL) return NULL; memset(s,0,sizeof(alkio)); return s; } /* Alkion lisäämistä ei pyydetty kokeessa*/ int lisaa_alkio(lista *l, alkio *s) { s->next = l->nodes; l->nodes=s; return 1; } /* Alkion tulostamista ei pyydetty kokeessa*/ void tulosta_lista(lista *l){ alkio *s; for (s= l->nodes; s; s=s->next) printf ("%c", s->key); } /* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% */ /* tässä pyydetty funktio list_reverse, joka kääntää */ /* yksisuuntaisen linkitetyn listan alkiot */ lista *kaanna(lista *l){ /* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/ alkio *p,*q; if(l->nodes) { p=(l->nodes)->next; (l->nodes)->next = NULL; while (p){ q=p; p=p->next; q->next = l->nodes; l->nodes=q; } } return l; } /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/ /* pääohjelmaa ei pyydetty kokeessa */ int main(void) { lista *l; alkio *s; char c; /*luodaan lista peräkkäistä kirjaimista a-g */ l= perusta_lista(); if(l==NULL) return 0; /*ei onnistuttu perustamaan listaa*/ for (c='a'; c<'h'; c++) { s = luo_alkio(); if(s==NULL) return -1; /*alkion luominen ei onnistunut */ s->key = c; lisaa_alkio(l,s); tulosta_lista(l); printf("\n"); } tulosta_lista(l); printf("\n"); kaanna(l); tulosta_lista(l); printf("\n"); return 1; } Arvostelusta: a) max 4p - alkio - lista b) max 4p - listan muodostus - tyyppien käyttö - oikeat arvot kenttiin - tilan varaus (malloc) ja onnistumisen varmistus 2p c) max 7p - listan käsittely ja listan linkkien käyttö 2 p - oikea logiikka 5 p - tyhjä lista (ja yhden alkion lista) 1p - kääntää listan 4 p - toimii oikein 3 p - toimii selkeästi 1p Jos käsitellyt listaa merkkijonona -6p ############################################################################# UK 18.8.2000 Tehtävä 4 1 #include 2 int longest(char **p, char *r) { 3 char *s,*t; 4 int max=0, len; 5 while(*p++) { 6 if len=strlen(*p)) > max ) { 7 max=len; 8 s=*p; 9 } 10 p++; 11 } 12 t=s; 13 while(*r++ = *s++); 14 r=t; 15 return s - t; 16 } 17 18 int main () { 19 int pit; 20 char pisin_rivi[80]; 21 static char *tptr[5] ={ 22 "Ensimmäinen rivi", 23 "Toinen rivi", 24 "Ja tässä kolmas rivi", 25 "Neljäs on riveistä kaikkein pisin", 26 "Viides ja viimeinen" 27 }; 28 char *pp; 29 pp=pisin_rivi; 30 pit= longest(tptr,pp); 31 printf("%d merkkiä: %s\n",pit, pp); 32 return 0; 33 } Käännettäessä gcc -Wall: varoitus sulkujen puuttumisesta rivillä 6 ja 13 (2p) t4.c:6: warning: suggest parentheses around assignment used as truth value t4.c:13: warning: suggest parentheses around assignment used as truth value Korjauksen jälkeen suoritus päättyi segmentation fault ilmoitukseen! Rivillä 5: while(*p++) => vain joka toinen rivi käsitellään. Pitäisi olla while(*p), sillä rivillä 10 kasvatetaan osoitinta. Tämä aiheuttaa myös segmentation fault -tilanteen. (3 p) Riveillä 12 ja 15 lasketaan merkkijonon pituus uudestaan, ihan turhaan sillä pituus on jo valmiina muuttujassa max. Lisäksi tässä pituudeksi tulee yhtä suurempi luku eli hiukan väärin. (2 p) Lisäksi puuttuu #include , vaikka käytetään strlen-funktiota. (1 p) Muista keksityistä virheistä menee miinuspisteitä! Toiminta ( max 7 p: pistemäärä riippuu siitä, miten toiminta on selvitetty): Pääohjelmassa on alustettu viisialkioinen merkkijonotaulukko, josta etsitään pisintä merkkijonoa funktion longest avulla ja lopuksi tulostetaan pisin merkkijono ja sen merkkien lukumäärä. ( => 3 p) Funktiolle longest annetaan parametreina osoitin merkkijonotaulukkoon ja toinen osoitin taulukkoon, johon löydetty pisin merkkijono kopioidaan. Funktio palauttaa merkkijonon pituuden. (=> 1 p) Longest-funktiossa 1. while -silmukassa käydään läpi saadun taulukon merkkijonot ja tutkitaan merkkien määrä strlen-funktiolla. Osoitin s osoittaa pisimman jonon ja max sen merkkimäärän. (1 p) Toinen while-silmukka kopioi pisimmän jonon parametrina ilmoitettuun taulukkoon. (1 p) Osoittimien asettelujen avulla lasketaan uudelleen pisimmän merkkijonon pituus. t=s; /*t osoittaa pisimmän merkkijonon alkuun*/ while((*r++=*s++)); /*s siirtyy osoittamaan merkkijonon ohi*/ return s-t-1; /*palauttaa kyllä merkkijonon pituuden*/ Tosin pituus on jo valmiiksi laskettuna muuttujassa max! (1 p)