3. 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);
4. Exercício
//definição da estrutura
typedef struct {
char tipo;
void* ptr;
}process;
//definição do buffer circular
#define BUFFERSIZE 10
process buffer[BUFFERSIZE];
//definição dos “ponteiros” de acesso
int ini, fim;
5. Exercício
//função de adição de “process” no buffer
void 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);
}
}
6. Exercício
//função de remoção de um “process” do buffer
void removeProc (void){
//checagem se existe alguem pra retirar
if ( ((fim+1)%BUFFERSIZE) <= ini){
//incremento da posição
fim = (fim+1)%(BUFFERSIZE);
}
}
8. 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?
9. 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
10. 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.
11. Definição de ponteiros de função
//definindo um tipo de ponteiro de função que
// não recebe nenhum parâmetro
// não retorna nenhum valor
typedef void (*pointerTest)(void);
//definição do ponteiro foo via typedef
pointerTest foo;
//definição do ponteiro bar sem typedef
void (*bar)(void);
12. Definição de ponteiros de função
//funções
void func1 (void){
printf("Primeira Função")
}
void func2 (void){
printf("Segunda Função")
}
//criando um ponteiro para função
pointerTest 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
13. 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.
14. 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
15. Engine de processamento
image 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;
}
16. 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
18. Engine de processamento
● Vantagens ● Desvantagens
● Novas funções não ● Ponteiros de função
alteram a engine são mais complexos
● O teste do código para se trabalhar
da engine só (pelo menos no
precisa ser feito começo)
uma vez ● Nem todos os
● Pode mudar as compiladores para
opções embarcados
dinâmicamente funcionam bem com
ponteiros de função
(Harvard x Von
Neuman)
19. 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
20. //código antigo
typedef struct {
char* NomeDoProcesso;
int Prioridade;
}process;
#define BUFFERSIZE 10
process 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);
}
}