Oppgaver uke 35: Oppgavene 1, 2, 4, 5, 6, 9, 12 og 13 passer best til å løses ved en datamaskin. Oppgave 1. Skriv et C-program som leser mål i tommer og skriver det ut i fot og tommer. (Det er 12 tommer i en fot.) Programmet skal avslutt når brukeren angir 0. Eksempel på kjøring: Oppgave 2. Tilordningen > tommer Gi et mål i tommer: 7 7 tommer er 0 fot og 7 tommer. Gi et nytt mål i tommer: 76 76 tommer er 6 fot og 4 tommer. Gi et nytt mål i tommer: 0 t = (time(null)/3600+2)%24; vil sette t til klokkeslettet, altså hvilken time det er på dagen (0-23). (Senere i kurset får vi forklaring på hvordan dette virker.) Ta utgangspunkt i «Hallo, alle sammen!»-programmet som ble vist på forelesningen 29.8. Modifisér dette slik at det skriver «God morgen, alle sammen!» klokken 6-9 «God dag, alle sammen!» klokken 10-17 «God kveld, alle sammen!» klokken 18-21 «God natt, alle sammen!» ellers. Oppgave 3. Programmet unsigned short a, b, sum; a = 20000; b = 50000; sum = a+b; printf("%d + %d = %d\n", a, b, sum); gir følgende resulat når det kjøres: 20000 + 50000 = 4464 Forklar hvorfor. Kan vi oppdage slike feil? Oppgave 4. C-programmet vist på foil 38 på onsdagens forelesning skriver egentlig 1
tabellen slik: 10: 32 ' ': 131 '!': 2 '"': 12 '#': 2 osv. (dvs. to rader nedover) Skriv om programmet slik at det skriver svaret i seks kolonner slik det ble vist på lysark 39. Oppgave 5. Gitt følgende program der funksjonen `strcatc' utvider teksten `s' med tegnet `c': #include <string.h> void strcatc (char s[], char c)... char teststr[20]; void test (char c) printf("før: \"%s\".", teststr); strcatc(teststr, c); printf("\tetter innsetting av '%c': \"%s\".\n", c, teststr); strcpy(teststr, ""); /* Initiering er nødvendig! */ test('a'); test('b'); test('c'); test('.'); test('.'); test('å'); Programmet sjekker om funksjonen virker ved å teste den på ulike data. Når programmet kjøres, skal det skrive: Før: "". Før: "a". Før: "ab". Før: "abc". Før: "abc.". Før: "abc..". Etter innsetting av 'a': "a". Etter innsetting av 'b': "ab". Etter innsetting av 'c': "abc". Etter innsetting av '.': "abc.". Etter innsetting av '.': "abc..". Etter innsetting av 'å': "abc..å". Skriv funksjonen `strcatc'. Hint Notasjonen «char s[]» angir at `s' er en char-vektor. Når en vektor overføres som parameter, trenger vi ikke angi antall elementer, men vi må ha med hakeparentesene slik at C-kompilatoren forstår at det er en vektor. 2
Oppgave 6. Skriv C-funksjonen char strgetc (char s[], int pos) som gir oss tegnet i posisjon nr `pos' i teksten `s'. (Første posisjon er nr 0, andre nr 1, osv.) Hvis det angitte tegnet ikke finnes i teksten, skal funksjonen returnere tegnet '?'. Skriv også et lite testprogram. Oppgave 7. Følgende program short a, b, sum; a = 20000; b = 20000; sum = a+b; printf("%d + %d = %d\n", a, b, sum); gir dette resultatet når det kjøres: 20000 + 20000 = -25536 Hvorfor skjer det? Oppgave 8. Skriv en test kan legges inn i programmet i forrige oppgave som skriver ut teksten «Overflyt!» om slikt skjer. Oppgave 9. Skriv en makro #define STREQ(s1,s2) som sjekker om de to tekstene er like. Tanken er at den kan brukes i if-tester: if (STREQ(s,"Abc"))... Oppgave 10. På forelesningen ble det vist en MIN-makro med mange parenteser: #define MIN(x,y) ((x)<(y)? (x) : (y)) Hvorfor er ikke definisjonen kun #define MIN(x,y) x<y? x : y? Med andre ord: finn C-uttrykk hvor den siste definisjonen vil gi et galt resultat. Oppgave 11. Dette programmet 3
char c[4]; short s; int i; s = 1; for (i = 4; i < 6; ++i) printf("c[%d] = %d\n", i, c[i]); gir følgende resultat når det kompileres og kjøres på en Sun-maskin: c[4] = 0 c[5] = 1 og følgende på en av våre Linux-maskiner med Intel-prosessor: c[4] = 1 c[5] = 0 Hva skyldes forskjellen? NB! Det er ikke spesifisert hvorledes C-variable skal legges i lageret. Dette programmet forusetter at de legges rett etter hverandre slik at c[4] og c[5] henter byte fra s. Slik gjøres det også for de angitt systemene, men det er ikke sikkert programmet vil virke om man endrer på det eller bruker en annen kompilator. Senere skal vi komme frem til en annen og bedre måte. Hint. Husk at vi har en byte-maskin. Hvordan ser minnet ut -- byte for byte -- der `c' og `s' er lagret? Oppgave 12. Skriv C-funksjonen int hexval (unsigned char c) som konverterer et hex-tegn ('0'-'9', 'a'-'f' eller 'A'-'F') til sin verdi 0-15. Vi kan anta at det alltid er et hex-tegn i c når funksjonen kalles. Her er et kort testprogram du kan bruke til å sjekke om funksjonen virker: int hexval (unsigned char c)... /* Også vektorer kan initialiseres! */ unsigned char ca[5] = '0', '4', 'A', 'b', 'f' ; 4
int i; for (i = 0; i < 5; ++i) printf("hexval('%c') gir %d\n", ca[i], hexval(ca[i])); Oppgave 13. Standardfunksjonen int strcmp (unsigned char s1[], unsigned char s2[]) sammenligner to tekster og returnerer en verdi som er <0 om s1 kommer før s2 =0 om s1 og s2 er like >0 om s1 kommer etter s2 Skriv `strcmpx' i C; den skal oppfører seg likt `strcmp'. Her er et testprogram: int strcmpx (unsigned char s1[], unsigned char s2[]) : void test (unsigned char s1[], unsigned char s2[]) printf("strcmpx(\"%s\", \"%s\") gir %d\n", s1, s2, strcmpx(s1,s2)); test("abc", "Ab"); test("abc", "Abc"); test("abc", "Abcd"); Oppgave 14. Spiller det noen rolle om parametrene er deklarert som «char», «signed char» eller «unsigned char»? 5