Ponteiros de Função
Click here to load reader
-
Upload
rodrigo-almeida -
Category
Technology
-
view
429 -
download
0
description
Transcript of Ponteiros de Função
ELT048 - SOE
Ponteiros de função
Rodrigo AlmeidaUniversidade Federal de Itajubá
Revisão● Ponteiros● Struct● Buffer circular● Ponteiro para void
Exercício● Implementar um buffer circular
● Utilizar um vetor de 10 posições
● Cada elemento do vetor é uma estrutura com duas variáveis
● char tipo
● void* ptr
● Criar uma função para adicionar novos elementos e uma para retirar os mais antigos.● Add(char tipo, void* var);● Remove(void);
//definição da estruturatypedef struct { char tipo; void* ptr;}process;
//definição do buffer circular#define BUFFERSIZE 10process buffer[BUFFERSIZE];
//definição dos “ponteiros” de acessoint ini, fim;
Exercício
//função de adição de “process” no buffervoid addProc(char ntipo, void* val){
//checagem de espaço disponível if ( ((ini+1)%BUFFERSIZE) < fim){ //Atualização da posição atual buffer[i].tipo = ntipo; buffer[i].ptr = val; //incremento da posição ini = (ini+1)%(BUFFERSIZE); }
}
Exercício
//função de remoção de um “process” do buffervoid removeProc (void){
//checagem se existe alguem pra retirar if ( ((fim+1)%BUFFERSIZE) <= ini){ //incremento da posição fim = (fim+1)%(BUFFERSIZE); }
}
Exercício
#include “stdio.h”void main (void){ int a=5; addProc('i', 5); addProc('i', a); addProc('e', &a); removeProc(); removeProc(); removeProc();}
Exercício
Problema● Como executar uma função que não é
conhecida em tempo de compilação?● Conhecer o endereço da função em tempo de
execução.● Empilhar corretamente os parâmetros que a
função necessita● Realizar uma chamada de função para esse
endereço
● Onde isso é importante?
Solução● Criar rotinas em assembly que recebem o
endereço da função, empilham todas as variáveis corretas e façam uma chamada de função para o endereço (JSR)
ou
● Utilizar ponteiros de função em C
Ponteiros de Função● Armazenam o endereço do início de uma função.
● A manipulação do valor obedece todas as regras de manipulação de ponteiros.● A única exceção é na chamada da função
apontada.● Apresenta uma declaração complexa.
● É necessário indicar a assinatura da função: a quantidade e tipos dos parâmetros.● É comum utilizar um typedef para simplificar a
criação dos ponteiros.
//definindo um tipo de ponteiro de função que// não recebe nenhum parâmetro// não retorna nenhum valortypedef void (*pointerTest)(void);
//definição do ponteiro foo via typedefpointerTest foo;
//definição do ponteiro bar sem typedefvoid (*bar)(void);
Definição de ponteiros de função
Definição de ponteiros de função//funçõesvoid func1 (void){ printf("Primeira Função")}void func2 (void){ printf("Segunda Função")}
//criando um ponteiro para funçãopointerTest foo;
foo = func1; //Nota: Sem parênteses(*foo)(); //chamando a função 1
foo = func2; //Nota: Sem parênteses(*foo)(); //chamando a função 2
Engine de processamento● O principal uso de um ponteiro de função é
permitir que o programa rode uma função arbitrária não conhecida em tempo de compilação com uma menor complexidade.
● menor complexidade = sem apelar para asm.
● Isto permite ao programador desenvolver “engines” de processamento.
● As “engines” realizam uma série de preparações/checagens/testes antes de executar as funções.
Engine de processamento● Objetivo:
● Fazer uma engine de um processador gráfico
● Utilização de um switch com passagem de parâmetro para a seleção da funcionalidade
Engine de processamentoimage Blur(image nImg){}image Sharpen(image nImg){}
image imgEngine(image nImg, int opt){ image temp; //checagem de consistência da imagem switch(opt){ case 1: temp = Sharpen(nImg); break; case 2: temp = Blur(nImg); break; } return temp;}
Engine de processamento● Utilização de
ponteiros de função para seleção da função
● Criação de um tipo via typedef para simplificar o código
Engine de processamento
image Blur(image nImg){}
image Sharpen(image nImg){}
typedef image (*ptrFunc)(image nImg);
//image editor engineimage imgEngine(ptrFunc function, image nImg){
image temp;//checagem de consistência da imagemtemp = (*function)(nImg);return temp;
}
Engine de processamento● Vantagens
● Novas funções não alteram a engine
● O teste do código da engine só precisa ser feito uma vez
● Pode mudar as opções dinâmicamente
● Desvantagens● Ponteiros de função
são mais complexos para se trabalhar (pelo menos no começo)
● Nem todos os compiladores para embarcados funcionam bem com ponteiros de função (Harvard x Von Neuman)
Exercicio● Modifique a estrutura apresentada
anteriormente para incluir também um ponteiro de função.
● Crie uma função que executa o ponteiro de função armazenado na “primeira” posição do buffer circular.
● Crie um main que adicione 3 elementos no buffer e execute cada um deles na ordem que foram inseridos.
● Add(x3), exec, remove, exec, remove, exec, remove
//código antigotypedef struct { char* NomeDoProcesso; int Prioridade;}process;#define BUFFERSIZE 10process buffer1[BUFFERSIZE];int ini, fim;void addProc (char *nome, int prio){ if ( ((ini+1)%BUFFERSIZE) < fim){ buffer[i].Prioridade = prio; buffer[i].NomeDoProcesso = nome; ini = (ini+1)%(BUFFERSIZE); }}void removeProc (void){ if ( ((fim+1)%BUFFERSIZE) <= ini){ fim = (fim+1)%(BUFFERSIZE); }}