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

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

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

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

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

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

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

Ulf Assarsson. Grundläggande C-programmering del 3. Läromoment: Grundläggande C-programmering del 3

Ulf Assarsson. Grafisk display + seriekommunika3on (USART) Läromoment: USART Grundläggande C-programmering del 2

Assemblerprogrammering för ARM del 3

Repetition C-programmering

Introduktion C-programmering

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

Föreläsning 10. Pekare (Pointers)

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

Att använda pekare i. C-kod

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

Programmering av inbyggda system. Kodningskonventioner. Viktor Kämpe

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

TDIU01 - Programmering i C++, grundkurs

Grundläggande C-programmering del 1 - För maskinorienterad programmering

Grundläggande C-programmering del 1 - För maskinorienterad programmering

Structs och funktionspekare

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

Grundläggande C-programmering del 4 Mer programstruktur samt Dynamisk minnesallokering Ulf Assarsson

Indexerade variabler

Tentamen med lösningsförslag

*Pekarvärden *Pekarvariabler & *

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

2 Pekare och dynamiska variabler.

En kort text om programmering i C.

Det finns många flaggor till g++,

Arrays (indicerade variabler) Föreläsning 6

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

Pekare och arrayer. Indexering och avreferering

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

TDDC76 - Programmering och Datastrukturer

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

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

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

Arrays (indicerade variabler) Föreläsning 4

4 Sammansatta datatyper

Funktionspekare, inledning: funktionsanropsmekanismen. Anrop via pekare

Poster ( structar ) Postdeklarationer

Assemblerprogrammering, ARM-Cortex M4 del 3

Grundläggande C-programmering

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

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

6.1 Kompilering och lite grundläggande information

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

PC-teknik, 5 p LABORATION ASSEMBLERINTRODUKTION

Lathund. Pacific C för MS-DOS

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

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

Föreläsning 2 Objektorienterad programmering DD1332. Typomvandling

TDIU01 - Programmering i C++, grundkurs

6 Lågnivåprogrammering

Föreläsning 12. struct

Klassdeklaration. Metoddeklaration. Parameteröverföring

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

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

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

Enkla datatyper minne

Funktioner och programstruktur. Föreläsning 5

Indicerade variabler

Kontrollskrivning Mikrodatorteknik CDT S2-704

översiktskurs (5DV031)

GU / Chalmers Campus Lindholmen Tentamen Programutveckling LEU 482 / TIG167

Innehåll. Pekare Syntax

Föreläsning 9. struct

Parameteröverföring. Exempel. Exempel. Metodkropp

Assemblerprogrammering för ARM del 2

Föreläsningsanteckningar, Introduktion till datavetenskap HT S4 Datastrukturer. Tobias Wrigstad

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

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

LEU240 Mikrodatorsystem

TDDC76 - Programmering och Datastrukturer

TDIU20 - Objektorienterad programmering i c++ - föreläsning 4

Innehåll. Pekare Exempel

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

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

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

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

Funktioner och programstruktur. Föreläsning 5

Classes och Interfaces, Objects och References, Initialization

Föreläsning 6 pekare och pekare tillsammans med arrayer

C++-programmets beståndsdelar

Assemblerprogrammering - fördjupning

Programmering i C++ EDA623 Mer om klasser. EDA623 (Föreläsning 6) HT / 26

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

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

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

Tentamen med lösningsförslag

Tentamen *:58/ID100V Programmering i C Exempel 3

Dagens föreläsning. Diverse Common Lisp. Konstanter, parametrar, globala variabler

Digital- och datorteknik

Data, typ, selektion, iteration

(Man brukar säga att) Java är... Denna föreläsning. Kompilering av Java. Historik: Java. enkelt. baserat på C/C++ Allmänt om Java

Classes och Interfaces, Objects och References Objekt-orienterad programmering och design (DIT952) Niklas Broberg, 2016

C konstruerades i början på sjuttiotalet av Dennis Ritchie vid Bell Laboratories.

Digital- och datorteknik

Transkript:

Grundläggande C-programmering del 2 Pekare och Arrayer Ulf Assarsson Läromoment: Pekare Absolutadressering (portar): typedef, volafle, #define Arrayer av pekare, arrayer av arrayer Hemuppgi9er: v2.

Föregående lekfon C-syntax Programstruktur, kompilering, länkning BitoperaFoner se övningsuppgi9erna 2

Pekare A pointer is essenfally a simple integer variable that holds a memory address of a value (variable or port), instead of holding the actual value itself. 3

Varför pekare? Kunna referera Fll ev objekt eller variabel, dvs utan av behöva skapa en kopia char namn1[] = "Elsa"; char namn2[] = "Alice"; char namn3[] = "Maja"; char *längstnamn = namn2; Man kan säga av längstnamn refererar Fll namn2, men vi kallar det inte referens utan pekare. Dvs längstnamn pekar på namn2. 4

Varför pekare? #include <stdlib.h> Skriva Fll /Läsa från portar Indexera fortare i arrayer Slippa kopiera inputparametrar Ändra inputparametrarna #include <stdlib.h> void inc(int x, char y) { } x++; y++; void inc(int *x, char *y) { } (*x)++; (*y)++; Argumenten är pass-by value i C. int var1 = 2; char var2 = 7; inc(var1, var2); var1 och var 2 har for]arande värdena 2 resp 7 e9er funkfonsanropet Argumenten är pass-by value i C. int var1 = 2; char var2 = 7; inc(&var1, &var2); var1 och var 2 har nu värdena 3 resp 8 e9er funkfonsanropet 5

Pekare Pekarens värde är en adress. Pekarens typ berävar hur man tolkar bitarna som finns på adressen. // array av chars char str[] = abc"; Vi hämtar värdet som ligger på adressen som ligger i p. // p pekare till char char* p = str; // == &str[0] == &(str[0]) *p; // värdet p pekar på är 'a' *p = 'b'; MOV R0, #'b LDR R1, p STRB R0, [R1] - skriv Fll *p LDR R0, =str LDR R1, =p STR r0, [R1] LDR R0, p LDRB R0, [R0] - läs *p 6

Pekare Pekarens värde är en adress. Pekarens typ berävar hur man tolkar bitarna som finns på adressen. 'c' 'b' char* p = str; // == 0x20030104 0x20030104 0110 0001 'a' typ p s värde är en adress... 0x00000001 0x00000000 Ökande adresser 7

Dereferera När vi derefererar en pekare så hämtar vi objektet som ligger på adressen. Antalet bytes vi läser beror på typen Tolkningen av bitarna beror på typen signed char 8 bitar 1111 1111 unsigned char -1 255 char är ev 8-bits värde, dvs ev 8-bits tal. EV tal kan motsvara en bokstav via ASCII-tabellen. 8

Operatorer på pekare (& *) #include <stdio.h> int main() { char a, b, *p; a = 'v'; b = a; p = &a; DeklaraFon av pekare Adressen av... } printf("b = %c, p = 0x%p (%c) \n", b, p, *p); a = 'k'; printf("b = %c, p = 0x%p (%c) \n", b, p, *p); Dereferering Utski9: b = v, p = 0x0027F7C3 (v) b = v, p = 0x0027F7C3 (k) 9

Asterisken (*) betyder I deklarafoner Pekartyp Som operator Dereferens ( av-referera ) char *p; char* p; void foo(int *pi); char a = *p; *p = 'b'; 10

Luring Antag *a = 2 Vad ger: int x=1.0/*a;? 11

Pekare - översikt Dvs, om a s värde är en adress, så är *a vad adressen innehåller. &a -> Adress till variabel a. Dvs minnesadress som a är lagrat i. a -> variabelns värde (t ex int, float eller en adress om a är pekarvaribel) *a -> Vad variabel a pekar på (här måste a's värde vara en giltig adress och a måste vara av typen pekare). a s värde är en adress till en annan variabel eller port. Vi hämtar värdet för den variabeln/porten. Exempel för pekarvariabel p: Adress för c: 0x2001bff3 118 ('v')... *p är värdet som p pekar på, dvs 'v' char c = 'v'; char* p = &c; *p == c; Adress för p: 0x2001c026 p s värde 0x2001bff3... Ökande adresser 12

C vs Assembler C Assembler Betyder v; v:.space 4 skapa adress för v (t ex 4 bytes för integer) &v; LDR R0, =v v s adress (t ex 0x2001c010) v; LDR R0, v v s värde (t ex 5) *v; LDR R0, [v] värdet som ligger på v måste här vara pekare, men finns inte på m4 adressen som ligger i v. t ex int *v; så man får skriva: T ex: v = 0x2001c004 LDR R7, v Ladda v s värde (R7=0x2001c004) LDR R0, [R7] Hämta innehållet på adress 0x2001c004 (4 bytes). 13

Pekare - lathund t *p; p får typen pekare Fll typen t p = 0; p blir en tom pekare (pekar ej på något) p = &v; p Flldelas adressen Fll variabeln v *p betyder det som p pekar på p1 = p2; p1 kommer peka på samma som p2 *p1 = *p2; det som p1 pekar på kommer av ändras 14

AritmeFk på pekare char *kurs = "Maskinorienterad Programmering"; *kurs; *(kurs+2); kurs++; kurs +=4; // 'M // 's // kurs pekar på 'a // kurs pekar på 'n' Man ökar p med (n * typstorlek) int a[] = {2,3,4,10,8,9}; short int b[] = {2,3,4,10,8,9}; float c[] = {1.5f, 3.4f, 5.4f, 10.2f, 8.3f, 2.9f}; int *p = a; // == &(a[0]) p++; // *p == a[1] short int *p2 = b; float *p3 = &(c[2]); 15

[Övningsuppgi9]

Absolutadressering Vid portadressering så kan vi ha en absolut adress (t ex 0x40011004). 17

Absolutadressering 0x40011000 // ett hexadecimalt tal (unsigned char*) 0x40011000 // en unsigned char pekare som pekar på adress 0x40011004 *((unsigned char*) 0x40011000) // dereferens av pekaren // läser från 0x40011000 unsigned char value = *((unsigned char*) 0x40011000); // skriver till 0x40011004 *((unsigned char*) 0x40011004) = value; Men vi måste lägga Fll volafle om vi har på opfmeringsflaggor...! 18

Läsbarhet med typedef typedef unsigned char* port8ptr; #define INPORT_ADDR 0x40011000 #define INPORT *((port8ptr)inport_addr) 0x40011000 (unsigned char*) 0x40011000 *((unsigned char*) 0x40011000) INPORT_ADDR (port8ptr)inport_addr INPORT // läser från 0x40011000 value = *((unsigned char*) 0x40011000); // läser från 0x40011000 value = INPORT; typedef förenklar/förkortar uvryck, vilket kan öka läsbarheten. typedef unsigned char* port8ptr; typ alias/typnamn 19

VolaFle qualifier char * inport = (char*) 0x40011000; void foo(){ } while(*inport!= 0) { //... } En kompilator som opfmerar kanske bara läser en gång (eller inte alls om vi aldrig skriver Fll adressen från programmet). 20

VolaFle qualifier volatile char * inport = (char*) 0x40011000; void foo(){ } while(*inport!= 0) { //... } volatile hindrar vissa opfmeringar (vilket är bra och här nödvändigt!), ty anger av kompilatorn måste anta av innehållet på adressen kan ändras uffrån. Vårt Fdigare exempel, nu korrekt med volafle: unsigned char value = *((volatile unsigned char*) 0x40011000); // läser från 0x40011004 *((volatile unsigned char*) 0x40011004) = value; // skriver till 0x40011004 21

SammanfaVning portar Inport: typedef volatile unsigned char* port8ptr; #define INPORT_ADDR 0x40011000 #define INPORT *((port8ptr)inport_addr) Utport: typedef volatile unsigned char* port8ptr; #define UTPORT_ADDR 0x40011004 #define UTPORT *((port8ptr)utport_addr) // läser från 0x40011000 value = INPORT; // skriver till 0x40011004 UTPORT = value; 22

Array (Fält) #include <stdio.h> char namn1[] = {'E', 'm', 'i', 'l', '\0'}; char namn2[] = "Emilia"; char namn3[10]; int main() { printf("namn1: %s \n", namn1); printf("namn2: %s \n", namn2); printf("sizeof(namn2): %i \n", sizeof(namn2)); Om ingen storlek anges i [ ] så blir arrayen Fllräckligt stor. OBS. Ini6ering funkar bara vid defini6on. 10 element stor array. } return 0; Utskri9: namn1: Emil namn2: Emilia sizeof(namn2): 7 23

Indexering samma för array/pekare #include <stdio.h> char* s1 = "Emilia"; char s2[] = "Emilia"; int main() { // tre ekvivalenta sätt att dereferera en pekare printf("'l' i Emilia (version 1): %c \n", *(s1+3) ); printf("'l' i Emilia (version 2): %c \n", s1[3] ); printf("'l' i Emilia (version 3): %c \n", 3[s1] ); // tre ekvivalenta sätt att indexera en array printf("'l' i Emilia (version 1): %c \n", *(s2+3) ); printf("'l' i Emilia (version 2): %c \n", s2[3] ); printf("'l' i Emilia (version 3): %c \n", 3[s2] ); } return 0; x[y] översävs Fll *(x+y) och är alltså ev säv av dereferera en pekare. Indexering är samma för pekare som för array. 24

Array Likhet/olikhet med pekare Har en adress och en typ. char s2[] = "Emilia"; - sizeof(s2) == 7 - Men sizeof(char*) == 4; Indexering har samma resultat. char* s1 = "Emilia"; char s2[] = "Emilia"; s1[0] = E ; s2[0] = E ; *s1 == E ; *s2 == E ; // e9ersom s2 är adress så kan vi dereferera den // precis som för en pekare 25

Array Likhet/olikhet med pekare char* s1 = "Emilia"; char s2[] = "Emilia"; s2 Typ: Array Pekarvariabel Adressering: PekararitmeFk: &s2 ej möjligt ty s2 endast symbol s2 = arrayens startadress. s2 = &(s2[0]) s2[0] = *s2 = 'E' s2++ ej möjligt (s2+1)[0] helt OK s1 &s1 = adress för variabeln s1. s1 = strängens startadress. s1 == &(s1[0]) s1[0] = *s1 = 'E' s1++ helt OK (s1+1)[0] helt OK Typstorlek: sizeof(s2) == 7 bytes sizeof(s1) == sizeof(char*) == 4 bytes s2 är endast symbol (ej variabel.) för adress som är känd i compile Fme. E9ersom s2 är adress så kan vi dereferera den precis som för en pekare: *s2 == E 26

Indexering fler exempel #include <stdio.h> #include <conio.h> char * s1 = "Emilia"; // s1 är pekare. Variabeln s1 är en variabel som går att ändra, och vid start tilldelas värdet av adressen till 'E : char s2[] = "Emilia"; // s2 är array. Värdet på symbolen s2 är känt vid compile time. Symbolen s2 är konstant, dvs ingen variabel som går att ändra. Är adressen till 'E. int main() { // tre ekvivalenta sätt att dereferera en pekare printf("'l' i Emilia (version 1): %c \n", *(s1+3) ); printf("'l' i Emilia (version 2): %c \n", s1[3] ); printf("'l' i Emilia (version 3): %c \n", 3[s1] ); printf("'l' i Emilia (version 3): %c \n", *(s2+3) ); printf("'l' i Emilia (version 3): %c \n", (s2+3)[0] ); char a[] = "hej"; (a+1)[0] = 'o'; char* p = a; p = "bye"; // funkar. Strängen bye" allokeras i compile time i strängliteralminne. char b[10]; // b blir 10 element stor och får adressvärde // b = "då"; // här försöker vi ändra b's värde och det GÅR inte. printf("%s\n", p); } return 0; 27

Arrayer som funkfonsargument blir pekare void foo(int pi[]); void foo(int *pi); [ ] notafonen finns, men betyder pekare! Undviker av hela arrayen kopieras. Längd inte allfd känd i compile Fme. Adressen Fll arrayen läggs på stacken och accessas via stackvariabeln pi. (En struct kopieras och läggs på stacken). 28

Antal bytes med sizeof() #include <stdio.h> char* s1 = "Emilia"; char s2[] = "Emilia"; int main() { printf("sizeof(char): %i \n", sizeof(char) ); printf("sizeof(char*): %i \n", sizeof(char*) ); printf("sizeof(s1): %i \n", sizeof(s1) ); printf("sizeof(s2): %i \n", sizeof(s2) ); } return 0; sizeof(char): sizeof(char*): sizeof(s1): sizeof(s2): 1 4 4 7 Sizeof utvärderas i compile-fme. En (av få) undantag där arrayer och pekare är olika. 29

Array av pekare #include <stdio.h> char *fleranamn[] = {"Emil", "Emilia", "Droopy"}; int main() { printf("%s, %s, %s\n", fleranamn[2], fleranamn[1], fleranamn[0]); } return 0; Droopy, Emilia, Emil sizeof(fleranamn) = 12; // 3*sizeof(char*) = 3*4 = 12 30

Array av arrayer #include <stdio.h> char kortanamn[][4] = {"Tor", "Ulf", "Per"}; int main() { printf("%s, %s, %s\n", kortanamn[2], kortanamn[1], kortanamn[0]); } return 0; Per, Ulf, Tor sizeof(kortanamn) = 31

Array av arrayer #include <stdio.h> int arrayofarrays[3][4] = { {1,2,3,4}, {5,6,7,8}, {9,10,11,12} }; int main() { int i,j; for( i=0; i<3; i++) { printf("arrayofarray[%i] = ", i); } for ( j=0; j<4; j++) printf("%i ", arrayofarrays[i][j]); printf("\n"); } return 0; 32

Nästa föreläsning: Structs, funkfonspekare