Funktionspekare, inledning: funktionsanropsmekanismen. Anrop via pekare

Relevanta dokument
Poster ( structar ) Postdeklarationer

Tentamen *:58/ID100V Programmering i C Exempel 3

Pekare och arrayer. Indexering och avreferering

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

*Pekarvärden *Pekarvariabler & *

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

Pekare. Pekare. Varför använder vi pekare? Vad är en pekare? Pekare. Deklaration/initiering av pekare

2 Pekare och dynamiska variabler.

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

Föreläsning 12. struct

Det finns många flaggor till g++,

TDDC76 - Programmering och Datastrukturer

Föreläsning 9. struct

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

Att använda pekare i. C-kod

Föreläsning 11. Strängar

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

Skizz till en enkel databas

Programmering av inbyggda system. Kodningskonventioner. Viktor Kämpe

Programmera i C Varför programmera i C när det finns språk som Simula och Pascal??

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

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

Vad har vi lärt oss så här långt Vad är en sträng? Strängkonstanter. Att skriva ut och läsa in strängar. Att arbeta med strängar.

Innehåll. Pekaren this Självreferens. Klasser Resurshantering, representation. Överlagring av operatorer. Överlagring av operatorer

SORTERING OCH SÖKNING

TDIU01 - Programmering i C++, grundkurs

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

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

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

Funktionens deklaration

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

Repetition C-programmering

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

Innehåll. Pekare Exempel

Introduktion C-programmering

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

Tentamen i Programmering grundkurs och Programmering C

Föreläsning 2 Objektorienterad programmering DD1332. Typomvandling

Symboliska konstanter const

Hantering av textsträngar och talsträngar. William Sandqvist

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

Typkonvertering. Java versus C

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

Tentamen i Programmering grundkurs och Programmering C

Introduktion till arv

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

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

Innehåll. Pekare Exempel

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

Tentamen i Programmering grundkurs och Programmering C

Innehåll. Typomvandlingar (casting) Implicita Typomvandlingar. Typomvandlingar (type casts) Explicita, namngivna typomvandlingar (C++-11)

Lite om felhantering och Exceptions Mer om variabler och parametrar Fält (eng array) och klassen ArrayList.

C++-programmets beståndsdelar

Tentamen i. Programmering i språket C

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

1 Modulär programutveckling.

Del3 Klassanvändning, operatorer och pekare Ämnesområden denna föreläsning:

Byggstenar. C++-programmets beståndsdelar. C++-programmets beståndsdelar. Grundläggande datatyper

6.1 Kompilering och lite grundläggande information

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

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

Datatyper och kontrollstrukturer. Skansholm: Kapitel 2) De åtta primitiva typerna. Typ Innehåll Defaultvärde Storlek

Tentamen i Programmering grundkurs och Programmering C

Tentamen i Programmering grundkurs och Programmering C

Exempel ( )

Dynamisk bindning och polymorfism

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

struct egendefinierad typ struct LECTURE_TYPE { char teacher[99]; float lengthinminutes; char type; /* L = lecture, E = exercise */ };

TDDC76 - Programmering och Datastrukturer

Innehåll. EDAf30: Programmering i C++, 7.5 hp. EDAf30: Programmering i C++, 7.5 hp Viktiga skillnader mot Java

Kapitel 3. Synlighet. Kapitel 3 - Klassanvändning, operatorer och pekare. Synlighet

TDP004. Minne och pekare. Eric Elfving Institutionen för datavetenskap

3 Listor. 3.1 Envägslistor

Översikt Introduktion DST 1. Nicholas Wickström. IDE, Högskolan i Halmstad. N. Wickström

F5: Högnivåprogrammering

Innehåll. Resurshantering. Resource handles. Minnesallokering. Minnesallokering Exempel: allokering på stacken. 6. Resurshantering

Innehåll. Exceptionella händelser (exceptions, undantag ) Felhantering Tre nivåer av felhantering: Nivå 2: exceptions (eller returvärde)

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

int (*fp) (char, char*) //pekare till funktion som tar //argumenten (char, char*) och //returnerar int

Synlighet. Namespace Scope-operatorn Klasser Vänner

F5: Högnivåprogrammering

Programmeringsteknik med C och Matlab

Abstrakta datastrukturer

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

HI1024, Programmering, grundkurs, 8hp KTH STH TENTAMEN. HI1024:TEN1 - Teoretisk tentamen Tid: Torsdagen den 20 oktober 2011,

TDIU01 - Programmering i C++, grundkurs

Assemblerprogrammering, ARM-Cortex M4 del 3

*:85/ID200V C++ HT07. Föreläsning 8 Medlemspekare Undantagshantering Namnrymder

const och pekare Output: char *unsafe(char *s) { // Returnerar pekare till det andra tecknet i s printf("%s \n", s);

Kapitel 6 - Undantag

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

översiktskurs (5DV031)

TDIU01 - Programmering i C++, grundkurs

4 Sammansatta datatyper

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

Avancerad SSL-programmering II

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

Programmering i C++ EDA623 Typer. EDA623 (Föreläsning 4) HT / 33

C-programmering, föreläsning 2 Jesper Wilhelmsson

Det objektorienterade synsättet. Objekt. Datorprogrammet kan uppfattas som en slags modell av den verklighet programmet skall samverka med.

Transkript:

Funktionspekare, inledning: funktionsanropsmekanismen Vid funktionsanrop läggs aktuella argumentvärden och återhoppsadressen på stacken, därefter sker ett hopp till adressen för funktionens första instruktion. Källkodens funktionsnamn översätts till denna adress. Exempel: void funk(int i){... funk(3);... main funk 3000 Instr. för att lägga 3 och returadressen på stacken CALL 3000... i 3 returadressen Instruktioner Statiska data Stacken Bild 88 Anrop via pekare Det finns inget som hindrar att funktionsadressen, istället för att finnas direkt i instruktionen, hämtas från en variabel där den tidigare lagrats av programmet: main funk 3000 Instr. för att lägga funks adress i fpek Instr. för att lägga 3 och returadressen på stacken CALL *3000... fpek 7000 3000 i 3 returadressen Instruktioner Statiska data Stacken void funk(int i){... funktionspekare fpek=funk; (*fpek)(3);... Bild 89 1

Om funktionspekare Funktionspekare kan som alla andra pekarvärden lagras i variabler, i datastrukturer (t.ex. en array av funktionspekare), skickas som argument till andra funktioner och returneras från funktioner, m.a.o. användas på alla sätt som andra typer av värden kan användas på. Funktionspekare gör att man kan skriva programkomponenter vilkas beteende kan modifieras och anpassas under exekvering genom att de vid olika tillfällen kan anropa olika funktioner från samma instruktioner (det som i objektorienterade språk kallas dynamisk bindning och polimorfism). Avreferering av en funktionspekare med anropsparenteser efter innebär anrop av den funktion som pekaren pekar ut för tillfället: (*fpek)(3); ANSI-C införde möjligheten att utelämna den explicita avrefereringen: fpek(3); Ett funktionsnamn utan anropsparenteser är adressen till funktionen: fpek=funk; Bild 90 Deklarationssyntax - exempel Eftersom kompilatorn skall kunna kontrollera argument- och returvärden vid anrop av funktioner även via pekare, måste funktionspekare deklareras med information om dessa. Deklarationssyntaxen följer anropssyntaxen och måste ta hänsyn till operatorernas precedens: void (*fpek)(int); - fpek är en pekare till en funktion som tar en int som argument och returnerar void. Parenteser kring *fpek är nödvändiga, void *fpek(int) betyder funktion som returnerar void * char *(*fpek)(char *, int); - fpek är en pekare till en funktion som tar en char * och en int som argument och returnerar en char * int (*fpekvek[10])(int); - fpekvek är en vektor med 10 pekare till funktioner som tar en int som argument och returnerar en int Anrop av en funktion via pekare i vektorn skulle ske enligt följande exempel: i=(*fpekvek[3])(137); Bild 91 2

Deklarationssyntax - exempel (forts.) int (*getfunk(int))(char *); - getfunk är en funktion som tar en int som argument och som returnerar en pekare till en funktion som tar en char * som argument och returnerar en int void (*signal(int sig, void (*hndl)(int)))(int); - signal är en funktion som tar som argument dels en int (sig), dels en pekare (hndl) till en funktion som tar en int som argument och returnerar void. signal returnerar en pekare till en funktion som tar en int som argument och returnerar void Sådana deklarationer kan underlättas genom att ett namn för funktionspekartypen definieras med en typedef: typedef void (*Sighandl)(int); Sighandl signal(int sig, Sighandl hndl); När pekar- eller argumentnamn är oväsentliga, t.ex. vid typomvandlingar, kan de utelämnas: (int (*)(int, int)) Bild 92 Exempel 1: funktion med funktionspekare som argument #include <stdio.h> #include <math.h> void tab(double from, double to, double step, double (*funk)(double), char *header){ double x; printf("x\t%s\n", header); printf("-----------------\n"); for(x=from; x<=to; x+=step) printf("%.2f\t%.3f\n", x, funk(x)); double sinpluscos(double x){ return sin(x)+cos(x); tab(0, 1, 0.05, sin, "sin(x)"); tab(0, 1, 0.05, sinpluscos, "sin(x)+cos(x)"); return 0; Bild 93 3

Exempel 2: återanvändbar datastruktur, sid 1 En sorterad array-list: Headerfilen sortarrlist.h: typedef struct sortarrstruct *Sorted_array_list; Sorted_array_list init(int (*cmp)(const void *, const void *)); void add(sorted_array_list list, void *new); void doforall(sorted_array_list list, void (*doit)(void *)); Obs att headerfilen endast definierar typen för pekare till något som heter struct sortarrstruct. Detta räcker för att tillämpningar skall kunna deklarera sådana pekarvariabler för att ta emot resultat av funktionen init() och för att skicka dem till de andra funktionerna. Däremot vet inte tillämpningar vad som finns inne i en struct sortarrstruct. På detta sätt skapar man dataabstraktion i C. Bild 94 Exempel 2: återanvändbar datastruktur, sid 2 #include <stdlib.h> #include "sortarrlist.h" #define CHUNK 10 typedef struct sortarrstruct{ int siz, count; void **arr; int (*cmp)(const void *, const void *); Sort_arr_struct; Sorted_array_list init(int (*cmp)(const void *, const void *)){ Sorted_array_list tmp = malloc(sizeof(sort_arr_struct)); if (!tmp) return NULL; tmp->siz=chunk; tmp->count=0; tmp->arr=calloc(chunk, sizeof(void *)); if (!tmp->arr){ free(tmp); return NULL; /* if */ tmp->cmp=cmp; return tmp; Bild 95 4

Exempel 2: återanvändbar datastruktur, sid 3 void add(sorted_array_list list, void *new){ int i; if (list->count == list->siz) list->arr=realloc(list->arr, (list->siz*=2)*sizeof(void *)); for(i=list->count; i>0 && list->cmp(list->arr[i-1], new)>0; i--) list->arr[i] = list->arr[i-1]; list->arr[i] = new; list->count++; void doforall(sorted_array_list list, void (*doit)(void *)){ int i; for(i=0; i<list->count; i++) doit(list->arr[i]); Bild 96 Exempel 2: återanvändbar datastruktur, sid 3, tillämpningsprogram #include <stdio.h> #include <stdlib.h> #include <string.h> #include sorarrlist.h typedef struct _person{ int nr; char namn[10]; Person; Person *make(int nr, char *namn){ Person *pek=malloc(sizeof(person)); pek->nr=nr; strcpy(pek->namn, namn); return pek; int perscmp(person *p1, Person *p2){ return strcmp(p1->namn, p2->namn); Bild 97 5

Exempel 2: återanvändbar datastruktur, sid 4, tillämpning forts. void visa(person *p){ printf("%d\t%s\n", p->nr, p->namn); Sorted_arr_list reg=init((int (*)(void *, void *))perscmp); add(reg, make(61, "Stefan")); add(reg, make(53, "Jozef")); add(reg, make(62, "Anna")); doforall(reg, (void (*)(void *))visa); return 0; Bild 98 qsort och bsearch #include <stdlib.h> void qsort(void *base, size_t n, size_t size, int (*cmp)(const void *, const void *)); sorterar arrayen som pekas ut av base och som består av n stycken objekt, var och en av storleken size. cmp skall vara en funktion som tar två pekare till sådana objekt och returnerar enligt samma konvention som strcmp. void *bsearch(const void *key, const void *base; size_t n, size_t size, int (*cmp)(const void *, const void *)); söker med binär sökning i den sorterade arrayen som pekas ut av base och som består av n stycken objekt av storleken size. cmp skall kunna ta en pekare till ett sökbegreppet (key) och en pekare till ett objekt och returnera enligt samma konvention som strcmp. Bild 99 6