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

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

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

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

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

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

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

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

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

Ulf Assarsson. Grundläggande C-programmering del 5 Applika'onsbyggnad/Spelprogrammering (real'dsstyrsystem) och Avancerad C.

Repetition C-programmering

Introduktion C-programmering

TDIU01 - Programmering i C++, grundkurs

Det finns många flaggor till g++,

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

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

Föreläsning 10. Pekare (Pointers)

Pekare och arrayer. Indexering och avreferering

C++-programmets beståndsdelar

Programmering, grundkurs, 8.0 hp HI1024, omtentamen, TEN1. Tisdagen den 7 juni 2011,

Structs och funktionspekare

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

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

Poster ( structar ) Postdeklarationer

TDIU01 - Programmering i C++, grundkurs

Att använda pekare i. C-kod

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

Funktionspekare, inledning: funktionsanropsmekanismen. Anrop via pekare

Arrays (indicerade variabler) Föreläsning 6

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

Assemblerprogrammering för ARM del 3

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

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

Arrays (indicerade variabler) Föreläsning 4

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

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

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

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

Innehåll. Pekare Exempel

Programmeringsteknik med C och Matlab

Tentamen *:58/ID100V Programmering i C Exempel 3

2 Pekare och dynamiska variabler.

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

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

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

En kort text om programmering i C.

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

Klassdeklaration. Metoddeklaration. Parameteröverföring

TDDC76 - Programmering och Datastrukturer

Programmering av inbyggda system. Kodningskonventioner. Viktor Kämpe

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

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

4 Sammansatta datatyper

2D1387, Programsystemkonstruktion med C++ Johnny Bigert, Kursassistent: Mårten Björkman,

Typkonvertering. Java versus C

Programmering, grundkurs, 8.0 hp HI1024, TEN1. Fredagen den 2 mars 2012

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

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

Programmering, grundkurs, 8.0 hp HI1024, extra tentamen, TEN1, för TIDAA1. Fredagen den 11 mars 2011,

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

Innehåll. Pekare Syntax

Innehåll. Pekare Exempel

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

6.1 Kompilering och lite grundläggande information

Programmering i C++ En manual för kursen Datavetenskaplig introduktionskurs 5p

Exempel ( )

Indexerade variabler

*Pekarvärden *Pekarvariabler & *

Föreläsning 2 Objektorienterad programmering DD1332. Typomvandling

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

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

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

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

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

GU / Chalmers Campus Lindholmen Tentamen Programutveckling LEU 482 / TIG167

Föreläsning 11. Strängar

TDDC77 Objektorienterad Programmering

Grunderna i C++ T A. Skapad av Matz Johansson BergströmLIMY

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

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

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

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

Grundläggande C-programmering

Tillämpad programmering

Tentamen Grundläggande programmering

Assemblerprogrammering, ARM-Cortex M4 del 3

Programsystemkonstruktion med C++

TDIU01 Programmering i C++

Funktioner och programstruktur. Föreläsning 5

Innehåll. Användardefinierade typer. Användardefinierade typer Kategorier. Konstruktorer. Konstruktorer Två sätt att skriva initiering av medlemmar

Programmering av grafisk display

C++ - En introduktion

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

Föreläsning 6: Metoder och fält (arrays)

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

Demonstration och konsultation Arbetsbokens avsnitt 5 och 6 LCD Grafisk display Introduktion till laboration 3

C-programmering del 4. Ulf Assarsson. extern, sta.c, Överkurs: const, inline, Gameloop, grafikloop, fraktalt berg

Filer och structer Del 2

TDDC76 - Programmering och Datastrukturer

Tillämpad programmering

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

Transkript:

Grundläggande C-programmering del 3 Ulf Assarsson Läromoment: Grundläggande C-programmering del 3 enum, union, byte-adressering med unions, include-guards Pekare och arrayer, 2D-arrayer dubbelpekare Kopplat.ll: Lab 5 - spelprogrammering Läsanvisningar: Översiktligt: STM32F407 reference manual s: 951-1002

C synlighet för deklara.oner Alla deklara.oner (variabler, funk.oner) och även usryck som typedefs + defines är synliga först nedanför dem ej ovanför dem. Källkodsfiler processas uppifrån och ned. Exempel: void fkn1(short param) if( ) return fkn2('a'); // fkn2 är här ännu okänd för C-kompilatorn så detta ger // kompileringsfel. return; void fkn2(char c) return; FortsäSning Pekare/VK 2

C synlighet för deklara.oner Alla deklara.oner (variabler, funk.oner) och även usryck som typedefs + defines är synliga först nedanför dem ej ovanför dem. Källkodsfiler processas uppifrån och ned. Exempel: void fkn2(char c); // Fix för att göra deklarationen av fkn2 känd redan här. // Vi får ha med deklarationen hur många ggr vi vill void fkn1(short param) void fkn2('a'); // Vi kan även lägga den här istället if( ) void fkn2('a'); // eller här return fkn2('a'); // Här är nu fkn2 känd return; void fkn2(char c) // Definitionen av fkn2 return; FortsäSning Pekare/VK 3

Preprocessor direc.ves - #if, #ifdef, #ifndef Preprocessor condi.onal inclusion #define X 1 // syntax: #define [identifier name] [value], där [value] är optional #if X == 0 // syntax: #if <value>, där 0=false och!0==true // any C-code #elif X-1 == 1 // betyder else if #else #endif #if 0 // bra för att temporärt kommentera bort stora block av kod. // any C-code #endif #define HW_DEBUG #ifdef HW_DEBUG // any C-code, t ex: #undef SIMULATOR #endif void delay_500ns(void) #ifndef SIMULATOR delay_250ns(); delay_250ns(); #endif FortsäSning Pekare/VK 4

Enumera.ons enum enum type_name value1, value2,..., valuen ; // type_name optional. By default, value1 = 0, value2 = value1 + 1, etc. enum type_name value1 = 0, value2, value3 = 0, value4 ; // helt OK. // Ger dock med gcc värdena: 0, 1, 0, 1 vilket kanske är ointuitivt. enum day monday=1, tuesday, wednesday, thursday, friday, saturday, sunday; enum day today; today=wednesday; printf("%d:th day",today+1); // output: "4:th day" typedef enum false, true bool; bool ok = true; --------------------------------------------------------------------------------- #define B_E 0x40 // GPIO-portexemplet med enums #define B_RST 0x20 #define B_CS2 0x10 #define B_CS1 8 #define B_SELECT 4 #define B_RW 2 #define B_RS 1 graphic_ctrl_bit_clear( B_RS B_RW ); Kan bytas ut mot: enum B_RS=1, B_RW=2, B_SELECT=4, B_CS1=8, B_CS2=0x10, B_RST=0x20, B_E=0x40; 5

Bonus Type Union Union allows to store different data types in the same memory loca.on. Same syntax as struct union opt_name int a; char b; float c; x; x.a = 4; x.b = 'i'; x.c = 3.0; &x.a == &x.b == &x.c a, b och c delar samma minnesadress. D v s samma minnesadress kan adresseras på tre olika säs via tre olika variabelnamn. typedef union float v[2]; struct float x,y;; Vec2f; Vec2f pos; pos.v[0] = 1; pos.v[1] = 2; pos.x = 1; pos.y = 2; Exempel: pos.v[0] och pos.x är samma sak. pos.x visar tydligt as det är x-koordinaten vi adresserar. pos.v[i] är dock användbart om vi vill skriva en loop över x- och y-koordinaten. Tex: Vec2f addvec(vec2f a, Vec2f b) for(i=0; i<2; i++) a.v[i] += b.v[i]; return a; 6

Endian Big endian / LiSle endian Vi använder lisle endian. ARM Cortex-m4 klarar båda. Kodningskonven.oner/VK 7

Byte-adressering med unions för GPIO-porten // GPIO typedef struct _gpio uint32_t moder; uint32_t otyper; uint32_t ospeedr; uint32_t pupdr; union uint32_t idr; struct byte idrlow; byte idrhigh; ; ; union uint32_t odr; struct byte odrlow; byte odrhigh; ; ; GPIO; #define GPIO_D (*((vola.le GPIO*) 0x40020c00)) #define GPIO_E (*((vola.le GPIO*) 0x40021000)) GPIO Input Data Register (IDR) offset 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 mnemonic 0x10 RESERVERADE r r r r r r r r r r r r r r r r IDR 0x11 0x10 Bitar 16 tom 31 används inte och ska hållas vid sitt RESET-värde, dvs 0. Nu kan idrhigh adresseras med: byte c = GPIO_E.idrHigh; Istället för med: byte c = *((byte*)&(gpio_e.idr) + 1)); ES.ll exempel: GPIO_E.odrLow &= ( ~B_SELECT & ~x); Istället för: *((byte*)&(gpio_e.odr)) &=(~B_SELECT & ~x); FortsäSning Pekare/VK 8

Include guards Include guards används för as automa.skt undvika as inkludera en.h-fil mer än en gång per.c-fil. DeSa kan annars hända om en.c-fil inkluderar flera.h-filer som i sin tur inkluderar samma.h-fil. FortsäSning Pekare/VK 9

Include guards // main.c #include "player.h" #include "enemies.h" // vecmath.h #ifndef VECMATH_H #define VECMATH_H // player.h #ifndef PLAYER_H #define PLAYER_H // enemies.h #ifndef ENEMIES_H #define ENEMIES_H void main() typedef struct union int v[2]; struct int x, y;; ; Vec2i; #include "vecmath.h" void moveplayer(vec2i v); #endif //PLAYER_H #include "vecmath.h" void moveenemy(int i, Vec2i v); #endif //ENEMIES_H Vec2i add2i(vec2i a, Vec2i b); c-fil char isequal(vec2i a, Vec2i b); #endif //VECMATH_H Vi bör ha include-guards på alla.h-filer även om det i desa exemplet inte behövs för player.h samt enemies.h Utan include guards så inkluderas vecmath.h två gånger för main.c. Andra gången kommer kompilatorn klaga på as Vec2i redan är definierad..c-filer kompileras var för sig. Preprocessorn och kompilatorn exekveras individuellt per.c-fil. 10

Bonus C non-standard extensions Följande finns som extensions.ll C Stöds typiskt inte alls i C++ Dessa stöds i C99 men typiskt ej i C89 / C11 (möjligen som op.onal för kompilaror-.llverkaren). FortsäSning Pekare/VK 11

C nested/local func.ons are compilerop.onal extensions to C Bonus VC++ (dvs Visual Studio C++) och GNU C++ stödjer inte lokala funk.oner. Det gör däremot ARM-gcc och MinGW-gcc. void fkn(double a, double b) double square (double z) return z * z; return square (a) + square (b); FortsäSning Pekare/VK 12

C nested/local func.ons are compilerop.onal extensions to C Bonus VC++ (dvs Visual Studio C++) och GNU C++ stödjer inte lokala funk.oner Det gör däremot ARM-gcc och MinGW-gcc. void main() void fkn(int *array, int offset, int size) int access (int *array, int index) return array[index + offset]; int i; for (i = 0; i < size; i++) access (array, i); int a[] = 1,2,3,4,5, offs=0, size = 5; fkn(a, offs, size); Den lokala funk.onen har t.o.m..llgång.ll omgivande scope s hizlls deklarerade variabler. FortsäSning Pekare/VK 13

Bonus C99 variable-length arrays (Op.onal in C11) void fkn(int len) char str1[10]; // längd känd i compile time. char str2[len]; // längd ej känd i compile time men i run time. str2 är en variable-length array (C99) FortsäSning Pekare/VK 14

Bonus C99 struct ini.a.on med.medlem, Initiering med.medlem =... tillåter oss att endast initiera valfria medlemmar. Exempel: struct Tst int a; char b; ; struct Tst x1 =.b = 'z' ; // ofullständig initiering struct Tst x2 =.b = 'z,.a = 5 ; // initiering i valfri ordning struct Tst x3 =.a = 5,.b = 'z' ; // initiering i valfri ordning FortsäSning Pekare/VK 15

Varför pekare? #include <stdlib.h> void inc(int x, char y) x++; y++; Några exempel: Skriva.ll / Läsa från portar Indexera fortare i arrayer Slippa kopiera inputparametrar Ändra inputparametrarna Pekare.ll funk.oner -> objektorienterad s.l #include <stdlib.h> 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 eer funk.onsanropet 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 eer funk.onsanropet Introduk.on C-programmering 16

Array - Likhet 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 ; // eersom s2 är adress så kan vi dereferera den // precis som för en pekare Pekare och Arrayer/VK 17

Indexering #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] ); return 0; x[y] översäss.ll *(x+y) och är alltså es säs as dereferera en pekare. Pekare och Arrayer/VK 18

char* s1 = "Emilia"; char s2[] = "Emilia"; Skillnader mellan array och pekare Arrayer s2 är symbol och kan ej ändra värde. Värdet är s2 s adress i minnet. Adress känd i compile-.me. Storlek känd i compile-.me. Storlek för pekare är storlek på adress vilket är 4 bytes på 32-bitssystem. Pekar-aritme.k möjligt men ej as försöka ändra symbolens värde. char a[] = hej ; a++ ej OK (a+1)[0] helt OK. a är en symbol för adressen.ll h. char* p = a; p är en variabel som går as ändra och här säss.ll a, dvs adressen för h. Pekare och Arrayer/VK 19

Array (Fält) #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] ); // pekararitmetik går även utmärkt för s2 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; 20

Arrayer som funk.onsargument blir pekare void foo(int pi[]); void foo(int *pi); [ ] nota.onen finns, men betyder pekare! Undviker as hela arrayen kopieras. Längd inte all.d känd i compile.me. Adressen.ll arrayen läggs på stacken och accessas via stackvariabeln pi. (En struct kopieras och läggs på stacken). Pekare och Arrayer/VK 21

Antal bytes med sizeof() #include <stdio.h> char* s1 = "Emilia"; char s2[] = "Emilia"; sizeof är en inbyggd operator i C som returnerar storlekten hos typen i antal bytes. 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-.me. En (av få) undantag där arrayer och pekare är olika. Pekare och Arrayer/VK 22

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 Pekare och Arrayer/VK 23

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) = Pekare och Arrayer/VK 24

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; FortsäSning Pekare/VK 25

Pekare.ll pekare (dubbelpekare) char *p1, *p2, *p3; char **pp; pp = &p1; Pointer Pointer Variable address address value // Annat exempel. Funktion som allokerar minne dynamiskt, t ex för elaka fiender i ett spel void allocateenemyarray(struct Enemy **pp, int n) *pp = (struct Enemy *)malloc(n * sizeof(struct Enemy)); int main() struct Enemy *penemies = NULL; allocate(&penemies, 100); // Game logic free(penemies); Ska funk.onen kunna uppdatera argumentet måste vi skicka in adressen för argumentet (istället för värdet på argumentet) Jämför med: void inc(int *x, char *y) (*x)++; (*y)++; int var1 = 2; char var2 = 7; inc(&var1, &var2); 26

Pekare.ll pekare (dubbelpekare) #include <stdio.h> #include <conio.h> char* s1 = "Emilia"; // variabeln s1 är en variabel som går att ändra, och vid start tilldelas värdet av adressen till 'E': char s2[] = "Emilia"; // värdet på s2 känt vid compile time. s2 är konstant, dvs ingen variabel som går att ändra. Är adressen till 'E. int main() char** pp; char* p = s1; // == &(s1[0]) pp = &p; *pp = s2; // ändrar p till s2 **pp = 'A'; // ändrar s2[0] till 'A' printf("%s\n", p); return 0; Pekare och Arrayer/VK 27

Dubbelpekare. Exempel int main() char s1[] = "Emilia"; char **pp, *p; -- MODIFIERA s1 via dubbelpekaren pp--- printf("s1 = %s", s1); return 0; Om ni är klara gör trippelpekare etc Kodningskonven.oner/VK 28

Dubbelpekare. Lösning int main() char s1[] = "Emilia"; char **pp, *p; p = &s1[0]; // p = adressen till 'E' // eller p = s1; // dvs p pekar på arrayen s1. pp = &p; **pp = 'A // eller (*pp)[0] = 'A'; *(*pp + 2) = 'e'; // pp pekar på pekaren p // dubbel avreferering av "pp som pekar på p som pekar på 'E'". // *pp pekar på p. Så det blir: p[0] = 'E' // *(p + 2). Dvs innehållet i (p + 2) tilldelas 'e. printf("s1 = %s", s1); getch(); return 0; Kodningskonven.oner/VK 29

Övningsuppgier om ni vill Skriv ned en struct Definiera en struct. Accessa en structmedlem via en pekare till structen. Dvs -> -notation. Skriv en funktion som clear:ar en variabel (sätter den = 0) så att man kan skriva t ex int a; clear(a); Skriv ned en union (som innehåller en enum) Vad är skillnaden mellan char* str = hej ; resp. char str[] = hej ; Skapa en funktionspekare till en funktion som tar en int-parameter och returnerar en float. Anropa funktionen och tilldela värdet till variabel a. 30