HI1024 Programmering, grundkurs TEN2 2014-01-08 KTH STH Haninge 8.15-13.00 Tillåtna hjälpmedel: En A4 handskriven på ena sidan med egna anteckningar Kursboken ”C PROGRAMMING A Modern Approach” K. N. King – helt utan anteckningar Logga in med tentamenskontot ni får av skrivvakten. Det kommer att ta tid att logga in – ha tålamod! Logga inte ut förrän ni är klara med hela tentan. Svaren på uppgifterna ska vara program bestående av en fil som kallas uppg1.c, uppg2.c, uppg3.c, uppg4.c och uppg5.c. Dessa ska sparas direkt under H:. Även om ni inte löser hela uppgiften så kan ni få delpoäng men ni måste se till att koden kompilerar och kan köras. Både output och koden bedöms och det är viktigt att denna är välskriven och uppfyller uppgiftens instruktioner. Välj bra variabelnamn och struktur men lägg inte så stor vikt vid kommentarer. Kom ihåg ert tentamenskonto. Resultaten kommer att presenteras kopplade till dessa! Lycka till Examinator: Nicklas Brandefelt Rättande lärare: Nicklas Brandefelt, Fredrik Bergholm Betygsgränser: Fx-8, E-9, D-11, C-12, B-14, A-16 (MAX-18) Generella rättningsnormer: Mycket dåliga variabelnamn ger -1p totalt på provet vid andra tillfället Inga eller dåliga kommentarer ger -0p på provet Dålig struktur ger avdrag varje gång Generellt gäller: -1p per avvikelse, minst -1p om koden ej kompilerar 1. En lek med vanliga heltal (4p) Vi skapar en följd av heltal på följande sätt: Välj ett tal. Om talet är jämnt dividera med 2, annars multiplicera med 3 och lägg till 1. Gör nu likadant med resultatet. Fortsätt tills du får 1. Exempel: Välj 3 Udda så: 3∙3 + 1 = 10 Jämnt så: 10/2 = 5 Udda så: 3∙5 + 1 = 16 Jämnt så: 16/2 = 8 Jämnt så 8/2 = 4 Jämnt så 4/2 = 2 Jämnt så 2/2 = 1 klar i 7 steg Skriv ett program som tar in ett positivt heltal från användaren och anger hur många steg (enligt ovanstående process) som behövs för att komma till 1. Programmet ger användaren möjlighet att mata in nya tal till dess att denne matar in 0. En körning skall se ut enligt nedan: Tal: 1 Steg: 0. Tal: 2 Steg: 1. Tal: 3 Steg: 7. Tal: 4 Steg: 2. Tal: 5 Steg: 5. Tal: 6 Steg: 8. Tal: 7 Steg: 16. Tal: 8 Steg: 3. Tal: 0 Lösning: #include <stdio.h> int main() { int tal, n; do { n=0; printf("Tal: "); scanf("%d",&tal); if(tal!=0) { while(tal!=1) { if(tal%2==0) tal/=2; else tal=3*tal+1; n++; } printf("Steg: %d\n", n); } }while(tal!=0); return 0; } 2. Par av heltal (4p) Skriv ett program som slumpar en lista på ett antal par av positiva heltal mellan 1 och 10. Användaren ska ange hur många par av tal som ska slumpas fram. Talparen ska sedan lagras i en array av structar av typen struct talpar { int n,m; } och arrayen ska sedan sorteras med avseende på summan av de båda talen som ingår i varje talpar. Vi kan tänka oss att programmet hanterar max 10 par av heltal. Interaktionen med användaren ska vara av följande typ: Antal talpar (max 10): 4 Resultat: ==================== Talpar 1: (3,2) Talpar 2: (1,6) Talpar 3: (3,4) Talpar 4: (6,7) <-- Användaren matar in detta Lösning: #include <stdio.h> #include <stdlib.h> #include <time.h> struct talpar { int n,m; }; int main() { int i, j, antal; struct talpar talparen[10], ettpar; srand(time(0)); printf("Antal talpar (max 10): "); scanf("%d", &antal); for(i=0;i<antal;i++) { talparen[i].n=rand()%10+1; talparen[i].m=rand()%10+1; } for(i=0;i<antal;i++)for(j=0;j<i;j++) { if( talparen[j].n+talparen[j].m > talparen[i].n+talparen[i].m ) { ettpar = talparen[i]; talparen[i]=talparen[j]; talparen[j] = ettpar; } } printf("Resultat:\n===================\n"); for(i=0;i<antal;i++) printf("Talpar %d: (%d,%d)\n", i+1, talparen[i].n, talparen[i].m); return 0; } 3. Formatering av namn (4p) Det finns två omvandlingsfunktioner som omvandlar mellan stora och små bokstäver, de heter toupper() respektive tolower(). Funktionen toupper() omvandlar bokstäver till stora genom att returnera ett heltal som kan tolkas som en stor bokstav, den fullständiga funktionsprototypen är int toupper(int c); och ett anrop kan vara printf(“%c”, toupper('a')); som alltså skulle resultera i utskriften av ett stort A. Funktionen tolower() fungerar på motsvarande sätt. Dessa funktioner finns i ctype.h som behöver inkluderas. Använd dessa funktioner för att formatera namnuppgifter. Ditt program ska ta ett namn som består av ett antal bokstäver (ett förnamn) följt av exakt ett mellanslag följt av ytterligare ett antal bokstäver (ett efternamn). Programmet ska se till att begynnelsebokstäverna är stora och alla andra är små. En provkörning ska se ut enligt nedan: Namn: jOHnny pAnRIKE Formaterat namn: Johnny Panrike Vi antar att programmet inte behandlar å, ä eller ö. (Och inte heller Å, Ä eller Ö.) Vidare antar vi också att ett namn har formen av två sammanhängande ord separerat av precis ett mellanslag (namn som “Karl Erik Jonsson” räknas alltså inte). Programmet skall använda funktioner på ett bra sätt och får inte använda globala variabler. Lösning: #include <stdio.h> #include <string.h> #include <ctype.h> int make_all_small(char namn[]) { int i=0; while(namn[i]) namn[i]=tolower(namn[i++]); } int do_capitals(char namn[]) { int i=0; while(namn[i++]!=' '); namn[i]=toupper(namn[i]); namn[0]=toupper(namn[0]); } int main() { char namn[30]; printf("Namn: "); gets(namn); make_all_small(namn); do_capitals(namn); printf("Namn: %s.\n", namn); return 0; } 4. Ett ofullständigt program (4p) Studera följande program: #include <stdio.h> #include <string.h> #define MAX 10 struct person { char namn[10]; int alder; } main() //Huvudprogram, får inte ändras { struct person personer[MAX]; int antal; matain(personer, &antal); sortera(personer, antal); skrivut(personer, antal); } Skriv funktionerna matain(), sortera() och skrivut() så att programmet fungerar på följande sätt: först tar det in en lista på ett antal personer, sedan sorteras dessa på ålder (med yngsta först). Vi kan anta att namn endast bildas av små bokstäver från a till z. Ett exempel på en körning (det användaren matar in visas i fet stil): Mata in personuppgifter (avsluta med ålder = 0.) Ålder: 10 Namn: kalle Ålder: 8 Namn: olle Ålder: 10 Namn: olle Ålder: 9 Namn: kalle Ålder: 11 Namn: lisa Ålder: 10 Namn: anders Ålder: 0 Resultat: olle, 8 kalle, 9 kalle, 10 anders, 10 lisa, 11 Du får absolut inte införa globala variabler i programmet eller ändra i huvudprogrammet. Det enda du får göra är att lägga till de tre funktionerna som ska fungera med exakt de anrop som finns i huvudprogrammet. Lösning: #include <stdio.h> #include <string.h> #define MAX 10 struct person { char namn[10]; int alder; }; void matain(struct person personer[], int *antal) { *antal = 0; struct person bufp; char bufs[2]; printf("Mata in personuppgifter (avsluta med alder = 0.)\n\n"); do { printf("Alder: "); scanf("%d", &(bufp.alder) ); if(bufp.alder==0)return; gets(bufs); printf("Namn: "); gets(bufp.namn); personer[*antal] = bufp; (*antal)++; printf("\n"); } while(*antal<MAX); } void sortera(struct person personer[], int antal) { int i, j; struct person bufp; for(i=0;i<antal;i++)for(j=i+1;j<antal;j++) { if(personer[j].alder<personer[i].alder) { bufp=personer[i]; personer[i]=personer[j]; personer[j]=bufp; } } } void skrivut(struct person personer[], int antal) { int i=0; printf("\nResultat:\n\n"); for(i=0;i<antal;i++) printf("%s, %d\n",personer[i].namn, personer[i].alder ); } main() //Huvudprogram, får inte ändras { struct person personer[MAX]; int antal; matain(personer, &antal); sortera(personer, antal); skrivut(personer, antal); } 5. Addition av stora tal (2p) I denna uppgift skall du skriva ett program som låter användaren addera stora heltal och presenterar resultatet. Talen skall kunna innehålla upp till 1000 siffror. Resultatet i en beräkning ska användas i nästa beräkning. Programmet fortsätter till dess att användaren matar in 0. En körning ska se ut enligt nedan: Tal 1: 100000000000000000000000000089002 Tal 2: 304000000000000000000000000000321009 Resultat: 304100000000000000000000000000410011 Tal 2: 10002 Resultat: 304100000000000000000000000000420013 Tal 2:0 Avslutar Lösning: #include <stdio.h> #include <string.h> #define MAX 10000 int main(){ char tal1[MAX],tal2[MAX],resultat[MAX]; printf("Tal 1: "); fgets(tal1,sizeof(tal1),stdin); tal1[strlen(tal1)-1]=0; while(1){ printf("Tal 2: "); fgets(tal2,sizeof(tal2),stdin); if(tal2[0]=='0') break; tal2[strlen(tal2)-1]=0; int aktuellSiffra1,aktuellSiffra2,minne=0,aktuellRes=0,delresultat; aktuellSiffra1=strlen(tal1)-1; aktuellSiffra2=strlen(tal2)-1; while(aktuellSiffra1!=-1&&aktuellSiffra2!=-1){ delresultat=minne+(tal1[aktuellSiffra1]-'0')+(tal2[aktuellSiffra2]-'0'); resultat[aktuellRes]='0'+delresultat%10; minne=delresultat/10; aktuellSiffra1--; aktuellSiffra2--; aktuellRes++; } while(aktuellSiffra1!=-1){ delresultat=minne+(tal1[aktuellSiffra1]-'0'); resultat[aktuellRes]='0'+delresultat%10; minne=delresultat/10; aktuellSiffra1--; aktuellRes++; } while(aktuellSiffra2!=-1){ delresultat=minne+(tal2[aktuellSiffra2]-'0'); resultat[aktuellRes]='0'+delresultat%10; minne=delresultat/10; aktuellSiffra2--; aktuellRes++; } resultat[aktuellRes]='\0'; int i,j=0; for(i=strlen(resultat)-1;i>-1;i--) tal1[j++]=resultat[i]; tal1[j]='\0'; printf("Resultat: %s\n",tal1); } printf("Avslutar"); return 0; }