Funkcje Modularyzacja program gwny funkcje Funkcje obliczajce warto
Funkcje Modularyzacja : program główny , funkcje Funkcje : – obliczające wartość – nie obliczające wartości Niedozwolone : – zagnieżdżanie – wywoływanie niezadeklarowanych ( deklaracje i definicje )
Deklaracja funkcji typ identyfikator_funkcji (lista_argumentów_formalnych ); typ wartości funkcji : liczbowy, wskaźnikowy, referencyjny, strukturowy sygnatura funkcji : liczba i typy argumentów formalnych argument_formalny : typ identyfikator int f 1( int x, int y );
float wartosc( float cena, int liczba ); char* odpowiedz ( char *pytanie ); double alfa( double x 1, x 2 ); // błąd max( int k, int l ); // typ domyślny int // przestarzałe void druk( char *napis ); // bez wyniku
Definicja funkcji typ identyfikator_funkcji (lista_argumentów_formalnych ) { blok } blok : ciąg deklaracji, definicji i instrukcji wykonywany : – do końca bloku – do instrukcji return argument_formalny : typ identyfikator
float sqr( float x ) { return x * x ; } void max( int *m, int a, int b ) { *m = a > b ? a : b ; } // return; void Drukuj. Wynik ( float x ) { printf ( "n. Wynik : %10. 2 f" , x); }
int split( char *S, char *D 1, char *D 2 ) { int licz_S = 0 ; // zmienna lokalna while ( *S ) { if ( licz_S & 0 x 01 ) *D 2++ = *S++; else *D 1++ = *S++; licz_S++; } *D 1 = *D 2 = 0; return licz_S; }
Wywołanie funkcji identyfikator_funkcji ( lista_argumentów_aktualnych ) argument_aktualny : wyrażenie a = 1 + sqr( 1. 25 ); // w wyrażeniu max( &lepsza, cena_1, cena_2 ); // instrukcja sqr(3 + b * d ); Drukuj. Wynik ((sqrt(delta) - 4 * a * c ) / ( 2 * a ) ) ; printf( "n%dt%dn", a + 2, a - 1 );
Powiązanie argumentów aktualnych i formalnych int Funa ( int a, int b, int c ) { if ( a > 3 * b – 1) return c + 2; else return c * c + 1; } int k, r; //. . int x = Funa (12, k + 4, r - 3); // a = 12, b = k + 4, c = r - 3
Przekazywanie argumentów do funkcji zgodny typ argumentu formalnego i aktualnego : – typy identyczne – możliwa konwersja
long suma( long x ) { return x + 1000; } suma(3); // poprawnie int -> long suma(1543443 L); // poprawnie bez konwersji suma(17. 8); // ryzykownie double -> long suma('A'); // poprawnie char -> long suma("ALA"); // błąd, konwersja niemożliwa
int oblicz( float *wf ); int *wi; oblicz( wi ); // błąd, nieodpowiedni wskaźnik oblicz (( float*) wi); // poprawnie, ryzykownie
Sposoby przekazywania argumentów · przekazywanie wartości · przekazywanie wskaźnika · przekazywanie referencji
void D 2 V ( int n ) // przekazywanie wartości { n = n + 2; // krok 2 } int a = 5; D 2 V ( a ); // krok 1
void D 2 P( int *n ) // przekazywanie wskaźnika { *n = *n + 2; // krok 2 } int a = 5; D 2 P( &a ); // krok 1
void D 2 R(int& n) // przekazywanie referencji { n = n + 2; // krok 2 } int a = 5; D 2 R( a ); // krok 1
long b = 5; D 2 R( b ); // krok 1 program główny funkcja D 2 R b tt n krok 1 5 5 & krok 2 5 7 &
struct Konto { long numer; long suma; } void Wplata ( Konto kk, long kwota) { kk. suma += kwota; } Konto AB = { 84404, 0 }; Wplata ( AB, 3285 ); // AB. suma == ?
Konto Wplata ( Konto kk, long kwota) { kk. suma += kwota; return kk; } AB = Wplata ( AB, 3285 ); // AB. suma == 3285 Argument stały float Pole. Kola(const float *lpi, float *pr) { *lpi = 2. 5; . . . } // błąd Podatek, ONP, Sum. Ilo. Fun
Tablice jako argumenty funkcji • Tablice jednowymiarowe int FT(int *); // deklaracje int FT(int[ ]); int FT(int[10]); int FT(int *T) {. . . } // definicje int FT(int T[ ]) {. . . } int FT(int T[10]) {. . . } // T [ 3 ] // T + 3 * sizeof ( int )
void ZAP 1( int T[100] ) { for ( int i = 0; i < 100; ++i ) T[ i ] = i; } // int ALFA[15]; ZAP 1 ( ALFA ) ; niszczenie // zapis + int BETA[100]; ZAP 1 ( &BETA [0] ); // zapis całej tablicy int GAMMA[150];
void ZAP 2(int T[ ], int rozmiar) { for ( int i = 0; i < rozmiar; ++i ) T[i] = i; }
• Tablice wielowymiarowe wszystkie wymiary tablicy, poza najstarszym ( pierwszym od lewej ) void ZAP 3( float TT[ ][10], int wierszy ) { for (int i = 0; i < wierszy; ++i) for (int j = 0; j < 10; ++j) TT[i][j] = i + j; } // TT [ 3 ] [ 5 ] // TT + 3 * 10 * sizeof ( float ) + 5 * sizeof ( float ) Tab. Dem, Ew. Tel. Fun
Wartości domyślne argumentów funkcji float SUM 3(float x, float y = 2. 5, float z = 3. 5) { return x + y + z; } float a, b, c; SUM 3( a, b, c ); // a + b + c SUM 3( a, b ); // a + b + 3. 5 SUM 3( a ); // a + 2. 5 + 3. 5 SUM 3( ); // błąd SUM 3( a, , c ); // błąd
long Dotacja( const char *Osoba, long Kwota = 100 ); long Dotacja (const char *Osoba = "Jan Kowalski" , long Kwota ) { . . } void F 1 (int = 8, int = 5, long = 3); void F 1 (int x, int y = 4, int z, long g ) {. . }
Funkcje rekurencyjne n * ( n - 2 ) * ( n - 4 ) *. . . // > 0 int IR ( int n ) { return n <= 0 ? 1 : n * IR( n – 2 ); } int IP ( int n ) { int s = 1; while ( n > 0 ) { s *= n; n -= 2; } return s; }
Podprogramy wstawiane inline double WB(double x, double y, double z) { return x > y ? z : x; } Hash
Wskaźniki funkcji int ( *pf )( int, int ); // typ wyniku i sygnatura int Ki( int x, int y ) { return (x + y) * (x + 2 * y); } long Kl( int x, int y ) { return (long)(x + 3 * y) * (x - y); } pf = Ki; // poprawnie pf = & Ki; // poprawnie pf = Kl; // błąd, nieodpowiedni wskaźnik
void bubble. Sort ( float T[ ], int n ) {. . . } void merge. Sort ( float T[ ], int n ) {. . . } void heap. Sort ( float T[ ], int n ) {. . . } void ( *w. S )( float[ ], int ) = bubble. Sort; void ( *n. S )( float[ ], int ) ; n. S = w. S; float TAB[ 150 ]; w. S ( TAB, 150 ); ( *n. S )( TAB, 150 ); /* równoważne wywołania funkcji bubble. Sort */
Tablice wskaźników funkcji int f. A(double x) {. . . } int f. B(double y) {. . . } int f. C(double z) {. . . } int ( *f. X [3] )( double ) = { f. A, f. B }; f. X[2] = f. C; f. X[1]( 37. 18 ); // wywołanie
int ( *Test [10] )( char* ) = {. . . }; int Wyniki [10]; char* Napisy[10]; for (int i = 0; i < 10; ++i ) Wyniki[i] = Test[i] ( Napisy[i] ); // // typedef int ( *PF )( float, float ); int Fun( float a, float b ) {. . . } PF f 1, f 2 = Fun; PF Tfun[15];
Wskaźnik funkcji jako argument funkcji void Sort( float[ ], int, void (*) ( float[ ], int ) = merge. Sort ); void Sort(float TAB[ ], int rozmiar, void (*f. S) (float[ ], int) ) { . . . . f. S( TAB, rozmiar ); . . . . } float T 1[100], T 2[200]; void ( *w. F )( float[ ], int ) = heap. Sort; Sort( T 1, 100, bubble. Sort ); Sort( T 2, 200, w. F ); // heap. Sort( T 2, 200 ); // merge. Sort
Wskaźnik funkcji jako wynik funkcji typedef char* ( *NP )( char*, char* ); struct FUNKCJE { int cecha; NP funkcja; } TABLICA[15];
NP Szukaj( FUNKCJE TAB[ ], int rozmiar, int wzorzec ) { for (int i = 1; i < rozmiar; ++i) if (TAB[i]. cecha == wzorzec) return TAB[i]. funkcja; return TAB[0]. funkcja; } // printf ( "%sn" , Szukaj ( TABLICA, 1527 )( "Alf", "Ogi") ); Kalku, Mat. Fun, Oferta
Przeciążanie identyfikatorów funkcji int SA( int TI[ ], int n ) { int s = 0; for (int i = 0; i < n; ++i) s += TI[i]; return s / n; } double SA( double TD[ ], int n ) { double s = 0; for (int i = 0; i < n; ++i) s += TD[i]; return s / n; }
int TAB_I [ 10 ]; double TAB_D [ 10 ]; SA ( TAB_I, 10); SA ( TAB_D, 10); // wyboru dokonuje kompilator Różne sygnatury : przeciążenie identyfikatora Równe sygnatury : · równe typy wyniku : przesłanianie · różne typy wyniku : błąd
/* plik funkcji bibliotecznych */ int strlen( char *s ); /* plik programu użytkowego */ int strlen( char *z ) { int len = 0; while (*z++) if (*z != ' ') ++len; return len; } /* definicja zawarta w pliku programu użytkowego przesłania deklarację z pliku bibliotecznego */ void czytaj(char *) {. . . } int czytaj(char *) {. . . } // błąd
Wybór wersji funkcji o przeciążonym identyfikatorze · zgodność : typ taki sam lub konwersja · niezgodność : konwersja niemożliwa · niejednoznaczność : zgodność w kilku funkcjach
void druk( char c ) {. . . } // wersja C void druk( int i ) {. . . } // wersja I void druk( float f ) {. . . } // wersja F void druk( char *s ) {. . . } // wersja S int a; druk( a ); // zgodność: wersja I druk( 'a' ); // zgodność: wersja C druk( "a" ); // zgodność: wersja S long l; druk( l ); // błąd: niejednoznaczność // możliwe wersje C, I, F float f, *pf = &f; druk( f ); // zgodność: wersja F druk( pf ); // błąd: niezgodność
Zasada minimalizacji liczby konwersji void ff( int k, float z ) {. . . } // wersja 1 void ff( char c, float z ) {. . . } // wersja 2 // ff( 'a', 15 ) // ?
Wartości domyślne argumentów void fun( int n ) {. . . } // wersja 1 void fun( long l, int n = 0 ) { } // wersja 2 fun( 2 L ); // wersja 2: fun (2 L, 0); fun( 5, 38 ); // wersja 2: fun (5, 38); fun( 137 ); // wersja 1: fun (137); fun( 3. 14 ); // błąd: niejednoznaczność Tekst
Wzorce funkcji int min(int a, int b) // wersja I { return a < b ? a : b; } long min(long a, long b) // wersja L { return a < b ? a : b; } float min(float a, float b) // wersja F { return a < b ? a : b; } // zastępuje wzorzec template <class T> T min( T a, T b ) { return a < b ? a : b; } // min( 1, 2 ); // poprawnie: wersja I min( 3, 1. 5 ); // błąd: niejednoznaczność Templa
Łączenie wielu plików programu · dyrektywa #include · pliki nagłówkowe · deklaracja extern External
- Slides: 42