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