Download de presentatie
De presentatie wordt gedownload. Even geduld aub
GepubliceerdMargaretha Verbeke Laatst gewijzigd meer dan 10 jaar geleden
1
p. 1 Deel I: Programmeertaal C 4. Functies en Macro’s Prof.Dr.Ir. Filip De Turck
2
p. 2 Vakgroep Informatietechnologie Overzicht 1.Concept en C-implementatie 2.Definitie/declaratie van functies 3.Oproepen van functies: call by value 4.Storage classes en scope 5.Macro’s 6.Functies met willekeurig aantal argumenten (…)
3
p. 3 Vakgroep Informatietechnologie Functies 6 lessen = basisblok van gestructureerd paradigma : Call & Return programmeermethodiek “stapsgewijze verfijning” Niveau 1 Probleemstelling stap 1stap 2stap 3 stap 1.1 stap 1.2 stap 2.2 stap 2.3 stap 2.1 stap 2.2 stap 3.1 stap 1.2.1 stap 1.2.2 stap 3.1.1 stap 3.1.2 stap 3.1.3 Niveau 2 Niveau 3 Niveau van detail
4
p. 4 Vakgroep Informatietechnologie De procedurale abstractie Divide et impera: beheers complexiteit door decompositie in functionele blokken (functies) Ieder blok: verbergt complexiteit (implementatie-details) biedt goed gedefinieerde interface aan voor “gebruiker” “gebruiker” dient enkel de interface (= uitwendige black-box beschrijving) te kennen Stel blokken samen tot andere met complexere functionaliteit
5
p. 5 Vakgroep Informatietechnologie De procedurale abstractie 6 lessen (triviaal) voorbeeld: functie die argument verdubbelt int verdubbel(int a) { return(a+a); } int verdubbel(int a) { return(2*a); } interface dezelfde implementatie verschillend! gebruiker kent enkel interface (= functie prototype) int verdubbel(int);
6
p. 6 Vakgroep Informatietechnologie Overzicht 1.Concept en C-implementatie 2.Definitie/declaratie van functies 3.Oproepen van functies: call by value 4.Storage classes en scope 5.Macro’s 6.Functies met willekeurig aantal argumenten (…)
7
p. 7 Vakgroep Informatietechnologie C-functies 6 lessen {type} opt functie_naam(parameter_lijst) { {declaratie} 0+ {opdracht} 0+ } Type van de functie: default int (te vermijden!) Voorbeelden: double bepaalE(){ … } void drukIetsAf(){ … } int verdubbel(int x) { … } double sommeer(double a,double b,double c) { … } tel_op(int a,int b) { …}
8
p. 8 Vakgroep Informatietechnologie Input: parameterlijst De functiedefinitie bevat formele parameterlijst = lijst van nog niet ingevulde variabelen Formele parameters worden bij functie-oproep ingevuld (evt. worden widening-conversies uitgevoerd) voorbeeld: double macht(double grondtal,int exponent){ … } geheel_deel(double x) { … } int is_lower_case(char c) { … } long double bepaal_pi(void) { … }
9
p. 9 Vakgroep Informatietechnologie Output: return uitdrukking van type van de functie (al dan niet via conversie) niet bij void functies meer dan 1 return statement toegelaten! automatische return indien niet opgegeven en het einde van de functie bereikt return {uitdrukking} opt ; voorbeeld double macht(double x,int e) { double res=1.0; int i=0; for(i=0;i<e;i++) res*=x; return res; }
10
p. 10 Vakgroep Informatietechnologie Declaratie Functie moet gedeclareerd worden VOOR gebruik 2 oplossingen (anders: default-declaratie): definieer alle functies VOOR ze gebruikt worden (niet altijd mogelijk!) gebruik een functie-prototype {type} opt functie_naam(proto_lijst); niet_lege_proto_lijst ::= {type {naam} opt } {, type {naam} opt } 0+ lege_proto_lijst ::=
11
p. 11 Vakgroep Informatietechnologie Declaratie int f(int a,int b); f(int a,int b); f(int,int); f(); double g(int a,doube d); double g(int a,double d); double g(int,double); double g(); Plaats prototypes van een compilatie-eenheid in bijhorende header file ! #include “functies.h”... int f1(double a) {…} double f2(int a,int b) {…} f3(double x,double y) {…} f4() {…} int f1(double); double f2(int,int); f3(double,double); f4( void ); functies.c functies.h
12
p. 12 Vakgroep Informatietechnologie “Traditional C-syntax” int f(int a,int b) {... } lege prototypelijst alternatieve vorm van parameterlijst int f(a, b) int a,b; {...} int g(double a,int b,char c) {... } int g(a, b, c) int b; double a; char c; {...} ANSI-C Traditional-C
13
p. 13 Vakgroep Informatietechnologie Voorbeeld: ASCII #include void print_lijn(int); void print_titel(void); void print_ascii_tabel(char,char); int main(void) { print_lijn(40); print_titel(); print_ascii_tabel('A','z'); print_lijn(40); return 0; } void print_lijn(int n){ int i=0; putchar('\n'); for(i=0;i<n;i++) putchar('-'); putchar('\n'); }
14
p. 14 Vakgroep Informatietechnologie Voorbeeld: ASCII (2) void print_titel(void) { printf("\nDe ASCII-tabel : \n"); } void print_ascii_tabel(char s,char e) { char c; for(c=s;c<=e;c++) printf("%c : %d\t",c,c); }
15
p. 15 Vakgroep Informatietechnologie Functie-oproep Kan overal gebruikt worden waar uitdrukking van zelfde type toegelaten is Effect: 1. argumenten worden geëvalueerd 2. waarde van elk argument wordt toegekend aan formele parameter van functiedefinitie 3. controle wordt overgedragen aan functie 4. resultaatwaarde (return value) vervangt functie-oproep (evt. na conversie) in de oproepende context Indien prototype gebruikt: compiler dwingt consistentie formele en actuele parameterlijst af!
16
p. 16 Vakgroep Informatietechnologie Call-by-value WAARDE wordt doorgegeven indien het NIET om een adres gaat KAN EEN FUNCTIE-OPROEP NOOIT DE WAARDE VAN EEN VARIABELE UIT DE OPROEPENDE CONTEXT WIJZIGEN #include void bepaal_opvolger(char); int main(void) { char a='a'; printf("a=%c\n",a); bepaal_opvolger(a); printf("a=%c\n",a); return 0; } void bepaal_opvolger(char a) { a++; }
17
p. 17 Vakgroep Informatietechnologie Scoping & storage class basics Variabele wordt gekenmerkt door type zichtbaarheid levensduur opgegeven bij declaratie bepaald door plaats van declaratie scoping rules opslagmodaliteiten storage class basis scoping rule variabele is zichtbaar in blok waarin gedeclareerd
18
p. 18 Vakgroep Informatietechnologie Scope {… int a, b; { int c, d; { int e, f; } bereik a,b bereik c,d bereik e,f name hiding/masking Als naam in genest blok = naam in buitenblok -> variabele in buitenblok gemaskeerd
19
p. 19 Vakgroep Informatietechnologie Name hiding {… int a=1; int b=2; { int a=10; float b=20.0; printf(“a=%d b=%f”,a,b); } printf(“a=%d b=%d”,a,b); } Gebruik parallelle blokken: spaart geheugen! geneste blokken: bij debuggen van programma’s
20
p. 20 Vakgroep Informatietechnologie Storage class basics Beïnvloeden van zichtbaarheid/levensduur variabele auto = default storage class voor variabelen binnen blok gedeclareerd lokale variabelen van een blok : worden gecreëerd bij start blok worden vernietigd bij eindigen blok -> levensduur = blok CategorieSleutelwoorden Storage Class Specifiers auto extern register static
21
p. 21 Vakgroep Informatietechnologie Storage class extern = default storage class voor variabelen buiten blok gedeclareerd (kunnen niet auto/register zijn!) globale variabele voor het programma! naam gedefinieerd in zelfde compilatie-eenheid naam gedefinieerd in andere compilatie-eenheid -> levensduur = permanent tijdens de uitvoeringstijd programma int a=1; int f3(void) { return a=3; } int f2(void) { extern int a; return a=2; } bestand1.c bestand2.c
22
p. 22 Vakgroep Informatietechnologie Storage class extern Opmerking: alle functies zijn extern doorgeven van informatie aan functies gebeurt via parameters, en niet via globale variabelen register = tip aan compiler om variabele in processorregister op te slaan typisch gebruikt voor tellers in lussen variabelen “register” bij default type int sommige (optimaliserende) compilers negeren dit
23
p. 23 Vakgroep Informatietechnologie Storage class static static extern toegepast op lokale variabelen toegepast op globale variabelen waarde wordt behouden bij herstarten van blok! beperken scope tot DEZE compilatie-eenheid, vanaf het punt van declaratie toegepast op functie beperken gebruik tot DEZE compilatie-eenheid
24
p. 24 Vakgroep Informatietechnologie Scope & storage: C vs. Java Enkelvoudige naamruimte voor functies en globale variabelen Elke klasse in Java definieert een naamruimte (Eng.: namespace), die toelaat dat methoden en attributen in verschillende ongerelateerde klassen een zelfde naam hebben. In C zijn alle functies globaal en is er slechts één naamruimte. In grote projecten moet dus bijzondere aandacht besteed worden aan het uniek kiezen van de namen van variabelen en functies. Let wel: een struct, union of enum definieert een aparte naamruimte voor zijn members en elke zogenaamde block statement (een uitdrukking tussen { }) definieert een aparte naamruimte voor zijn lokale variabelen.
25
p. 25 Vakgroep Informatietechnologie Functienaam overlading In Java kunnen twee functies in dezelfde naamruimte dezelfde naam hebben als hun argument types verschillend zijn. In C is dit niet het geval en alle functienamen dienen uniek te zijn! Scope & storage: C vs. Java (2)
26
p. 26 Vakgroep Informatietechnologie Macro’s: concept tekstuele substitutie door preprocessor evt. MET ARGUMENTEN oppervlakkige gelijkenis met functies (gebruik HOOFDLETTERS voor namen van macro’s) efficiëntere uitvoering definitie #definenaam(arg1,arg2,…)schrifttekst CAVEAT !!! #defineSQUARE(x)x*x double y=SQUARE(x); double z=SQUARE(x+y); double q=SQUARE(SQUARE(x+y)); double r=y/SQUARE(y); geen spatie ! geen ; ?
27
p. 27 Vakgroep Informatietechnologie Macro’s: concept vernietiging #undefnaam OPMERKINGEN argumenten hebben geen type ! macro’s worden dikwijls in headerbestanden opgenomen sommige compilers laten toe resultaat van macro-expansie te zien : b.v.CC -E bestand.c #defineSQUARE(x)((x)*(x))
28
p. 28 Vakgroep Informatietechnologie Zonder argumenten definitie van constanten “syntactic sugar” Voorbeeld #definePI3.1415926 #defineSMALL1E-20 #defineEOF(-1) #defineMAXINT2147483647 (overflowdetectie) #defineEOS(‘\0’) #defineEQUALS== if(i EQUALS j)...
29
p. 29 Vakgroep Informatietechnologie # en ## effect: #arg->“arg” voorbeeld /* stringization.c */ #include #definePRINTVAR(t,x)printf(" "#x " = %" #t" ",x) int main(void) { double d=1.0; char c='a'; d+=c; PRINTVAR(f,d); PRINTVAR(c,c); return 0; } # = “stringisatie-operator”
30
p. 30 Vakgroep Informatietechnologie # en ## effect : token1##token2-> token1token2 voorbeeld /* merger.c */ #include #defineX(i)x##i #definePRINT(i)printf("%d ",X(i)) int main(void) { int x1=10,x2=20,x3=30; PRINT(1); PRINT(2); PRINT(3); } ## = “token merger”
31
p. 31 Vakgroep Informatietechnologie Functies met variabel aantal argumenten: ellipsis voorbeeld printf(formaat_string, … ) Definities in Type va_list Gegevensstructuur die parameterlijst kan bevatten 3 Macro’s va_start Initialisatie via laatst gekende argument va_arg Toegang tot een argument va_end Oproepen na toegang tot laatste argument ellipsis Beperkingen Hoe aantal argumenten bepalen ? via de gekende argumenten via afspraak (b.v. sentinel) van niet-gekende argumenten Type van de argumenten moet gekend zijn Argumenten sequentieel te doorlopen
32
p. 32 Vakgroep Informatietechnologie Variabel aantal argumenten: vb /* ellipsis.c */ #include double gemiddelde(int n,...); int main(void) { printf("Gemiddelde = %f\n",gemiddelde(3,1,2,3)); printf("Gemiddelde = %f\n",gemiddelde(2,1,2)); } double gemiddelde(int n,...) { int som=0; va_list arg; int i; va_start(arg,n); for(i=0;i<n;i++) som+= va_arg(arg,int) ; va_end(arg); return (double)som/n; }
Verwante presentaties
© 2024 SlidePlayer.nl Inc.
All rights reserved.