Programmeringsspråket C Del 2

Like dokumenter
Programmeringsspråket C Del 2

Programmeringsspråket C Del 2

Dagens tema. C-programmering. Nøkkelen til å forstå C-programmering ligger i å forstå hvordan minnet brukes.

Dagens tema. Kort repetisjon om rutiner. Programmering i C Variable og adresser. Vektorer. Tekster. Preprosessoren. Separat kompilering

Dagens tema INF2270. Cs preprosessor. Separat kompilering av C funksjoner. C og minnet. Dag Langmyhr,Ifi,UiO: Forelesning 5. februar 2007 Ark 1 av 15

Cs preprosessor. Dagens tema. Betinget kompilering

Programmeringsspråket C Del 2. Michael Welzl

Dagens tema. Rutiner i LC-2 Og her er tilsvarende kode for LC-2: Funksjoner i C Her er det samme programmet i C: Kort repetisjon om rutiner

Dagens tema INF1070. Vektorer (array er) Tekster (string er) Adresser og pekere. Dynamisk allokering

Dagens tema. C-programmering. Nøkkelen til å forstå C-programmering ligger i å forstå hvordan minnet brukes.

Vektorer. Dagens tema. Deklarasjon. Bruk

IN 147 Program og maskinvare

Dagens tema INF1070. Vektorer (array-er) Tekster (string-er) Adresser og pekere. Dynamisk allokering

Dagens tema. Cs preprosessor Separat kompilering av C-funksjoner C og minnet Oversikt over operatorene

Dagens tema C, adresser og pekere

Ark 3 av 26. printf("i adresse %08x ligger b med verdien %d.\n", &b, b); printf("i adresse %08x ligger a med verdien %d.

Programmeringsspråket C Del 3

Del 4 Noen spesielle C-elementer

Programmeringsspråket C Del 3

Dagens tema. Cs preprosessor Separat kompilering av C-funksjoner C og minnet Oversikt over operatorene

Programmeringsspråket C Del 3. Michael Welzl

Dagens tema INF1070. Info om C. Cs preprosessor. Feilsøking. Dag Langmyhr,Ifi,UiO: Forelesning 31. januar 2005 Ark 1 av 29

Informasjon om C. Dagens tema INF1070 INF1070 INF1070 INF1070. Den viktigste kilden til informasjon om C (utenom en god. C-funksjonene.

Programmeringsspråket C Del 3

Programmeringsspråket C Del 3

Dagens tema. Oppsummering om assemblerspråk. Programmering i C. Bakgrunn. Et minimalt eksempel med forklaring. Datatyper i C.

Del 1 En oversikt over C-programmering

Kapittel 1 En oversikt over C-språket

Programmeringsspråket C

IN 147 Program og maskinvare. Dagens tema

IN 147 Program og maskinvare

Repetisjon fra sist - 1: Plan for dagen. Repetisjon fra sist 2: Hva jeg glemte sist: Nyttige Kommandoer

IN 147 Program og maskinvare

Dagens tema. Adresser som parametre Dynamisk allokering Signaturer Definisjon av nye typenavn Typekonvertering Pekere og vektorer

Dagens tema INF1070. Signaturer. Typekonvertering. Pekere og vektorer. struct-er. Definisjon av nye typenavn. Lister

Hvordan en prosessor arbeider, del 1

Programmeringsspråket C

Nybegynnerkurs i C. Øyvind Grønnesby. 14. oktober Introduksjon Typer Operatorer Kontrollstrukturer Pekere Makroer Lenker

Programmeringsspråket C

Programmeringsspråket C Del 3. Hans Petter Taugbøl Kragset

Bakgrunnen for INF2100. Velkommen til INF2100. Prosjektet. Hva gjør en kompilator?

public static <returtype> navn_til_prosedyre(<parameter liste>) { // implementasjon av prosedyren

Oppgavene 1, 2, 4, 5, 6, 9, 12 og 13 passer best til å løses ved en datamaskin.

INF1000 (Uke 5) Mer om løkker, arrayer og metoder

IN 147 Program og maskinvare

Velkommen til INF2100

public static <returtype> navn_til_prosedyre(<parameter liste>) { // implementasjon av prosedyren

Signaturer. Dagens tema. En vanlig feil int-funksjon. Dette kan noen ganger gi rare feilmeldinger: INF1070 INF1070 INF1070 INF1070

Kjøresystemer. Hva er et kjøresystem? Den abstrakte maskinen SIMPLESEM (2.6) Klassifisering av språk: Parametre (2.7.7) Statiske språk (

Kort om meg. INF1000 Uke 2. Oversikt. Repetisjon - Introduksjon

Del 2 Tabeller, arrays, strenger

Dagens tema. Mer om C Enkle datatyper Sammensatte datatyper: Vektorer og matriser Tekster Mengder Strukturer Unioner Ringbuffere

ITGK - H2010, Matlab. Repetisjon

Dagens tema: Datastrukturer

Programmeringsspråket C Del 2. Hans Petter Taugbøl Kragset

Velkommen til INF2100 Jeg er Dag Langmyhr

INF1000 : Forelesning 4

i=0 i=1 Repetisjon: nesting av løkker INF1000 : Forelesning 4 Repetisjon: nesting av løkker Repetisjon: nesting av løkker j=0 j=1 j=2 j=3 j=4

Oversikt. Introduksjon Kildekode Kompilering Hello world Hello world med argumenter. 1 C programmering. 2 Funksjoner. 3 Datatyper. 4 Pekere og arrays

Oversikt. INF1000 Uke 1 time 2. Repetisjon - Introduksjon. Repetisjon - Program

Del 3. Pekere RR 2016

En oppsummering (og litt som står igjen)

i=0 Repetisjon: arrayer Forelesning inf Java 4 Repetisjon: nesting av løkker Repetisjon: nesting av løkker 0*0 0*2 0*3 0*1 0*4

Forelesning inf Java 4

Dagens tema: Enda mer MIPS maskinkode

Debugging. Tore Berg Hansen, TISIP

Pensum Hovedtanker Selvmodifiserende Overflyt Veien videre Eksamen. Oppsummering

Innhold uke 4. INF 1000 høsten 2011 Uke 4: 13. september. Deklarasjon av peker og opprettelse av arrayobjektet. Representasjon av array i Java

Dagens program. Operativsystemer Prosesser og systemkall i UNIX Hente prosessens nummer Starte prosesser Vente på prosesser Utføre programmer

Oversikt. INF1000 Uke 2. Repetisjon - Program. Repetisjon - Introduksjon

2 Om statiske variable/konstanter og statiske metoder.

Forelesning inf Java 5

Forelesning inf Java 5

INF 1000 høsten 2011 Uke september

Repetisjon: Statiske språk uten rekursive metoder (C1 og C2) Dagens tema Kjøresystemer (Ghezzi&Jazayeri 2.6, 2.7)

INF1000 undervisningen INF 1000 høsten 2011 Uke september

Dagens tema Kjøresystemer (Ghezzi&Jazayeri 2.6, 2.7)

Ark 1 av 18. programmeringsspråkenes. Velkommen til IN 211. verden. IN 211 Programmeringsspråk

Den siste dagen. Pensumoversikt Hovedtanker i kurset Selvmodifiserende kode Overflyt Veien videre... Eksamen

TDT4102 Prosedyre og Objektorientert programmering Vår 2015

Programmering i C++ Løsningsforslag Eksamen høsten 2005

<?php. count tar en array som argument, og returnerer et tall som uttrykker antallet innførsler i arrayen.

INF1000: noen avsluttende ord

Pekere og vektorer. Dagens tema. I C gjelder en litt uventet konvensjon:

Dagens tema. Det siste om C Pekere og vektorer. Pekere til pekere. Vanlige pekerfeil. struct-er og typedef. Lister. Feilsøking

OPPGAVE 1 OBLIGATORISKE OPPGAVER (OBLIG 1) (1) Uten å selv implementere og kjøre koden under, hva skriver koden ut til konsollen?

INF225 høsten 2003 Prosjekt del 4: kodegenerering

Pekere og referanser.

Praktisk informasjon. I dag. Repetisjon: While-løkker. INF1000 (Uke 5) Mer om løkker, arrayer og metoder

2. Pekere og referanser.

INF1000 EKSTRATILBUD. Stoff fra uke 1-5 (6) 3. oktober 2012 Siri Moe Jensen

Dagens tema: 12 gode råd for en kompilatorskriver

IN 147 Program og maskinvare

Dagens tema. Nyttige programmer Programmet make. Hvis én fil endres, hvilke filer må da kompileres på nytt?

Obligatorisk oppgave 1 INF1020 h2005

Semantikk. Dagens tema Kjøresystemer (Ghezzi&Jazayeri 2.6, 2.7) Semantikk. Semantikk. En måte å svare på: gi semantikken til språket!

Løse reelle problemer

Utførelse av programmer, metoder og synlighet av variabler i JSP

Transkript:

Programmeringsspråket C Del 2 Michael Welzl E-mail: michawe@ifi.uio.no 8/25/10 inf1060 1

Et eksempel Dette er lite eksempel som ber om et tall, leser det og så teller fra det ned til 0. 8/25/10 inf1060 2

8/25/10 inf1060 3

Forklaring: Definisjonspakker hentes inn med #include. Den vanligste er for lesing og skriving: #include <stdio.h> Det er mulig å definere konstanter med: #define STOP 0 (Mer om dette siden.) Man kan lese tall (og tegn eller ord) med scanf. Første parameter angir formatet (som for printf). Øvrige parametre gir variablene verdiene skal legges inn i. NB! Variablene må ha en & foran seg! (Forklaring kommer siden.) 8/25/10 inf1060 4

Forklaring (forts.): for-løkka benyttes til å utføre kode et fast antall ganger. Den litt eiendommelige syntaksen er egentlig en kortform for: Counter = startpoint; While (counter >= STOP) { printf( %d\n, counter); counter--; } Operatoren ++ brukes til å øke en variabel med 1. Om den står foran variabelen, foretas økningen før vi henter verdien. Tilsvarende brukes -- til å senke en variabel med 1. 8/25/10 inf1060 5

Nok et eksempel: Dette eksemplet gjør ikke noe fornuftig, men demonstrerer bruk av variable og operatorer i C. En kjøring ser slik ut: 8/25/10 inf1060 6

#include <stdio.h> int inglobal; /* Variable inglobal is a global variable */ /* because it is declared outside of all blocks */ Int main(void) { int inlocal; /* Variables inlocal, outlocala, outlocalb */ int outlocala; /* are all local to main */ int outlocalb; /* Initialize */ inlocal = 2; inglobal = 3; /* Perform calculations */ outlocala = inlocal++ & ~inglobal; outlocalb = (inlocal + inglobal) - (inlocal - inglobal); } /* Print out results */ printf("the results are : outlocala = %d, outlocalb = %d\n", outlocala, outlocalb); 8/25/10 inf1060 7

Funksjoner En funksjon (også kalt metode, prosedyre eller rutine) er en bit av programkoden som kan kalles fra andre steder. Under utførelsen hopper man da til funksjonen, utfører programkoden til funksjonen, og hopper så tilbake. 8/25/10 inf1060 8

En metode i Java: 8/25/10 inf1060 9

Her er det samme programmet som en funksjon i C: 8/25/10 inf1060 10

Funksjoner i C (forts.) Merk at i C kan man bare kalle funksjoner definert tidligere. Dette er ikke helt riktig, men en god regel for nybegynnere... 8/25/10 inf1060 11

Størrelser og adresser De fleste datamaskiner idag er byte-maskiner der man adresserer hver enkelt byte; char lagres i én byte. short lagres i to bytes. long lagres i fire bytes. Prosessorene har instruksjoner som kan hente et gitt antall bytes av gangen. Dette kalles bussbredden og er oftest 2, 4 eller 8 idag. En 64-bits prosessor kan hente 8 bytes av gangen. 8/25/10 inf1060 12

Byte-rekkefølgen Anta at vi har en 32-bits prosessor. Hvis et ord som inneholder 32-bit verdien 0x01020304 og lagres som; 01 02 03 04 kaller vi maskinen big-endian. Hvis det lagres som; 04 03 02 01 kalles den little-endian. 8/25/10 inf1060 13

Vektorer Alle programmeringsspråk har mulighet til å definere en såkalte vektor (også kalt matrise eller array på engelsk). Dette er en samling variable av samme type hvor man bruker en indeks til å skille dem. Deklarasjon: I C deklareres vektorer ved å sette antallet elementer i hakeparentes etter variabelnavnet char a,b[4],c; 8/25/10 inf1060 14

Bruk: 8/25/10 inf1060 15

Beregning av adresser Adressen til vanlige variable er kjent, men adressen til vektorelementer må beregnes. Formelen er Startadresse + Indeks x Størrelse Hva skjer med ulovlig indeks? I C sjekkes ikke indeksen. Dette gjør det mulig å ødelegge andre variable, kode eller i noen tilfelle hele systemet. Dette er ikke helt sant, men vi kan tro det er slik en stund. 8/25/10 inf1060 16

Tekster I C lagres tekster som tegnvektorer med en spesiell konvensjon: Etter siste tegn står en byte med verdien 0. Variable Når man deklarerer en tekstvariabel, må man angi hvor mange tegn det er plass til (samt plass til 0-byten). Tekstvariabel str har plass til 5 tegn. En byte med verdien 0 er ikke det samme som sifferet 0 ; det er representert av verdien 48. 8/25/10 inf1060 17

Kopiering av tekst Flytting av tekst skjer med standardfunksjonen strcpy: 8/25/10 inf1060 18

Andre tekstoperasjoner: strlen(str) beregner den nåværende lengden av teksten i str. (Dette gjør den ved å lete seg frem til 0-byten.) strcat(str1,str2) utvider teksten i str1 med den i str2. strcmp(str1,str2) sammenligner de to tekstene. Returverdien er < 0 om str1 < str2 0 om str1 = str2 > 0 om str1 > str2 sprintf(str, "... ", v1, v2,... ) fungerer som printf men resultatet legges i str i stedet for å skrives ut. 8/25/10 inf1060 19

Hva om teksten er for lang? Siden tekstvariable er vektorer, er det ingen sjekk på plassen. Det er derfor fullt mulig å ødelegge for seg selv (og noen ganger for andre). 8/25/10 inf1060 20

C s preprosessor Før selve kompileringen går C-kompilatoren gjennom koden med en preprosessor (som er programmet /usr/lib/cpp). Dette er en programmerbar tekstbehandler som gjør følgende: Hvis filen er angitt med spisse klammer (som for eksempel <stdio.h>), hentes filen fra området / usr/include. Ellers benyttes vanlig notasjon for filer. 8/25/10 inf1060 21

C s preprosessor (forts.) Av gammel tradisjon gis makroer navn med store bokstaver. (En makro er en navngitt programtekst. Når navnet brukes, blir det ekspandert, dvs erstattet av definisjonen. Dette er ren tekstbehandling uten noen forbindelse med programmeringsspråkets regler.) Benytter man makroer med parametre, bør disse settes i parenteser. Likeledes, hvis definisjonen er et uttrykk med flere symboler, bør det stå parenteser rundt hele uttrykket. 8/25/10 inf1060 22

C s preprosessor (forts.) Betinget kompilering. Her angis hvilke linjer som skal tas med i kompileringen og hvilke som skal utelates. Følgende direktiver finnes for betinget kompilering: #if Hvis uttrykket etterpå er noe annet enn 0, skal etterfølgende linjer tas med. Uttrykket kan ikke inneholde variable eller funksjoner. #ifdef Hvis symbolet er definert (med en #define), skal etterfølgende linjer tas med. #ifndef Motsatt av #ifdef. #else Skille mellom det som skal tas med og det som ikke skal tas med. #endif Slutt med betinget kompilering. 8/25/10 inf1060 23

Betinget kompilering 8/25/10 inf1060 24

Betinget kompilering (forts.) På denne måten er det mulig å ha flere versjoner av koden (for eksempel for flere maskin-typer) og så kontrollere dette utelukkende gjennom kompileringen. Fare med betinget kompilering Man kan risikere å ha kode som aldri har vært kompilert, og som kan inneholde de merkeligste feil. 8/25/10 inf1060 25

Separat kompilering I utgangspunktet er det ingen problem med separatkompilering i C; hver fil utgjør en enhet som kan kompileres for seg selv,uavhengig av alle andre filer i programmet. 8/25/10 inf1060 26

Separat kompilering; Eksempel 8/25/10 inf1060 27

Separat kompilering; Eksempel (forts) 8/25/10 inf1060 28

Definisjonsfiler Det er en fare for at funksjonssignaturer, strukturer, makroer, typer og andre elementer ikke blir skrevet likt i hver fil. Dette løses ved hjelp av definisjonsfiler ( header files ), hvis navn gjerne slutter med.h. 8/25/10 inf1060 29

Filen prog.c: Definisjonsfiler (forts.) Definisjonsfiler inneholder gjerne følgende: Makrodefinisjoner (#define) Typedefinisjoner (typedef, union, struct) Eksterne spesifikasjoner (extern) Funksjoner som extern int f(int, char); (Legg merke til semikolonet sist! Det betyr at funksjonen ikke defineres her, men et annet sted.) 8/25/10 inf1060 30

Utskrift Som nevnt brukes printf til utskrift. Første parameter er formatet, og det tolkes slik: Alle tegn unntatt % kopieres. Tegnkombinasjonen %... angir noe spesielt: %% setter inn et %-tegn %d setter inn et heltall hentet fra parameterlisten. %u setter inn et heltall uten fortegns-bit fra parameterlisten. %x setter inn et heltall (uten fortegns-bit), men skriver det på heksadesimal form. %o setter inn et heltall (uten fortegns-bit), men skriver det på oktal form. %f setter inn et flyt-tall. %c skriver ut et heltall tolket som et tegn. %s skriver ut en tekst fra en tekstvariabel. 8/25/10 inf1060 31

Et eksempel: 8/25/10 inf1060 32

Lesing fra fil: Man må gjøre følgende når man skal lese fra fil: Deklarere fil-variabelen som FILE *. Åpne filen med funksjonen fopen med filnavn og r (for read ) som parametre. Hvis filen ikke finnes, returneres NULL. Lese fra filen med fscanf (som virker som scanf) eller fgetc (som leser ett og ett tegn). Lukke filen med fclose. 8/25/10 inf1060 33

Et eksempel: 8/25/10 inf1060 34

Skriving til fil: Skriving til fil er tilsvarende lesing fra fil. Man må gjøre følgende: Deklarere fil-variabelen som FILE*. Åpne filen med funksjonen fopen med filnavn og w (for write ) som parameter. Lag en ny file hvis den ikke finnes allerede! Hvis filen ikke lar seg åpne, returneres NULL. Skrive til filen med fprintf (som virker som printf). Lukke filen med fclose. 8/25/10 inf1060 35

Et eksempel: 8/25/10 inf1060 36

Et eksempel (forts.) Utskrift i faste kolonner: Ved å angi et tall i formatet (som i %2d) får vi printf til å sette av minst så mange posisjoner til tallet. 8/25/10 inf1060 37

Nok et eksempel: Dette programmet leser en fil min.fil tegn for tegn. Så skriver det ut hvor mange forekomster det er av hvert tegn. 8/25/10 inf1060 38

Bruker vi programmet på seg selv, får vi følgende resultat: 8/25/10 inf1060 39

Adresser Som nevnt tidligere, ligger data og programkode lagret i minnet (gjerne kalt RAM for Random Access Memory. Et slikt minne er typisk for dagens maskiner, og er gjerne byte-adressert med f.eks. 32 bits adresser. 8/25/10 inf1060 40

Operatoren & I C kan man få vite i hvilken adresse en variabel ligger ved å bruke operatoren &. 8/25/10 inf1060 41

La oss kjøre dette programmet: NB! Det kan variere fra gang til gang hvilke adresser man får. Her ser vi at variablene ligger pent etter hverandre og at hver av dem opptar 4 bytes. 8/25/10 inf1060 42

Pekervariable I C kan vi legge adresser i variable; disse deklareres med en stjerne: Her er v en vanlig variabel mens p er en peker som kan peke på int-variable. (Vi må alltid oppgi hva slags variable pekere skal peke på.) Bruk av pekervariable: Vi kan sette adressen til variable inn i pekervariabelen; Vi sier at vi får pekeren til å peke på variabelen. 8/25/10 inf1060 43

Bruk av pekervariable (forts.) Vi kan følge en peker ved å bruke operatoren *; da får vi variabelen som pekeren peker på. Denne koden skriver ut: Både v og *p angir altså samme variabel: Utskriften av denne koden er: 8/25/10 inf1060 44

Eksempel: La oss lage en funksjon som bytter om de to parametrene sine. Til selve ombyttingen trengs en hjelpevariabel: 8/25/10 inf1060 45

Vi skriver følgende program: 8/25/10 inf1060 46

Når vi kjører programmet, får vi en overraskelse: Grunnen er: Parametre overføres som verdier i C (som i Java). Systemet tar altså en kopi av parameterverdien og legger denne i et register (eller et annet sted for parametre). Følgelig er det bare lokale kopier som endres. Når funksjonen er ferdig, er alt glemt! 8/25/10 inf1060 47

Løsning: Løsningen er å overføre pekere til de to variablene i steden for verdiene. Pekerne overføres som kopier, men vi kan allikevel endre det de peker på. 8/25/10 inf1060 48

Et program som fungerer vil være som følger: 8/25/10 inf1060 49

Eksempel (forts.) Legg merke til at både funksjonsdeklarasjonen og kallet er endret! Når dette programmet kjører, skjer alt som vi forventer: 8/25/10 inf1060 50

Konklusjon om parametre: Det er ulike måter å overføre parametre på. I C og i Java brukes verdioverføring. Man kan allikevel oppdatere variable ved å sende over pekere til dem. Dette gjøres for eksempel i scanf( %d, &v); 8/25/10 inf1060 51