Övning 3 i 2D1324. Strukturering h filer deklaration vs definition Debuggning gdb Preprocessorn #define assert(s) FILE LINE Länkning

Relevanta dokument
Det finns många flaggor till g++,

grundläggande C++, funktioner m.m.

Dynamiskt minne. Vad är dynamiskt minne Motivering Hur gör man i C Övningar

Ett enkelt program i C++, hello.cpp. #include <iostream> int main() { std::cout << "Hello World\n"; return 0; } C++, Övning 1

Övning från förra gången: readword

Programsystemkonstruktion med C++: Övning 1. Karl Palmskog september 2010

*Pekarvärden *Pekarvariabler & *

Pekare och arrayer. Indexering och avreferering

Poster ( structar ) Postdeklarationer

Tentamen *:58/ID100V Programmering i C Exempel 3

#include <stdio.h> #include <string.h>

Avancerad SSL-programmering II

Grundläggande C-programmering del 2 Pekare och Arrayer. Ulf Assarsson

Agenda. Arrayer deklaration, åtkomst Makron Flerdimensionella arrayer Initiering Strängar Funktioner och arrayer. Övningar nu och då

Programmeringsteknik för Ingenjörer VT06. Föreläsning 10

Repetition C-programmering

Grundläggande C-programmering del 2 Pekare och Arrayer. Ulf Assarsson

Introduktion C-programmering

Ulf Assarsson. Grundläggande C-programmering del 2 Pekare och Arrayer. Läromoment:

TDIU01 - Programmering i C++, grundkurs

Länkade listor kan ingå som en del av språket, dock ej i C Länkade listor är ett alternativ till:

Hur man kompilerar och kör IT++-program med MinGW. 1 Sammanfattning. 2 Om dokumentet. 3 Om min konfiguration

... Funktionsanrop. Vad händer när man kör ett program?

Att använda pekare i. C-kod

Vad händer när man kör ett program? Program och processer. Funktionsanrop. Avsluta programmet

Programsystemkonstruktion med C++

Johan Karlsson Datavetenskap för teknisk kemi, 10p, moment 1 Datavetenskap Umeå Universitet. Tentamen

En klass behöver både deklaration och definition. Daniel Aarno Globala funktioner och variabler är OK.

Funktionspekare, inledning: funktionsanropsmekanismen. Anrop via pekare

2 Pekare och dynamiska variabler.

Programmering, grundkurs, 8.0 hp HI1024, HI1900 etc., Tentamen TEN1. Måndagen den 10 januari 2011,

KTH STH TENTAMEN. HI1024:TEN2 - Praktisk tentamen Tid: 8-13, den 18 februari 2012

Föreläsning 3. Programmering, C och programmeringsmiljö

Programmering av inbyggda system. Pekare och Arrayer. Viktor Kämpe

Abstrakta datastrukturer

GU / Chalmers Campus Lindholmen Tentamen Programutveckling LEU 482 / TIG167

Skriv i mån av plats dina lösningar direkt i tentamen. Skriv ditt kodnummer längst upp på varje blad.

Kapitel 6 - Undantag

Programmeringsteknik med C och Matlab

Lite om länkade strukturer

Strängar. Strängar (forts.)

Föreläsning 3. Programmering, C och programmeringsmiljö

Välkommen till. Datastrukturer, algoritmer och programkonstruktion. eller DOA

Föreläsning 13. In- och utmatning

Recap Mera om nya typer Kort Fält. Programmering. Sommarkurs Verónica Gaspes. IDE-sektionen.

BINÄRA TRÄD. (X = pekarvärdet NULL): struct int_bt_node *pivot, *ny; X X X 12 X X 12 X X -3 X X

Programmering av inbyggda system. Pekare och Arrayer. Ulf Assarsson. Originalslides av Viktor Kämpe

Dagens föreläsning. Specialtecken. Mer om printf. Formateringssträngar. Mer om scanf. Programmeringsteknik för Ingenjörer VT05

Fortsä'ning Pekare. Ulf Assarsson. Originalslides av Viktor Kämpe

BMI = (vikt i kg) / (längd i m) 2. Lösningsförslag

Programmering B med Visual C

Föreläsning 12. struct

Exempel ( )

lex källkod lex.l lexkompilator lex.yy.c C- kompilator lex.yy.c a.out sekvens av tokens a.out input specifikation av tokens mha reguljära uttryck

Föreläsning 9. struct

GU / Chalmers Campus Lindholmen Tentamen Programutveckling LEU 482 / TIG167

Programmeringsteknik med C och Matlab

TDDC74 Lab 04 Muterbara strukturer, omgivningar

Funktioner. Jan Erik Moström,

tentamensdags och lab 3

Operativsystem ID1200/06 och ID2200/06 Tentamen TENA 6 hp :00-18:00

C++ Objektorientering - Klasser. Eric Elfving

Föreläsning 10. Pekare (Pointers)

Första exemplet. Kompilator & länkare. Projekt. Övning 1, Ögrupp 4, Programsystemkonstruktion med C++, Ronnie Johansson,

Minnestilldelning (allokering) och frigörande (avallokering) av minne

IS1200 Datorteknik. Övning CE_O4 Maskinnära programmering med C Förberedelser till hemlaboration 1

Värmedistribution i plåt

Sätt att skriva ut binärträd

GPT föreläsning 8. Förra veckan: Man kan ta tiden på en sorterad teckensträng Förra gången: Problemlösning på lägre nivå kan sortera funktioner

Deklarera en struct som kan användas för att representera en rät linje

2D1387, Programsystemkonstruktion med C++ Johnny Bigert, Kursens hemsida:

Lösningar till uppgifterna sätts ut på kurssidan på nätet i dag kl Omtentamen i Programmering C, Fri, Kväll,

Generell säkerhet. Loggning - Hur mycket ska man logga? Inloggningsrutinerna i Unix. Loggning fortsättning

Instruktioner för att kunna programmera på skolans datorer

Planering Programmering grundkurs HI1024 HT 2014

Raspberry Pi och Tellstick, ett program i C.

Programsystemkonstruktion med C++: Övning 2. Karl Palmskog september 2010

Innehållsförteckning. Exempel. Åtkomst & användarhandledning

Laboration 3 HI1024, Programmering, grundkurs, 8.0 hp

Pekare ( )

Innehåll. Introduktion till objektorientering. OOP (objektorienterad programmering) Objekt, instanser, klasser

Innehåll. Pekare Exempel

TDIU01 - Programmering i C++, grundkurs

Programbibliotek. Ur innehållet: Olika typer av bibliotek Kompilatorbibliotek C-bibliotek Run-time miljö Så skapar du ett nytt bibliotek

En kort text om programmering i C.

TUTORIAL: KLASSER & OBJEKT

HI1024 Programmering, grundkurs TEN

C++ Objektorientering - Klasser. Eric Elfving Institutionen för datavetenskap

Föreläsning 9: Förprocessorn och stora program

Kompilatorer och interpretatorer

3 Listor. 3.1 Envägslistor

Assemblerprogrammering, ARM-Cortex M4 del 3

Programmering av inbyggda system. Kodningskonventioner. Viktor Kämpe

Om pekare och minneshantering i C, relaterat till operativsystem och särskilt konstruktionen fork() execvp().

TDP005 Projekt: Objektorienterat system

TDIU01 Programmering i C++

1. Klass med en dynamiskt allokerad variabel, definitionsfilen-del Klass med en dynamiskt allokerad variabel, inkluderingsfilen.

Föreläsning 2: Avlusning och antilustekniker

Kapitel 1. C++-programmets beståndsdelar. C++-programmets beståndsdelar. Kapitel 1 grunderna i C++

Tentamen i. för D1 m fl, även distanskursen. lördag 19 januari 2013

Transkript:

Övning 3 i 2D1324 Strukturering h filer deklaration vs definition Debuggning gdb Preprocessorn #define assert(s) FILE LINE Länkning Avancerad c-programering och repetition

Typisk h-fil #ifndef special_a #define special_a struct another_struct{ char name[30] int age; }; struct dummy_node{ struct another_struct *data; struct dummy_node *next }; typedef struct dummy_node Dummy_Node; typedef stuct another_struct Another_struct; void swap(int *a, int *b); Another_struct* clone(another_struct* to_clone); void print_int_array(int *start, int num_to_print); #endif

Kloning av structar #include <stdio.h> #include <stdlib.h> #include <string.h> #include special_a.h Another_struct* clone(another_struct* to_clone){ Another_struct* p= (Another_struct*)malloc(sizeof(Another_struct)); strcpy(p->name,to_clone->name); p->age=to_clone->age; return p; }

Kopiering av bufferts #include <stdio.h> #include <stdlib.h> #include <string.h> int main(int argc, char* argv[]) { if(argc == 1){ printf("du måste ange ett extra ord när du startar programmet\n usage: %s ord_att_kopiera",argv[0]); } else{ char buffert[30]="initialt innehåll"; printf("buffert innehåller: %s\n kopierar från argv...",buffert); /*För att kopiera innehållet i sträng måste vi använda funktion strcpy(char *dest,char *source) som finns i string.h skriver vi buffert=argv[1]; ändrar vi var buffert pekar istället för innehållet skriver vi *buffert= *(argv[1]); så kopierar vi inte hela strängen */ strcpy(buffert,argv[1]); printf("...koperiering gjord till buffert\nbuffert innehåller: %s\n",buffert); } return 0; }

Deklarerad vs Definerad. int foo(int bar); är en deklaration eftersom den slutar med ; Eftersom foo behövs i flera av våra moduler måste foo deklareras i varje fil. Lättast görs detta i en h fil som har en include guard. Då kan vi inkludera den i varje fil. int foo(int bar){ return bar*2; } är definderad eftersom själva programkoden för foo är med. Eftersom det är definition ska den ligga i c fil.

Dela med sig kod/program? Ofta är det olämpligt att ge folk för mycket kunskap om funktioners innehåll. Du säljer ditt program och vill inte avslöja din lösning. Vidare frestas köparen nyttja kunskap om detaljer som han inte bör ta hänsyn till eftersom du avser att ändra dessa. Om dina deklarationer ligger i h fil som kan inkluderas och c filerna bifogas som o eller lib filer undviker man problemet. Personen kan iofs hypotetiskt köra disassemblings program för att få fram koden i alla fall. Det förbjuds dock normalt uttrycklingen av licensvillkoren.

Abstraktion och separation Ofta har man läget att man dels har logik som väljer vad som ska göras samt programkod som direkt kommunicerar med hårdvara, grafiska komponenter eller annat. Skriver man ett enda program blir det mycket kostsamt att byta hårdvara, logik eller dylikt. All kod måste undersökas innan man vet att allt fungerar. En bättre lösning är att logik lagret har en h fil som beskriver ett mellanlager som i sin tur anropar hårdvaran. Fördelarna med detta är så stora att detta upplägg normalt är krav inom industrin. (dock tyvärr inte alltid på kth)

Kompilera flera filer Man kan kompilera flera c filer genom att skriva. gcc -Wall -g -o result fil1.c fil2.c fil3.c fil4.c (om ni inte vet vad -Wall och -g gör bör ni skyndsamt kolla upp dessa flaggor) Själva h filerna inkluderas i c filerna så dessa står aldrig uttryckligen. Vill man spara tid i kompileringen bör man kompilera endast den fil som ändrats och sedan länka ihop den gamla o filer gcc -Wall -g -c fil2.c

make Make arbetar på filer som innehåller specifikationer om hur ditt program arbetar. Först står mål sedan ett : följt av vilka filer som behövs för att skapa målet. På raden efter följer de kommandon som make ska göra om den märker att filen behöver uppdateras. Är make filen rätt skriven så kommer make undersöka vilka filer som ändrats och kompilera om dessa enbart. Make kan sättas att göra annat än kompilera filer. Kommandon som cp, cd,mv,rm ls och liknande stöds. Man kan även få make att zippa filer eller göra annat nyttigt.

Debuggning Att komma på vad pekare faktiskt gör i ett program kan vara klurigt. Har vi pekare till structar är det ju adressen för det som pekaren pekar på som är intressant och inte adressen till pekaren själv. I praktiken är det lätt att göra bort sig. Om ni inte fattar varför ert progam inte fungerar...kompilera med flaggan -g och använd sedan programmet gdb. En beskrivning av hur man använder gdb finns på http://mia.ece.uic.edu/~papers/www/debugging/debugging-with-gdb.html

Preprocessorn kan hitta buggar #include<assert.h> void open_record(char *record_name) { assert(record_name!=null); /* Rest of code */ } int main(void) { open_record(null); }

Hur skulle assert kunna se ut? #define assert(s) if(s) {} else printf( Assert failed in %s on line %d, FILE, LINE ) /*Dock så finns piffig variant av assert i filen assert.h så man slipper att ens göra testet. FILE och LINE är värden som preprocessorn tillhandahåller som säger vilken fil och vilken rad som koden kommer från. Har man ingen terminal att få utdata till så får man blinka med diod, skicka ett interupt eller göra något annat man kan upptäcka.*/

Dynamisk vs statisk länkning Allt i c standard biblioteket ligger kompilerat redo att länkas in i program. Det finns två sätt att göra detta. Med dynamisk länkning så hämtas funktionen från så kallad dll fil när den behövs. Man sparar massa plats på hårddisken...men måste ha speciellt installationsprogram som kontrollerar om dll filen finns installerad. Alternativt gör man statisk länkning. Från så kallade lib filer hämtas den kompilerade koden och länkas in permanent. Programmet blir betydligt mycket större men kan köras utan installationsprogram.

Viktiga saker om minne Var försiktiga med pekare som inte satts att peka på något menigsfullt. Antingen bör pekare sättas att peka på NULL eller på något från malloc. Varje malloc anrop måste matchas av exakt ett free anrop. Gör man free på samma minne två gånger så får man problem. Sätt därför en pekare att peka på NULL efter att ni gjort free. Det är ofarligt att göra free på en NULL pekare. Läs pekar tutorialen på hemsidan!

Dålig pekar returnering Funktioner som returnerar saker ska aldrig returnera pekare till något som ligger på stacken. Allt som ligger på stacken för funktionen blir ju av allokerat när funktionen tagit slut så minnet pekaren är satt att peka på kan skrivas över när som helst efteråt. Just direkt efter funktionen returnerat märker man dock inget...men det är bara en tidsfråga innan någon funktion anropas. Lösningen är givetvis att allokera minnet med malloc och returnera pekare till detta.

Repetition pekare Läs pekartutorialen på hemsidan! rad[] == *(rad) rad[30] == *(rad+30) Observera att sammanhanget avgör om char rad[30] ska tolkas som en deklaration av 30 char eller som *(rad+30) matris[3][2]==*(*(matris+3)+2)

Returnera flera saker från funktion Python kan returnera flera saker från funktioner eftersom list är en av de inbygda typerna. I c har vi ingen lista. Vi har inte ens en riktig array utan pekar artimetik för att hantera dessa...vi kan dock deklarera en struct, allokera den med malloc och returnera en pekare till denna.

Skumma sätt att skriva saker... Kompakt men kanske lite svårtolkat... z = (a>b)? a : b; if (a>b) z = a; else z=b;

Hur klarar man sig utan try, catch? Lösning : Undersök returvärdet på allt...lusläs manualen så ni vet i vilka fall ni kan få NULL eller annat värde som indikerar fel. Det finns ett kompakt sätt att skriva saker...(nästa sida visar varför detta orsakar problem.) if( char *ptr= (char*)malloc(10*sizeof(char))){ printf( ERROR: Could not alloc memory. ); exit(-1); }

Problemet med = och == Skriver man if(tal = 5 ) istället för if(tal == 5) så betyder det en tilldelning istället för jämförelse. Eftersom 5 inte har samma värde som NULL så tolkas det som sant. Väldigt jobbig loggisk bugg att hitta... Lösningen är att skriva smartare jämförelser. Om if(5 == tal) felskrivs som if( 5 = tal ) så klagar kompilatorn eftersom vi inte får tilldela värden till konstanter.

Pekare till funktioner C stödjer precis som python att man har pekare till funktioner. Precis som i python används det typiskt för att ändra sorteringsvillkor. Ett annan användning är att i structar har pekare till funktioner som operar på structens data... int foo(int); int (*pf) (int) = &foo; #Anrop av samma funktion ans = foo(5); ans = pf(5);

Länkade listor Att repetera länkade listor är bortkastad tid. Ni har gjort swahili labben från i höstas, kan hitta 184 000 000 sidor om länkad listor via google och vet hur man formulerar rekursiva tankar. Att en del personer har problem med listorna är delvis befarat...hälften av de som skrev tentan körde rekursionsuppgiften. Det är dock inget skäl att ni inte ska bli klara med labben denna vecka. Ta en paus...skriva h-filer som uppfyller de krav labben kräver...jobba med rekursiva tankar och ni kommer snart vara helt klara. Själva hash funktionen går fort när ni kommit så långt.