Pekare och arrayer. Indexering och avreferering

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

2 Pekare och dynamiska variabler.

Funktionspekare, inledning: funktionsanropsmekanismen. Anrop via pekare

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

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

Tentamen *:58/ID100V Programmering i C Exempel 3

Programmeringsteknik med C och Matlab

Poster ( structar ) Postdeklarationer

4 Sammansatta datatyper

TDIU01 - Programmering i C++, grundkurs

*Pekarvärden *Pekarvariabler & *

Strängar. Strängar (forts.)

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

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

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

C++-programmets beståndsdelar

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

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

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

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

Repetition C-programmering

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

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

Introduktion C-programmering

Typkonvertering. Java versus C

TDDC76 - Programmering och Datastrukturer

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

TDDC76 - Programmering och Datastrukturer

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

En kort text om programmering i C.

6.1 Kompilering och lite grundläggande information

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

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

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

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

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

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

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

Det finns många flaggor till g++,

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

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

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

Tommy Färnqvist, IDA, Linköpings universitet

Dagens föreläsning. Repetition. Repetition - Programmering i C. Repetition - Vad C består av. Repetition Ett första C-program

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

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

SP:PROG3 HT12 Tenta

TDIU01 - Programmering i C++, grundkurs

Föreläsning 11. Strängar

Innehåll. Pekare Syntax

Föreläsning 3-4 Innehåll. Diskutera. Metod. Programexempel med metod

Avancerad SSL-programmering II

Enkla datatyper minne

Föreläsning 11. Arrayer. Arrayer. Arrayer. Lagrar flera värden av samma typ Kan vara primitiva typer eller objekt. Kan ha en array av t.

Föreläsning 3-4 Innehåll

4 Sammansatta datatyper

Föreläsning 7 Strängar

Introduktionslaboration

Abstrakta datastrukturer

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.

Föreläsning 10. Pekare (Pointers)

Kapitel 6 - Undantag

Föreläsning 2 Objektorienterad programmering DD1332. Typomvandling

Kompilering och exekvering. Föreläsning 1 Objektorienterad programmering DD1332. En kompilerbar och körbar java-kod. Kompilering och exekvering

Att deklarera och att använda variabler. Föreläsning 10. Synlighetsregler (2) Synlighetsregler (1)

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

TDIU01 - Programmering i C++, grundkurs

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

Dagens föreläsning. Repetition. Repetition - Programmering i C. Repetition - Vad C består av. Repetition Ett första C-program

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

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

Tentamen i Programmering grundkurs och Programmering C

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

Exempel ( )

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

Symboliska konstanter const

Klassdeklaration. Metoddeklaration. Parameteröverföring

Tentamen DE12, IMIT12, SYST12, ITEK11 (även öppen för övriga)

C++ Funktioner 1. int summa( int a, int b) //funktionshuvud { return a+b; //funktionskropp } Värmdö Gymnasium Programmering B ++ Datainstitutionen

Objektorienterad Programmering (TDDC77)

Objektorienterad programmering i Java I. Uppgifter: 2 Beräknad tid: 5-8 timmar (OBS! Endast ett labbtillfälle) Att läsa: kapitel 5 6

1 Texthantering. 1.1 Typen char. Exempel, skriv ut alfabetet

Tentamen i Programmering grundkurs och Programmering C

Tentamen i Programmering grundkurs och Programmering C

Lösningar till tentauppgifterna sätts ut på kurssidan på nätet idag kl

Programmering med Java. Grunderna. Programspråket Java. Programmering med Java. Källkodsexempel. Java API-exempel In- och utmatning.

Idag. Javas datatyper, arrayer, referenssemantik. Arv, polymorfi, typregler, typkonvertering. Tänker inte säga nåt om det som är likadant som i C.

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

732G Linköpings universitet 732G11. Johan Jernlås. Översikt. Repetition. Felsökning. Datatyper. Referenstyper. Metoder / funktioner

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

Programmeringsteknik med C och Matlab

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

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

Lösningar till uppgifterna sätts ut på kurssidan på nätet idag kl Omtentamen i Programmering C, 5p, A1, D1, E1, Fri, Pr1, Te/Ek1,

Skizz till en enkel databas

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

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

Lathund. Pacific C för MS-DOS

HI1024, Programmering, grundkurs, 8hp KTH STH TENTAMEN. HI1024:TEN2 - Praktisk tentamen Tid: Fredagen den 21 oktober 2011,

Föreläsning 6: Introduktion av listor

Transkript:

Pekare och arrayer En array är ett sammanhängande minnesområde rymmande ett antal element av en viss typ. Arraynamnet kan ses som adressen till arrayens början, dvs. dess första element. En pekare är en variabel innehållande adressen till ett minnesområde. Ett arraynamn kan alltså ses som ett konstant pekarvärde till arrayens första element. Antag deklarationerna: int vek[5], *pek=vek; vek pek Bild 71 Indexering och avreferering I C kan pekare och arrayer i de flesta situationer användas i samma betydelse och i samma syntaktiska konstruktioner, t.ex. kan arraynamn avrefereras och pekare indexeras. T.ex. har följande satser samma effekt: vek[0]=137; *vek=137; *pek=137; pek[0]=137; (och faktiskt 0[vek], men det låtsas vi inte om...) Obs dock att arraynamnet är ett konstant pekarvärde, som alltså inte kan ändras. Vidare finns det situationer då arrayer och pekare inte är utbytbara, t.ex. är extern int vektor[]; och extern int *pek; två helt olika saker. Bild 72 1

Pekararitmetik Vissa aritmetiska operationer är definierade för pekare av känd typ (alltså inte för void * ). Obs! att dessa operationer är typkänsliga och tar hänsyn till de utpekade elementens storlek! addition av pekare med heltal: pek++; - flyttar pek till nästa element pek2=pek+5; - pek2 pekar på femte elementet bortom pek pek+=5; - pek flyttas fem element längre bort Obs att heltalet tolkas som antalet element, inte antalet bytes! Obs vidare att dessa operationer garanteras fungera endast så länge resulterande pekarvärde ligger inom samma sammanhängande datastruktur, t.ex. inom en deklarerad array eller ett minnesutrymme allokerat med ett malloc()-anrop. Det resulterande pekarvärdet får dock peka just bortom sista elementet i strukturen. subtraktion av pekare med heltal: pek--; - flyttar pek till föregående element pek-=5; - pek flyttas fem element bakåt Bild 73 Pekararitmetik (forts.) subtraktion av pekare med pekare i samma datastruktur: count = pek2 - pek1; Ger antalet element mellan pekarna. jämförelse av pekare för likhet och olikhet: if (pek1 == pek2)... if (pek1!= pek2)... jämförelse av pekare i samma datastruktur med andra relationsoperatorer: if (pek1 < pek2)... Innebär alltså om pek1 pekar ut ett objekt som ligger före det objekt som pekas ut av pek2 i datastrukturen. Bild 74 2

Indexering och avreferering II Uttrycket vek[i] är per definition ekvivalent med *(vek+i). Indexering innebär alltså implicit avreferering. I vissa situationer kan man vilja undvika avreferering vid åtkomster till en array, säg t.ex. att man håller på att avtolka en sträng innehållande en kommandoradsflagga av typen -ofilnamn, och vill öppna filen med det givna namnet. Antag följande deklarationer: char str[20]; /*Innehåller flaggan */ char *filnamn; FILE *fil; Detta görs t.ex. så här: filnamn=str+2; if ((fil=fopen(filnamn, r ) == NULL){ fprintf(stderr, Can t open %s\n, filnamn); exit(-1); Bild 75 Ett kuriosum Eftersom vek[i] är ekvivalent med *(vek+i) och addition är kommutativ, dvs. *(vek+i) är ekvivalent med *(i+vek) som i sin tur är per definition ekvivalent med i[vek] så kan man byta plats mellan vektornamn och indexuttrycket... T.ex. är det tillåtet att skriva 5[ abcdefgh ], värdet av detta uttryck är f. Detta är dock inte den viktigaste detaljen på kursen och inte ett rekommenderat sätt att skriva sin kod. Bild 76 3

Vektorgenomgångar med pekararitmetik Vektorgenomgången for(i=0; i<10; i++) vek[i]=0; kan göras så här: for(pek=vek; pek < vek+10; pek++) *pek=0; För vektorer vilkas logiska slut markeras med ett noll-element, t.ex. strängar eller pekarvektorer kan noll-elementet användas som avbrottsvillkor. Exempel: En implementering av strcpy(): char *strcpy(char *str1, char *str2){ char *start=str1; while(*str1++=*str2++) ; return start; En implementering av strlen(): int strlen(const char *str){ char *start=str; while (*str) ++str; return str - start; Bild 77 Dynamiska arrayer Sambandet mellan pekare och arrayer gör att man kan implementera dynamiska arrayer, som alltså kan minskas eller utökas vid behov, genom att deklarera en pekare istället för en array och allokera utrymmet dynamiskt. Exempel (ineffektivt): int *arr=null; int count=0; void add(int val){ arr=realloc(arr, ++count*sizeof(int)); arr[count-1]=val; void del(void){ arr=realloc(arr, --count*sizeof(int)); void print(void){ int i; for(i=0; i<count; i++) printf( %d, arr[i]); printf( \n ); Bild 78 4

Dynamiska arrayer (forts.) Omallokering är en ganska krävande operation, varför man inte brukar göra det med ett element i taget. Istället allokerar man ett antal element åt gången. Om det är fråga om en enstaka buffertarea brukar man inte heller minska arean. Exempel: #define CHUNK 20 int count=0, siz=0; int *arr=null; void add(int val){ if (++count>siz) arr=realloc(arr, (siz+=chunk)*sizeof(int)); arr[count-1]=val; Bild 79 Pekararryer Samlingar av större objekt eller (framför allt) av objekt av varierande storlek hanteras lämpligen genom arrayer av pekare till objekten. Om antalet objekt varierar kan pekararrayen allokeras dynamiskt och omallokeras vid behov. En viktig användning av pekararrayer är arrayer av strängar. Exempel: enum errcodes {ERRNONE, ERROPEN, ERRMEM; const char *errmgs[]={ No error, Can t open file %s\n, Out of memory! ; void funk(char *fname){ FILE *f; if ((f=fopen(fname, r )==NULL){ fprintf(stderr, errmsg[erropen], fname); exit(erropen);... Bild 80 5

Kommandoradsargument Kommandoraden som ett program har startats med finns tillgänglig för programmet som en NULL-terminerad vektor av pekare till strängar som kommandoraden bestod utav. Kommandotolken delar upp kommandoraden i delsträngar avdelade med blanktecken (som alltså inte ingår i strängarna, såvida dessa inte var omgivna med citationstecken) efter eventuell avtolkning av specialtecken (såsom * - alla filnamn). Antalet strängar och en pekare till vektorn av strängpekarna blir tillgängliga för programmet genom deklaration av två argument till main(), kallade av konvention argc resp. argv:... Bild 81 argc och argv Om programmet prog har startats med kommandoraden prog hej hopp 123 så ger det följande situation: main argc 4 argv prog\0 hej\0 hopp\0 123\0 Bild 82 6

argv - exempel 1 Filkonkatenering - genomgång med indexering: #include <stdio.h> void copyfile(file *out, char *fname){... char *myself=argv[0]; FILE *out; int i; if(argc<3) { fprintf(stderr, %s: Usage:.., myself); exit(1); if ((out=fopen(argv[1], w ))==NULL){ fprintf(stderr, %s: Can t open %s!, myself, argv[1]); exit(2); for(i=2; i<argc; i++) copyfile(out, argv[i]); fclose(out); return 0; Bild 83 argv - exempel 2 Filkonkatenering - genomgång med pekararitmetik: #include <stdio.h> void copyfile(file *out, char *fname){... char *myself=*argv; FILE *out=null; while (*++argv) if(out==null) if((out=fopen(*argv, w ))==NULL){ fprintf(stderr, %s: Can t open %s!\n,myself,*argv); exit(2); else copyfile(out, *argv); fclose(out); return 0; Bild 84 7

argv - exempel 3 Ett program med flaggor, kommandoexempel: prog -a fil1 -ab fil2 fil3 #include <stdio.h> void doonefile(char *fname, int a, int b){... char *myself=*argv; int a=0, b=0; while (*++argv) if (**argv== - ) while (*++*argv) switch(**argv){ case a : a=1; break; case b : b=1; break; default:fprintf(stderr, Unknown %c\n,**argv); else doonefile(*argv, a, b); return 0; Bild 85 argv - exempel 4 Flaggor med argument, kommandoexempel: prog -hinledning -p40 fil1 -havhandling -p50 fil2 #include <stdio.h> void doonefile(char *fname, char *h, int p){... char *myself=*argv, *h=null; int p=60; while (*++argv) if (**argv== - ) switch(*++*argv){ case h : h=++*arg; break; case p : p=atoi(++*argv); break; default:fprintf(stderr, Unknown %c\n,**argv); else doonefile(*argv, h, p); return 0; Bild 86 8

Strängar - konverteringsfunktioner I stdio.h: int sprintf(char *str, const char *format,...); int sscanf(char *str, const char *format,...); I stdlib.h: int atoi(const char *str); double atof(const char *str); long atol(const char *str); long strtol(const char *str, char **endp, int base); double strtod(const char *str, char **endp); Bild 87 9