Dagens föreläsning Repetition Egendefinierade datatyper och konstanter Programmeringsteknik för Ingenjörer VT05 Funktionsbibliotek Rekursion Föreläsning 6 Programmeringsteknik VT05 Repetition – Funktionsbegrepp 2 Repetition – Funktionsbegrepp #include <stdio.h> Aktuellt argument – Ett uttryck mellan paranteserna i funktionsanropet. /* Funktionsprototyp */ double pow2(double tal); pow2(5.0); int main (void) { printf("Kvadraten är: %.2f\n",pow2(5.0)); return 0; } Formell parameter – En identifierare som representerar värdet av det aktuella argumentet i funktionsdeklarationen. double pow2(double tal) { return (tal * tal); } /* Funktionsdefinition */ double pow2(double tal) { return (tal * tal); } Programmeringsteknik VT05 3 Repetition - Programflöde 4 Repetition - Överlagring • Programflödet är sekventiellt. • Sats efter sats i den beskrivna ordningen. • Återhoppet sker till anropsstället. ... funktion1() { ... sats; funktion2(); sats; ... } Programmeringsteknik VT05 C tillåter ej överlagring av funktionsnamn. /* Funktionsprototyper */ int fkn(int a); double fkn(int a); int fkn(double a); funktion2() { ... ... return ...; } Programmeringsteknik VT05 int fkn(int a, double b); Ej tillåtet ha flera funktionsprototyper med samma funktionsnamn, även om parametrar och returtyp skiljer. 5 Programmeringsteknik VT05 6 1 Konstanter Typdeklarationer Med typedef kan en datatyp associeras med en identifierare. Variabler kan därefter deklareras med identifieraren. Exempel - flyttalskonstant: #define RANTA 0.12 • • • • Exempel: typedef unsigned int coord_t; typedef double temp_t; #define – preprosessordirektiv. Gäller från exakt den punkt konstanten deklareras. STORA bokstäver på identifieraren. Inget semikolon (jämför #include). // Variabeldeklaration coord_t x, y; temp_t inne, ute; float inkomst = 10000.0; float summa = inkomst + inkomst * RANTA; Programmeringsteknik VT05 7 Programmeringsteknik VT05 Uppräkningsbara typer 8 Matematiska funktioner Med nyckelordet enum kan man skapa en datatyp med ett fixt antal kategorier. Tillhandahålls via math.h (Tabell 3.1 i Hanly,Koffman) Måste länkas in vid kompilering: Definition: gcc –lm –Wall –o körbar_fil fil.c typedef enum {identifierarlista} enum_type; Grundform: double math_func(double); Specialfall: double pow(double x, double y); int abs(int x); // OBS! Finns i <stdlib.h> double fabs(double x); double rint(double x); Exempel på deklaration av korttyp för en kortlek. typedef enum {heart, spade, diamond, club} suit_t; Programmeringsteknik VT05 9 Programmeringsteknik VT05 Konstanter i math.h 10 Exempel #include <stdio.h> #include <math.h> # # # # # # # # # # # # # define define define define define define define define define define define define define M_E M_LOG2E M_LOG10E M_LN2 M_LN10 M_PI M_PI_2 M_PI_4 M_1_PI M_2_PI M_2_SQRTPI M_SQRT2 M_SQRT1_2 2.7182818284590452354 1.4426950408889634074 0.43429448190325182765 0.69314718055994530942 2.30258509299404568402 3.14159265358979323846 1.57079632679489661923 0.78539816339744830962 0.31830988618379067154 0.63661977236758134308 1.12837916709551257390 1.41421356237309504880 0.70710678118654752440 /* /* /* /* /* /* /* /* /* /* /* /* /* e */ log_2 e */ log_10 e */ log_e 2 */ log_e 10 */ pi */ pi/2 */ pi/4 */ 1/pi */ 2/pi */ 2/sqrt(pi) */ sqrt(2) */ 1/sqrt(2) */ 11 (void) { height = 3.0; hyp = 5.0; angle_r, angle_d, base; r_to_d = 180.0 / M_PI; θ base sin angle_r = asin(height / hyp); angle_d = angle_r * r_to_d; base = hyp * cos(angle_r); printf("Vinkeln : %.2f\n", angle_d); printf("Basen är: %.1f\n", base); return 0; } Programmeringsteknik VT05 hyp height int main double double double double cos θ θ = height hyp = base hyp // Vinkeln: 36.87, Basen är: 4.0 Programmeringsteknik VT05 12 2 I/O funktioner double_out.c #include <stdio.h> /* i stdio.h finns raden #define EOF (-1) */ int main(void) { int c; printf(”Skriv tecken, avbryt med ^D”); while ((c = getchar()) != EOF) { putchar(c); putchar(c); } putchar(’O’); putchar(’K’); putchar(’\n’); return 0; } Läsa tecken (char) från tangentbordet: int getchar(); Skriva tecken till skärmen int putchar(int c); • Finns i stdio.h • putchar returnerar talet man skrev om allt ok. Programmeringsteknik VT05 13 Programmeringsteknik VT05 capitalize.c Assertions assert.h innehåller funktionen assert(). #include <stdio.h> int main(void) { int c; while ((c = getchar()) != EOF) { if (c >= ’a’ && c <= ’z’) putchar(’A’ + c - ’a’); else putchar(c); } return 0; } #include <assert.h> double div (double a, double b) { assert(b != 0); return a/b; } int main(void) { div(2, 0); /* assertion will fail */ } Programmeringsteknik VT05 15 Rekursion my_div: my_div.c:3: div: Assertion `b != 0' failed. Aborted Programmeringsteknik VT05 16 Rekursion En funktion i C får anropa sig själv. En rekursiv funktion måste hantera: • Basfallet. • Direkta eller indirekta rekursiva anrop. En funktion är rekursiv om den anropar sig själv. Alla funktioner kan anropas rekursivt. Varje anrop exekveras i en egen miljö med nya parametrar och nya lokala variabler. Inkarnation av funktionen. #include <stdio.h> int main(void) { printf("The universe is never ending\n"); main(); return 0; /* Kommer aldrig att nås */ } Programmeringsteknik VT05 14 När en inkarnation avslutas återges kontrollen till anroparen (som kan vara en inkarnation av samma fkn). 17 Programmeringsteknik VT05 18 3 Exempel Fakultet Summera de fyra första heltalen: sum(4); Matematiskt så lyder definitionen av fakultet som följer 0!=1, n!=n·(n-1) ·…·2·1 n>0 int sum(int n) { if (n == 1) // Basfall return 1; else return n + sum(n-1); } sum(4) Rekursiv fakultetsfunktion: int factorial(int n) { assert(n >= 0); if (n == 0) return 1; else return (n * factorial(n-1)); } = 10 = 4 + sum(3) =6 = 3 + sum(2) =3 = 2 + sum(1) =1 = 1 Programmeringsteknik VT05 19 Iterativ motsvarighet Programmeringsteknik VT05 20 fibonacci.c Funktionen kan också skrivas iterativt: Fibonaccisekvensen definieras som följer: ƒ0=0, ƒ1=1, ƒi+1=ƒi + ƒi-1 i=1,2,… int factorial (int n) { int product = 1; assert(n >= 0); long fib(long n) { if (n <= 1) return n; // basfallet else return fib(n-1) + fib(n-2); } for ( ; n > 1; n-- ) { product *= n; } return product; } Programmeringsteknik VT05 21 Programmeringsteknik VT05 22 Rekursion vs. Iteration BRA • Ofta enklare att skriva. • Lättare att förstå. • Lättare att underhålla. DÅLIGT • Många funktionsanrop. Ineffektivt. Programmeringsteknik VT05 23 4