Diferenças
Aqui você vê as diferenças entre duas revisões dessa página.
Ambos lados da revisão anterior Revisão anterior | |||
c:ponteiros_para_funcoes [2023/08/01 20:16] – edição externa 127.0.0.1 | c:ponteiros_para_funcoes [2023/08/15 14:56] (atual) – maziero | ||
---|---|---|---|
Linha 1: | Linha 1: | ||
+ | ====== Ponteiros para funções ====== | ||
+ | |||
+ | {{ progc_func_ptr.mkv |Video desta aula}} | ||
+ | |||
+ | {{ funcptr.png|https:// | ||
+ | |||
+ | ===== Declaração e uso ===== | ||
+ | |||
+ | Declarar um ponteiro para uma função é relativamente simples, apesar da sintaxe assustar à primeira vista. O código abaixo declara um ponteiro '' | ||
+ | |||
+ | <code c> | ||
+ | // uma função com protótipo "void name (int)" | ||
+ | void f (int) | ||
+ | { | ||
+ | ... | ||
+ | } | ||
+ | |||
+ | // um ponteiro para funções com protótipo "void name (int)" | ||
+ | void (*fp) (int) ; | ||
+ | </ | ||
+ | |||
+ | Observe que os parênteses envolvendo '' | ||
+ | |||
+ | <code c> | ||
+ | void * fp (int) ; // protótipo de função retornando '' | ||
+ | </ | ||
+ | |||
+ | O uso de ponteiros para funções é simples: | ||
+ | |||
+ | <code c funcptr.c> | ||
+ | #include < | ||
+ | |||
+ | void inc (int *n) | ||
+ | { | ||
+ | (*n)++ ; | ||
+ | } | ||
+ | |||
+ | int main () | ||
+ | { | ||
+ | void (*fp) (int *) ; // function pointer | ||
+ | |||
+ | fp = inc ; // fp points to inc | ||
+ | |||
+ | int a = 0 ; | ||
+ | printf ("a vale %d\n", a) ; | ||
+ | |||
+ | inc(&a) ; // normal call | ||
+ | printf ("a vale %d\n", a) ; | ||
+ | |||
+ | fp(&a) ; // call using the function pointer | ||
+ | printf ("a vale %d\n", a) ; | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | Sua execução resulta em: | ||
+ | |||
+ | a vale 0 | ||
+ | a vale 1 | ||
+ | a vale 2 | ||
+ | |||
+ | <note important> | ||
+ | Obviamente, um ponteiro de função só pode apontar para funções que tenham o mesmo protótipo (assinatura) com o qual o ponteiro foi declarado. | ||
+ | |||
+ | Caso necessário, | ||
+ | |||
+ | ===== Funções como parâmetros ===== | ||
+ | |||
+ | Como uma variável pode apontar para uma função, então funções podem ser usadas como parâmetros de outras funções. O código a seguir ilustra como fazer isso: | ||
+ | |||
+ | <code c funcparam.c> | ||
+ | #include < | ||
+ | #include < | ||
+ | #include < | ||
+ | |||
+ | // aplica a função " | ||
+ | void aplica (int (* func) (int), char *str) | ||
+ | { | ||
+ | for (int i = 0; str[i]; i++) | ||
+ | str[i] = func (str[i]) ; | ||
+ | } | ||
+ | |||
+ | // se c for uma vogal, devolve ' | ||
+ | int tira_vogal (int c) | ||
+ | { | ||
+ | switch (c) | ||
+ | { | ||
+ | case ' | ||
+ | case ' | ||
+ | case ' | ||
+ | case ' | ||
+ | case ' | ||
+ | case ' | ||
+ | case ' | ||
+ | case ' | ||
+ | case ' | ||
+ | case ' | ||
+ | default : return (c) ; | ||
+ | } | ||
+ | } | ||
+ | |||
+ | int main () | ||
+ | { | ||
+ | char frase[128] ; | ||
+ | |||
+ | strcpy (frase, "Uma frase com MAIUSCULAS e minusculas" | ||
+ | printf (" | ||
+ | |||
+ | aplica (toupper, frase) ; | ||
+ | printf (" | ||
+ | |||
+ | aplica (tolower, frase) ; | ||
+ | printf (" | ||
+ | |||
+ | aplica (tira_vogal, | ||
+ | printf (" | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | Resultado da execução: | ||
+ | |||
+ | < | ||
+ | Frase: Uma frase com MAIUSCULAS e minusculas | ||
+ | Frase: UMA FRASE COM MAIUSCULAS E MINUSCULAS | ||
+ | Frase: uma frase com maiusculas e minusculas | ||
+ | Frase: -m- fr-s- c-m m---sc-l-s - m-n-sc-l-s | ||
+ | </ | ||
+ | |||
+ | <note tip> | ||
+ | Uma função também pode retornar um ponteiro de função. Neste caso, a sintaxe da declaração da função pode ficar complexa, sobretudo se a função tiver parâmetros e a função retornada também. | ||
+ | </ | ||
+ | |||
+ | /* | ||
+ | https:// | ||
+ | |||
+ | typedef int (*function_type)(int, | ||
+ | |||
+ | function_type getFunc() | ||
+ | { | ||
+ | | ||
+ | test = ... ; | ||
+ | | ||
+ | } | ||
+ | */ | ||
+ | |||
+ | ===== Exercícios ===== | ||
+ | |||
+ | - A função '' | ||
+ | * a) crie um vetor de 100 inteiros aleatórios e ordene esse vetor usando a função '' | ||
+ | * b) Idem, para um vetor de tipo '' | ||
+ | * c) Idem, para um vetor de //structs// (ordenar por um dos campos do // | ||