Dagens tema Mer om C Enkle datatyper Sammensatte datatyper: Vektorer og matriser Tekster Mengder Strukturer Unioner Ringbuffere Formål: Nyttige å bruke under programmeringen Trening i programmering i C og assemblerspråk Ark 1 av 19 Forelesning 17.2.1998
Enkle datatyper Tall Heltall og flyt-tall finnes ulike størrelser: % more size.c #include <stdio.h> int main(void) { printf("sizeof(char): %d\n", sizeof(char)); printf("sizeof(short): %d\n", sizeof(short)); printf("sizeof(int): %d\n", sizeof(int)); printf("sizeof(long): %d\n", sizeof(long)); printf("sizeof(float): %d\n", sizeof(float)); printf("sizeof(double): %d\n", sizeof(double)); } % a.out sizeof(char): 1 sizeof(short): 2 sizeof(int): 4 sizeof(long): 4 sizeof(float): 4 sizeof(double): 8 Det eneste C lover er: sizeof(char) 1 sizeof(short) 2 sizeof(long) 4 sizeof(char) sizeof(short) sizeof(int) sizeof(long) Forelesning 17.2.1998 Ark 2 av 19
Fortegns-bit Typene short, int og long er alle heltall med fortegns-bit. Man kan sette signed foran, men dette er overflødig. Disse typene har også en variant uten fortegns-bit: unsigned short, unsigned int og unsigned long. Typen char er signed eller unsigned, så her må man angi hva man ønsker hvis dette er viktig. Heltallskonstanter Man kan angi hvilken type en konstant skal være de få gangene dette er viktig: 123 er int (eller long int eller unsigned long) 123L er long int (eller unsigned long) 123U er unsigned int (eller unsigned long) 123UL er unsigned long Forelesning 17.2.1998 Ark 3 av 19
Heltallsvariable i assemblerspråk I MIPS assemblerspråk setter man av plass til variable med.word eller.byte: Var1:.word 122 B1:.byte 65 Bruk av riktig instruksjon (byte/halvord/ord og med/uten fortegnsbit) er programmererens ansvar. Ofte benyttes bare ett adresseregister til å peke på en samling variable. De enkelte variable aksesseres via et fast tillegg: la $t0,var1 lb $t1,4($t0) # Hent B1, addi $t1,$t1,1 # øk med 1, og sb $t1,4($t0) # legg tilbake. Alternativt kan man legge lokale variable på stakken. Fordel: Variabelen opptar kun plass når den brukes. Ulempe: Programmereren kan gå i surr med bruk av $sp-registeret. (Ofte brukes $fp-registeret ($30) til å peke på de lokale variable. Vi vil ikke bruke $fp i dette kurset.) Forelesning 17.2.1998 Ark 4 av 19
Andre enkle datatyper Tegn Finnes ikke; bruk unsigned char siden vi i Norge bruker 8-bits tegnsett. Men: Ved innlesning bruk int siden EOF er 1. Logisk (Boolean) Finnes ikke; bruk char. I tester sjekke det om verdien er 0 (som angir FALSE) og 0 (som regnes som TRUE). Følgende to tester er derfor ekvivalente: while (n!= 0)... while (n)... Flyt-tall Omtales senere i kurset. Tekst Omtales senere i dag. Pekere Omtales neste uke. Forelesning 17.2.1998 Ark 5 av 19
Matriser Vektorer (én-dimensjonale matriser) C FORTRAN Pascal Simula Lagring int A[12]; INTEGER A(12) var A: array [10..21] of Integer; integer array A(10:21); short int Arr[6] = {1, 1, 2, 3, 5, 8}; I C: Generelt:. A10A 8 5 A108 5 4 A106 3 3 A104 2 2 A102 1 1 A100 1. 0 Arr + I S Arr + (I L) S Forelesning 17.2.1998 Ark 6 av 19
Indeksering # Kode: Henter et element i vektoren «Vektor». # Registre: $8: Indeksen (i området 1 til 10). # $9: Elementet. # Spesielt: Vektor er deklarert med noe à la # Vektor: array [1:10] of Short; (Pascal). addi $8,$8,-1 # Kompensér for nedre grense. add $8,$8,$8 # Doble, pga 2 byte/element. la $9,Vektor # Hent adressen til Vektor. add $8,$8,$9 # Legg til 2 indeks. lh $9,0($8) # Hent elementet. Forelesning 17.2.1998 Ark 7 av 19
To-dimensjonale matriser I Simula: integer array Arr2(1:3,1:2); hvor hver integer opptar 4 byte. Disse lagres radvis i de fleste programmeringsspråk. Generelt:. A114 (3,2) A110 (3,1) A10C (2,2) A108 (2,1) A104 (1,2) A100. (1,1) Arr2 + ((I 1 L 1 ) D 2 + (I 2 L 2 )) S der D i er U i L i + 1. I C: long int Arr2[3][2]; Arr2 + (I 1 D 2 + I 2 ) S I FORTRAN lagres matriser kolonnevis. Forelesning 17.2.1998 Ark 8 av 19
Eksempel: I Simula: integer array Arr2(1:3,1:2); Hvor ligger Arr2(3,1)? Arr2 + ((3 1) D 2 + (1 1)) 4 = Arr2 + (2 (2 1 + 1) + 0) 4 = Arr2 + (2 2) 4 = Arr2 + 16 = A100 hex + 16 = A110 hex Forelesning 17.2.1998 Ark 9 av 19
Tekster En tekst må lagres som en vektor, og det er flere måter å angi lengden på: Avslutningstegn: H a l l o! 0 Viktigste fordel: Vilkårlig lange tekster kan lagres. Denne teknikken brukes i C. Avslutningstegnet skrives som \0. Lengdeangivelse: 6 H a l l o! Viktigste fordeler: Alle tegn kan lagres. Lett å finne siste tegn i teksten. Denne teknikken brukes i Pascal og Simula. Forelesning 17.2.1998 Ark 10 av 19
Hvordan oppstår tekster? I C og assemblerspråk oppstår ikke objekter med tekster så automatiske som i for eksempel Simula. De kan faktisk kun oppstå på tre måter: Som programkonstanter: printf("hallo!"); /* i C */ t_var:.asciiz "Hallo!" # I ass.språk Som tegnvektorer: unsigned char melding[200]; melding:.space 200 Ved eksplisitt allokering: unsigned char *p; /* «p» er en peker. */ p = (unsigned char*)malloc(20); strcpy(p, "Hallo!"); Forelesning 17.2.1998 Ark 11 av 19
Operasjoner på tekster I C benyttes egne funksjoner for alle operasjonene på tekster. De vanligste er: strcpy(a,b) kopierer teksten b til a. strcat(a,b) utvider a med innholdet av b. strlen(a) beregner antall tegn i a. strcmp(a,b) sammenligner tekstene a og b. < 0 hvis a<b Svaret er 0 hvis a=b > 0 hvis a>b Det er programmererens ansvar at det er plass i den teksten som endres ved strcpy, strcat eller lignende. Forelesning 17.2.1998 Ark 12 av 19
Mengder På en tippekupong kan man velge mellom tre tips: H, U og B. Man kan imdlertid gardere: HU, HB, UB eller HUB. I alt finnes det 8 verdier i mengden over mulige tips i hver kamp: {}, {H}, {U}, {B}, {H, U}, {H, B}, {U, B} og {H, U, B}. En slik verdi kan lagres som et bit-mønster med 3 bit: H U B {H, B} x x x x x 1 0 1 Forelesning 17.2.1998 Ark 13 av 19
Operasjoner på mengder Det fine med denne representasjonen, er at maske-operasjonene fungerer: Snitt ({H, B} {H, U} = {H}) kan implementeres som and. Union ({H, B} {H, U} = {H, U, B}) kan implementeres som or. Differanse ({H, B}\{H, U} = {B}) kan implementeres som and og not. Til å test om et element er med i en mengde, må man bruke and og kanskje sll. Forelesning 17.2.1998 Ark 14 av 19
Strukturer Strukturer kan sammenlignes med enkle Simula-klasser. I C ser de slik ut: struct punkt{ long xpos, ypos; char merke; short status; } origo;. struct punkt p1, p2;. p1.xpos = 0; p1.ypos = 7; p1.merke = A ; ++p1.status; I assemblerspråk: p1:.space 12 # struct punkt p1; p2:.space. 12 # struct punkt p2; la $8,p1 # Adressen til «p1». sw $0,0($8) # p1.xpos = 0; li $9,7 # 7; sw $9,4($8) # p1.ypos= li $9,65 # A ; sb $9,8($8) # p1.merke= lh $9,10($8) # p1.status addi $9,$9,1 # +1; sh $9,10($8) # p1.status= Legg merke til instruksjonene lh, sh og sb. Legg også merke til at p1.status har tillegg 10 og ikke 9 på grunn av lagertilpasning. Forelesning 17.2.1998 Ark 15 av 19
Unioner I en union lagres verdiene «oppå» hverandre. Deklarasjonen i C ser slik ut: union fortegn { long med_fort; unsigned long uten_fort; unsigned char byte[4]; } x; Eksempler på bruk: x.med_fort = -2; a[0] = x.byte[0]; a[2] = x.byte[2]; a[1] = x.byte[1]; a[3] = x.byte[3]; Bruksområder Omgå type-definisjoner Strukturer med variabel del Forelesning 17.2.1998 Ark 16 av 19
Ringbuffere Ringbuffere brukes til å implementere køer («FIFO-lister»). Ingen høynivåspråk har noen tilsvarende struktur. Ut Inn Pekerne forteller hvor neste element skal inn, og hvor man kan finne neste element som skal ut. Forelesning 17.2.1998 Ark 17 av 19
Implementasjon En ringbuffer implementeres å «klippe den opp» og lagre den i en vektor: Ut xx xx xx xx xx xx Inn Deklarasjon i C #define BUFFSIZ 12 int ringb[buffsiz], innp = 0, utp = 0, ant_e = 0; Forelesning 17.2.1998 Ark 18 av 19
Innsetting i ringbuffer int put(int x) { if (ant_e == BUFFSIZ) return 0; } ant_e++; ringb[innp] = x; innp++; if (innp >= BUFFSIZ) innp = 0; return 1; Henting fra ringbuffer int get(void) { int x; if (ant_e == 0) return -1; } ant_e--; x = ringb[utp]; utp++; if (utp >= BUFSIZE) utp = 0; return x; Forelesning 17.2.1998 Ark 19 av 19