Kapitel 11 Program Detta kapitel är som synes mycket kort och nämner inte allt från föreläsningen. 11.1 Program Ett datorprogram är en samling instruktioner som beskriver något som en dator ska utföra. Med datorprogram kan man avse dessa instruktioner så som de skrivits i något programspråk i en eller flera textfiler källkoden. Man kan också avse en binärfil med instruktioner i en maskinnära form (maskinkod) som kan utföras (exekveras, köras) direkt av datorn. 11.2 Interpreterande och kompilerande program 11.3 make Ett större program består normalt en mängd filer som använder sig av varandra, och för att kompilera detta kan det krävas flera steg. I Unix-världen används oftast make för att tillverka den körbara filen då. Med det programmet kan man tala om hur olika filer kan tillverkas utifrån andra filer så att det kan utföras automatiskt. Det kan även vara användbart till andra filer som genereras från varandra. Regler för vilka filer som är beroende av vilka kan man lägga in i en särskild fil Makefile och med make filnamn tillverkas filen filnamn på nytt ifall någon av filerna den är beroende av dess prerekvisit har ändrats sen sist. I de flesta programspråk skriver man instruktioner som ligger långt ifrån den typen av instruktioner som datorn kan utföra direkt. Det finns olika sätt att då få datorn att utföra instruktionerna i källkoden: kompilering och interpretering. Kompilering är att översätta källkoden till maskinkod. Översättningen sker med en kompilator ett särskilt program. Sen kör man den resulterande koden. (Källkoden behövs inte längre för att kunna köra programmet. Men om man behöver göra ändringar i programmet behöver man källkoden igen och får lov att kompilera om den efteråt.) Interpretering är att tolka källkoden bit för bit istället. Ett särskilt program, en interpretator, läser och utför dessa instruktioner. (Det finns även mellanlägen mellan kompilering och interpretering.) 111
Laboration 11: Program Redovisning Skicka svar på frågorna till Per senast måndagen den 20/12. Att kompilera Skapa en ny underkatalog för denna labb, under en katalog där du redan har GDB-saker. Ändra så att du har den katalogen som aktuell katalog. Uppgift 11.1 Vad heter katalogen du har använt? Kopiera till denna katalog filen /local/kurs/ gdb06/trappa.c samt några valfri textfiler med namn på.txt att använda till olika tester. (I flera exempel nedan antas det finnas en saga.txt, men du kan använda något annat.) Kompilera programmet med cc trappa.c. Det skapas då en ny fil med det körbara programmet. Uppgift 11.2 Vad heter denna fil? Kör detta program med någon av textfilerna som input. (Använd en textfil som är minst nåt dussin rader lång.) Uppgift 11.3 Hur skrev du kommandot för att göra detta? Normalt skulle man vilja att detta program vars källkod ligger i trappa.c skulle heta trappa istället. Du kan tillverka en sådan fil trappa med hjälp av kommandot make. Kör make trappa. Det skriver ut vilket kommando det i sin tur utför. Uppgift 11.4 Vilken väljare till cc använde make för att tala om vad det kompilerade programmet skulle heta? Uppgift 11.5 Vilken tumregel om ordningen i skalkommandon bryter det kommando som make just utförde mot, förresten? (Den tumregeln är bara en tumregel, som oftast gäller.) Uppgift 11.6 Om du gör om make trappa vad får du du för meddelande från make? Såg du vad programmet gjorde med textfilen? Även om du antagligen inte kan C, så öppna källkoden med Emacs ändå och se om du kan förstå en del av hur programmet fungerar. Uppgift 11.7 Vissa delar av programmet är kommentarer de har ingen effekt på vad programmet gör, utan finns där för att underlätta läsningen och förståelsen av programmet. Vad skriver man tydligen före respektive efter kommentarer i C? Uppgift 11.8 Vad heter den funktion som används i detta program för att skriva ut ett tecken? Makefile Vissa saker vet make redan från början hur den ska tillverka. När du sa åt den att tillverka trappa så såg den att det fanns en fil trappa.c och hade då ett recept för att komma från nånting.c till nånting. Nya sådana recept kan man lära make genom att skriva in dem i en fil Makefile. Öppna en sådan fil i samma katalog som förut och skriv in 3-%.txt: echo $* $* $* >$@ Tryck på TAB för indraget av den andra raden! TAB-tecken har en särskild betydelse i denna fil och det duger inte med några vanliga mellanslagstecken istället. 113
LABORATION 11: PROGRAM Detta är en ny regel för make som talar om hur den kan tillverka filer som har namn som börjar med 3- och slutar med.txt. I dessa mönster kan procenttecknet stå för vad som helst, i stil med asterisken i skalet. Spara denna Makefile och ge kommandot make 3-foo.txt. Om du har skrivit rätt kommer filen 3-foo.txt att skapas. Uppgift 11.9 Vilket kommando utförde make nu? I receptet som talade om hur dessa filer 3-nånting.txt ska tillverkas så har $* bytts ut mot det som procenttecknet stod för i detta fall (nånting). Även andra kombinationer med dollartecken byts ut mot annat. Uppgift 11.10 Varifrån har ersättningen av $@ tagits? Nästa regel du ska skriva är en som dubblerar en fil. Om du har en fil med innehållet så ska resultatet bli t. ex. Om originalfilen hette t. ex. saga.txt så låt den nya filen heta saga2.txt. I make-termer: Om originalet heter %.txt så låt den nya heta %2.txt. %2.txt: %.txt cat $*.txt $*.txt >$@ Här har något nytt tillkommit jämfört med den förra regeln, nämligen något efter kolonet. Det anger prerekvisit, vilket betyder filer som måste finnas för att regeln ska användas och som antagligen används som input. I detta fall finns det bara ett prerekvisit, men det kan finnas flera. Det kan även finnas flera kommandon i en regel, även om det räckt med ett enda i dessa exempel. När det finns flera kommandon utförs de i tur och ordning allihop och ska alla skrivas med ett indrag med ett TAB-tecken. Använd regeln för att tillverka en fil saga2.txt. I denna regel användes $* i uttrycket $*.txt för att skriva namnet på prerekvisitet. Det finns även en särskild beteckning för det första prerekvisitet. Uppgift 11.11 Ta fram Info-dokumentationen för make. Det finns ett menyalternativ»automatic«1 där det står om sådana som du redan sett, som $*. Hur betecknar man första prerekvisitet enligt detta? Ändra så att du använder detta istället, och använd detta sätt även i fortsättningen. * * * Skapa nu en regel i din Makefile som utifrån en fil som saga.txt skapar en fil saga-trappa.txt genom att köra programmet trappa på den. Lägg till trappa som ett andra prerekvisit för att visa att detta kräver att det programmet finns. Uppgift 11.12 Hur lyder denna regel i sin helhet? Prova att make saga-trappa.txt funkar och att resultatet ser ut som det bör. Uppgift 11.13 Ändra sen i trappa.c så att mellanslag används istället för understrykningstecken och gör om make saga-trappa.txt. Vad händer då? Varför? Uppgift 11.14 Vad kan du skapa för ytterligare filer nu med make genom att kombinera de regler du skrivit där utan att skriva något nytt i Makefile? Lite Python Skriv idle & och tryck på RET. Det nya fönstret visar en kommandotolk för programspråket Python där prompten är >>>. Titta på webben på http://nltk.sourceforge. net/lite/doc/en/programming.html, och följ instruktionerna i avsnitt 2.1 2.5. (Observera att sidan fortsätter med 2.6 osv. som inte ingår nu.) Istället för att köra idle kan du också köra python direkt i skalet. Gör exemplen i texten själv också, och lös uppgifterna i slutet av varje avsnitt. 1 Obs, inte det som heter»automatic Prerequisites«, utan det som heter bara»automatic«. 114
Lite Python * * * Uppgift 11.15 Skriv in alla dina kommandon från uppgift 1 i avsnitt 2.5.4 i en fil shells.py i Emacs. (Använd TAB för indentering.) Även i Python mode i Emacs finns det ett kommando för att utföra alla Python-kommandon i bufferten. Sök upp det i Python-menyn och prova det. Uppgift 11.16 Hur kan du köra det från tangentbordet? Från skalet kan du utföra alla Pythonkommandon i filen med python shells.py. För att kunna köra det på samma sätt som ett kompilerat program så måste det framgå inne i filen vilket interpretator som ska tolka programmet, i detta fall Python. En fullständig sökväg till python är /usr/bin/python så lägg därför till en rad #!/usr/bin/python först i shells.py. (Denna speciella rad måste stå allra först i filen.) Jämför med avsnitt 3.7 på s. 33 för att få fram svar på följande: Uppgift 11.17 Vad behöver du mer göra för att det ska gå att köra shells.py direkt? (Gör det!) Med print i Python-övningarna har du skrivit ut text. Den hamnar på standard output. Ett sätt att läsa rader från standard input visas i följande exempel. Den första raden import sys behövs för att det ska gå att använda sys.stdin. Raderna kan läsas en efter en med for som ovan. Raderna avslutas med nyradstecken. Det är därför det sista tecknet på varje rad tas bort med line[:-1] ovan. Uppgift 11.18 Vad gör ovanstående program? Uppgift 11.19 Skriv ett program rev.py som skriver ut varje rad i sin input baklänges. Så en rad»staffan var en stalledräng«ska bli»gnärdellats ne rav naffats«. Uppgift 11.20 Skriv ett program countwords.py som skriver ut rad för rad av sin input, men först på varje rad inom parentes hur många ord det är på den raden. Med inputten Natten är stor och stum. Nu hör det svingar i alla tysta rum sus som av vingar. ska outputten därför blir (5) Natten är stor och stum. (4) Nu hör det svingar (4) i alla tysta rum (4) sus som av vingar. import sys for line in sys.stdin: line = line[:-1] if len(line) > 30: print line[:30] + "..." else: print line Detta program läser text från standard input, en rad i taget, och skriver ut varianter av dessa rader på standard output. Standard input betecknas med sys.stdin. 115