Översiktskurs – föreläsning 3
• För en vecka sedan: Problemlösning, sortering, kursen,
flödesschema, lösningsmetoder, vikten av noggrann beskrivning av saker när man gör saker med datorer, sova
• Förra gången: flödesscheman, uttryck, prioritetsordningar,
• Förra gången: flödesscheman, uttryck, prioritetsordningar, iterationer, exempel, variabler
• Idag: Skall vi fortsätta med
– översätta flödesscheman till C-kod
– skriva och köra våra första C-program
Flödesschema - övningar
• Konstruera ett flödesschema som läser in ett tal och frågar efter ett nytt tal så länge talet ligger utanför intervallet 5 till 10
• Konstruera ett flödesschema som läser in ett tal N och skriver ut sekvensen
1 2 3 4 5 … (N-1) N
• Konstruera ett flödesschema som beräknar N! (dvs N fakultet = 1*2*3*4*…*(N-1)*N )
1*2*3*4*…*(N-1)*N )
Koppling till C
• int main(void)
• scanf(”%d”,&a);
• if(a>0){
//True-block }
else{
Start
Läs in a
a>0 True
False
else{
//False-block }
• printf(”%d”,a);
• a=a+1;
• return(0);
Grundläggande
programmeringsteknik
Skriv ut a
a = a+1
Stop
Variabler
• Värden som behövs i uträkningar, för att hålla koll på saker etc lagras i variabler
• En variabel kan förstås som en låda i minnet med en speciell position (adress), ett namn samt en storlek (typ)
• Vi kan använda tecknen ”a”-”z”, ”A”-”Z”, ”0”-”9”, samt ”_” i våra variabelnamn, men de får inte börja med en siffra
• Variabelnamn kan vara godtyckligt långa, men bara de 31 första
• Variabelnamn kan vara godtyckligt långa, men bara de 31 första tecknen ”räknas”
Variabler
• Vi måste tydligt tala om vilka variabler vi vill använda – innan de används första gången
– detta kallas att man deklarerar variablerna
• Vi måste också vara tydliga med vilken typ av data variabeln skall innehålla
– dels för att datorn skall vet hur stor plats det tar
– dels för att datorn skall veta vad man kan göra med data som lagrats i variabeln
• I C skiljer man på heltal, decimaltal, bokstäver, strängar etc
Grundläggande
programmeringsteknik
Block
• För att skilja på olika
instruktioner från varandra används semikolon ;
• Radbrytningar efter
instruktioner och kommandon fyller egentligen ingen funktion
• Likaså betyder mellanslag eller
• För att visa att vissa
instruktioner skall hänga ihop och ses som en enhet
grupperas dessa mellan { och }
• En sådan enhet kallas för ett block
• Likaså betyder mellanslag eller tabbar innan en instruktion
eller kommando ingenting
block
• Ett block kan i sin tur innehålla block som kan innehålla block osv.
• Ordningen på instruktionerna inom ett block är oftast
Koppling till C
• Sekvenser uttrycks alltså genom att rada upp semikolonseparerade instruktioner i block
• Val uttrycks med hjälp av if-satser som styr programflödet till olika block
• Hur kan vi uttrycka iterationer?
Grundläggande
programmeringsteknik
Koppling till C
• do{
//LOOP1-block
Start
LOOP1
//LOOP1-block } while(villkor)
Stop
villkor
s f
Koppling till C
• while(villkor){
Start
LOOP1
• while(villkor){
//LOOP1-block }
Grundläggande
programmeringsteknik
Stop
villkor
true false
Koppling till C
• for(i=0;i<N;i=i+1){
//LOOP1-block
Start
i=0
i=i+1
//LOOP1-block }
Stop i<N
LOOP1 t f
Iterationer
• do-while används när vi garanterat vill utföra blocket en gång innan iterationsvillkoret testas
– Loopblocket kommer att utförs 1 eller 2 eller … gånger
• while används när vi vill testa iterationsvillkoret innan blocket utförs
– Loopblocket kommer att utföras 0 eller 1 eller … gånger
• for används när vi i förväg vet hur många iterationer vi vill utföra – Loopblocket kommer att utföras N gånger
• För alla typer av iterationer måste vi övertyga oss om att iterationen kommer att avslutas (terminera)
Grundläggande
programmeringsteknik
Programmering
• Att programmera innebär att vi
– översätter (implementerar) en konstruerad lösning till ett programmeringsspråk
– översätter implementationen (kompilerar) till ett körbart program
– hittar och eliminerar olika fel i vårt program
Programvaruutveckling
Problem
Lösning på problemet
(algoritm)
Grundläggande
programmeringsteknik
(algoritm)
Datorvänlig variant av lösningen
Användning av lösningen Förståelse
av problemet
Programvaruutveckling
Programmeringsspråket C
• Utvecklat 1972 av Dennis Ritchie för att användas tillsammans med UNIX
• C är ett imperativt språk
• C översätts lätt till assembler och maskinkods- instruktioner
• C kan kompileras med en relativt enkel kompilator
• I C har programmeraren möjlighet att komma åt minne och andra enheter på datorn direkt
• Program skrivna i C behöver därför lite exekveringsstöd från operativsystemet vid körning
• C ersatte i mångt och mycket program skrivna i assembler
Grundläggande
programmeringsteknik
En liten ordlista
• Operativsystem – Ett program som sköter administrativa uppgifter på en dator, som att hålla reda på filer och program, resurser och användare.
• UNIX – ett exempel på ett operativsystem som kan hantera flera användare och flera program
• Imperativt – Att programmeringen bygger på att stegvis instruera datorn vad som skall göras
datorn vad som skall göras
• Maskinkod – Det språk som datorn verkligen ”förstår”
• Assembler – Representation av maskinkod i lite mer naturligt språk
• Kompilera – Att översätta från programmeringsspråk till maskinkod
• Minne – Där datorn sparar undan data
Vårt första C-program
• Arbeta fram en arbetsplan för lösningen
• Skriv med fördel programmet i en utvecklingsmiljö, dvs
kombinerad textbehandlare (editor) och kompilator. Tex Dev-C++
• Spara programfilen med ett beskrivande namn och avsluta namnet med .c
– uppg_1-1.c ett bra namn för lösningen till uppgift 1-1
• Kompilera programmet
• Korrigera eventuella kompilatorfel och kompilera om
• Kör programmet och verifiera att det gör det du tänkt
Grundläggande
programmeringsteknik
Våra första C-program
• Skriv ett program som skriver ut ”Hejsan svejsan” på skärmen
• Skriv ett program som frågar efter två tal och skriver ut summan av dem på skärmen
• Skriv ett program som frågar efter spänningen (U) över en last och strömstyrkan (I) genom lasten och beräknar lastens resistans (R) och skriver ut denna. Kom ihåg Ohms lag: U=R*I
Utmatning från enkla program
• Utskrift till skärmen sker med printf
– printf(”Hejsan Svejsan”); -> Hejsan Svejsan
• Printf arbetar med en formateringsträng på följande sätt
– printf(”Hejsan Svejsan\n”); -> Hejsan Svejsan [ny rad]
– printf(”Hejsan %s”,”Svejsan”); -> Hejsan Svejsan – printf(”Hejsan %s”,”Svejsan”); -> Hejsan Svejsan – printf(”Hejsan nummer %d”,2); -> Hejsan nummer 2 – printf(”Tal %d och %d”,3,2); -> Tal 3 och 2
– printf(”Tjo%s på alla %d:or”,”flöjt”,1); -> Tjoflöjt på alla 1:or
Grundläggande
programmeringsteknik
• Formatsträngen till printf kan innehålla styrkoder:
– %c ett tecken – %d ett heltal
– %f ett decimaltal
– %e ett decimaltal i exponentialform – %g e eller f, vilket som är kortast – %g e eller f, vilket som är kortast – %s textsträng
• Man kan även styra hur många positioner en variabel skall få – %5d totalt 5 positioner
– %6.2f totalt 6 positioner med 2 decimaler
Kommentarer
• int a; /* en heltalsvariabel med namnet a*/
• float b; // en decimaltalsvariabel med namnet b
• int c=2; /* en heltalsvariabel med namnet c som sätts till 2*/
• float pi=3.141592654; /* decimaltalsvariabel som sätts till 3.14…*/
• char bokstav=’b’; //en bokstavsvariabel som sätts till ’b’
• Kommentarer skrivs mellan /* och */
• …eller efter //
• Alla kommentarer plockas automatiskt bort innan kompilatorn börjar jobba så de är bara till för att öka läsbarheten på koden
• Pre-processorn ansvarar för att plocka bort kommentarerna
Grundläggande
programmeringsteknik
#include<stdio.h>
int main(void){
/* kommentar*/
int a=0;
printf(”%d”,a);
}
test.c test.c
0000000 7f45 4c46 0102 0100 0000 0000 0000 0000 0000020 0001 0002 0000 0001 0000 0000 0000 0000 0000040 0000 0194 0000 0000 0034 0000 0000 0028 0000060 0008 0001 002e 7368 7374 7274 6162 002e 0000100 726f 6461 7461 002e 7465 7874 002e 7379 0000120 6d74 6162 002e 7374 7274 6162 002e 7265 0000140 6c61 2e74 6578 7400 2e63 6f6d 6d65 6e74 0000160 0000 0000 0000 0000 2564 0000 9de3 bf88 0000200 0300 0000 9010 6000 d207 bfec 4000 0000 0000220 0100 0000 b010 0001 81c7 e008 81e8 0000
gcc test.c –o test
#include<stdio.h>
int main(void){
/* kommentar*/
int a=0;
printf(”%d”,a);
}
Pre-processor
int printf(char *format) int main(void){int a=0;printf(”%d”,a);}
Kompilator
0000000 7f45 4c46 0102 0100 0000 0000 0000 0000 0000020 0001 0002 0000 0001 0000 0000 0000 0000 0000040 0000 0194 0000 0000 0034 0000 0000 0028 0000060 0008 0001 002e 7368 7374 7274 6162 002e 0000100 726f 6461 7461 002e 7465 7874 002e 7379 0000120 6d74 6162 002e 7374 7274 6162 002e 7265 0000140 6c61 2e74 6578 7400 2e63 6f6d 6d65 6e74 0000160 0000 0000 0000 0000 2564 0000 9de3 bf88 0000200 0300 0000 9010 6000 d207 bfec 4000 0000 0000220 0100 0000 b010 0001 81c7 e008 81e8 0000 0000240 0000 0000 0000 0000 0000 0000 0000 0000 0000260 0000 0001 0000 0000 0000 0000 0400 fff1 0000300 0000 0000 0000 0000 0000 0000 0300 0003 0000320 0000 0000 0000 0000 0000 0000 0300 0002
test.o
test.c
Grundläggande
programmeringsteknik
test.o
0000000 7f45 4c46 0102 0100 0000 0000 0000 0000 0000020 0001 0002 0000 0001 0000 0000 0000 0000 0000040 0000 0194 0000 0000 0034 0000 0000 0028 0000060 0008 0001 002e 7368 7374 7274 6162 002e 0000100 726f 6461 7461 002e 7465 7874 002e 7379 0000120 6d74 6162 002e 7374 7274 6162 002e 7265 0000140 6c61 2e74 6578 7400 2e63 6f6d 6d65 6e74 0000160 0000 0000 0000 0000 2564 0000 9de3 bf88 0000200 0300 0000 9010 6000 d207 bfec 4000 0000 0000220 0100 0000 b010 0001 81c7 e008 81e8 0000 0000240 0000 0000 0000 0000 0000 0000 0000 0000 0000260 0000 0001 0000 0000 0000 0000 0400 fff1 0000300 0000 0000 0000 0000 0000 0000 0300 0003 0000320 0000 0000 0000 0000 0000 0000 0300 0002 0000000 7f45 4c46 0102 0100 0000 0000 0000 0000
0000020 0001 0002 0000 0001 0000 0000 0000 0000 0000040 0000 0194 0000 0000 0034 0000 0000 0028 0000060 0008 0001 002e 7368 7374 7274 6162 002e 0000100 726f 6461 7461 002e 7465 7874 002e 7379 0000120 6d74 6162 002e 7374 7274 6162 002e 7265 0000140 6c61 2e74 6578 7400 2e63 6f6d 6d65 6e74 0000160 0000 0000 0000 0000 2564 0000 9de3 bf88 0000200 0300 0000 9010 6000 d207 bfec 4000 0000 0000220 0100 0000 b010 0001 81c7 e008 81e8 0000 0000240 0000 0000 0000 0000 0000 0000 0000 0000 0000260 0000 0001 0000 0000 0000 0000 0400 fff1 0000300 0000 0000 0000 0000 0000 0000 0300 0003 0000320 0000 0000 0000 0000 0000 0000 0300 0002
test.c
test*
gcc test.c –o test
• Kom ihåg att även om man använder samma symbol ( / ) så är heltalsdivision något annat än att dividera två decimaltal
int i=3,j=2;
float m=3,n=2;
printf(”%f”,i/j);
printf(”%f”,m/n);
skriver ut 0.000000
• Om man blandar heltal och decimaltal så kommer decimaltalsdivision att användas
• Om man vill att resultatet av att dividera två heltal skall vara ett flyttal används en såkallad typecast
int i=3,j=2;
printf(”%f”,(float)i/j); -> 1.5 printf(”%f”,(float)i/j); -> 1.5
• Om ett heltalsvariabel skall divideras med ett konstant heltal kan man sätta ett decimalkomma på konstanten
int i=3;
printf(”%f”,i/2.0); -> 1.5
Grundläggande
programmeringsteknik
Inmatning till enkla program
• Inmatning sker normalt med scanf
– scanf(”%d”,&a); -> läser in ett heltal och lagrar det i variabeln a
• Glöm ej att deklarera variabeln innan – ger ett fel som kompilatorn upptäcker
• Glöm ej &-tecknet framför variabelnamnet
• Glöm ej &-tecknet framför variabelnamnet
– ger fel som kanske ej upptäcks av kompilatorn men som kommer att krascha ditt program med buller och bång
– & anger att det egentligen är variabelns adress som är intressant
Magiska knep
• För att enkel inmatning skall fungera på PC måste man göra enligt – scanf(”%d%c”,&a,&dummy) där dummy deklareras som en char – anledningen till detta är att scanf läser in det som skrivs
inklusive enter-tecknet
– Gör man som ovan kommer entertecknet att hamna i dummy- variabeln
• Om man vill köra på nån annan maskin än PC byter man ut bokens getch(); mot getchar(); och utelämnar #include<conio.h>
– Conio.h är en Borlandspecifik utökning av C och inte del av standard C-biblioteken
Grundläggande
programmeringsteknik
• Formatsträngen till scanf kan innehålla – %c ett tecken läses in
– %d ett heltal läses in
– %f ett decimaltal av typen float läses in – %lf ett decimaltal av typen double läses in – %s en sträng läses in
– %s en sträng läses in
• För att läsa in två heltal och ett decimaltal skriver vi int a,b;
float f;
IF-satsen
• Det enklaste sättet att uttrycka ett val är med hjälp av if-satsen
• if(villkor) sats; /*sats utförs endast om villkor är sant*/
• sats kan vara ett {}-grupperat gäng av satser….
if(2<4){
printf(”Hej”);
printf(” och hå\n”);
}
Grundläggande
programmeringsteknik
Villkor
• Vi har sett att det är möjligt att sätta ihop rätt komplexa utryck int a=1,b=2,c=a;
if (a==c || b<=a && 2!=b)
printf(”Skrivs detta ut?\n”);
printf(”Skrivs detta ut?\n”);
if ((a==c || b<=a) && 2!=b) printf(”Eller det här?\n”);
Prioritetsordningar
() Parenteser
-, +, ! Unärt + och – samt not
*, /, % Multiplikation, division, modulo
+, - Addition, subtraktion
<, <=, >, >= Relationsoperatorer
Grundläggande
programmeringsteknik
<, <=, >, >= Relationsoperatorer
==, != Likhet, olikhet
&& Logiskt och
|| Logiskt eller
= Tilldelning
Om flera operatorer har samma prioritet utförs de från vänster till höger i uttrycket
Villkor
• I C kodas
– falsk som värdet 0
– sant som allt skilt från 0
• Vid tilldelning får hela uttrycket det värde som tilldelas
• Detta kan leda till mycket svårfunna fel:
int a=1;
if(a=3) printf(”Detta skrivs ut\n”);
Våra första C-program (2)
• Skriv ett program som läser in två tal och skriver ut det mindre av talen
• Skriv ett program som löser en andragradsekvation given på
formen ax2+bx+c=0, dvs frågar efter värden på a, b och c samt beräknar x1 och x2 om det finns reella rötter, annars skrivs ett meddelande ut att ekvationen saknar reella lösningar
Grundläggande
programmeringsteknik
Sammanfattning av föreläsningen
• På denna föreläsning har vi pratat om: C-kod, flödesschema, styrkoder, maskinkod, sqrt, en gammal farbror, stdio.h,
kvadratrötter
• Detta var speciellt bra: olika sätt att göra val,
• Detta kan göras bättre: bättre läsbarhet på slides, upplösningen på projektorn,