1. Este site usa cookies. Ao continuar a usar este site está a concordar com o nosso uso de cookies. Saber Mais.

Parametros funcionais em C (function pointers)

Discussão em 'Programação' iniciada por gryphus1, 1 de Julho de 2007. (Respostas: 12; Visualizações: 1221)

  1. Boas.

    Tenho uma duvida referente a funções passadas para outras funções como apontadores, isto é, parâmetros funcionais em C.

    Por exemplo, tenho uma funçao:

    Código:
    tDic newDic (int max, tKey(*key)(tElem),
    int (*eqKey)(tKey,tKey),int (*eqElemKey)(tElem,tElem),int (*hash)(tKey,int));
    tDic é o tipo que a função devolve, tKey é o tipo para a função apontada por *key assim como o tipo de alguns parametros de entrada para o apontador *eqKey e *hash por exemplo, e o mesmo para tElem que é o tipo dos parametros de entrada para o apontador *eqElemKey por ex.


    Mas isto é apenas a declaração da função newDic... como posso fazer para a chamar no programa principal?? A minha duvida é o que passar durante o chamamento da função newDic no programa principal para os apontadores às funções *key,*eqKey,*eqElemKey... etc
     
  2. Dan

    Dan Power Member

    Vou dar um exemplo para as funções:

    - Imagina que tens 2 funções para cada tipo que tens de passar para a função newDic

    Código:
    tKey keyGet(tElem elem);
    tKey keyFunc(tElem elem);
    
    int eqKeyComp (tKey key1, tKey key2);
    int eqKeyDiff (tKey key1, tKey key2);
    
    int eqElemKeyPrim (tElem elem1, tElem elem2);
    int eqElemKeySec (tElem elem1, tElem elem2);
    
    int hashGen (tKey key, int i);
    int hashProd (tKey key, int i);
    
    - Agora, para chamares a função newDic podes passar qualquer das duas funções de cada tipo, por exemplo

    Código:
    int main() {
    ...
    tDic d = newDic(100, keyGet, eqKeyDiff, eqElemKeyPrim, hashGen);
    ...
    }
    - E para usares as funções dentro da newDic é só chamar por elas e passar-lhes os argumentos

    Código:
    tDic newDic (int max, tKey(*key)(tElem), int (*eqKey)(tKey,tKey),int (*eqElemKey)(tElem,tElem),int (*hash)(tKey,int)) {
    ...
    tElem e1;
    tElem e2;
    ...
    tKey k1 = key(e1);
    tKey k2 = key(e2);
    ...
    if(eqKey(k1, k2)) ...
    ...
    if(eqElemKey(e1,e2)) ...
    ...
    int a = hash(k1, 100);
    ...
    }



    EDIT: Já agora, por curiosidade, se quiseres uma função que te devolva outra função podes faze-la do seguinte modo

    Código:
    (tipo_dados_devolve) (tipo_dados_recebe, tipo_dados_recebe, ...) nome_funcao_devolve(parâmetros ...) {
    ...
    return(nome_funcao_devolvida);
    ...
    } 
    Mas uma nota importante: se queres andar a passar funções como argumento e funções para devolveres funções, trabalha em LISP que isso é o pão nosso de cada dia :) em C o código torna-se pouco legível e intuitivo, mas funciona na mesma.
     
    Última edição: 2 de Julho de 2007
  3. Obrigado pela explicação Dan!:) Já percebi como se faz, era mesmo isso.

    O que é LISP? Alguma linguagem? (não conheço :D)

    De todas as formas estou actualmente a trabalhar em C não por escolha própria mas porque estou a dar C na faculdade e vou ter exame de C eheh :P mas de todas as formas nunca é demais aprender, e agora fiquei deveras curioso com essa linguagem LISP... :)
     
  4. Dan

    Dan Power Member

    Fonte: Wiki

    Na prática é um paradigma completamente diferente do imperativo (usado em C) e a estrutura de dados base, como está dito em cima, é a lista, ao invés do vector (mais usado em C), embora também o tenha.

    O que eu chamo "o pão nosso de cada dia" em LISP é a recursão, as funções que recebem funções e as funções que devolvem funções. Em LISP estas operações, ao nível do programador, são extremamente simples, e permitem algo de maravilhoso que são as operações/funções de alto nível, que simplificam o código bastante.

    Só tem um senão, que com o hábito o pessoal lá atina, que é a notação prefixa. Uma simples soma também é uma função, logo escreves o "+" e a seguir todos valores que queres somar, e se tens uma subtracção lá no meio idem. Há uns exemplos no link de cima.

    Dado que estás na faculdade penso que irás dar alguma linguagem funcional e muito possivelmente será LISP.

    Já agora, boa sorte para o exame! :D
     
  5. MadOnion

    MadOnion Folding Member

    Nas faculdades, muitas vezes o LISP é substituido pelo Haskell.
     
  6. Dan

    Dan Power Member

    Ah, então gryphus1 pode ser que não dês LISP na faculdade, é uma questão de veres o programa da tua licenciatura. Não conheço Haskell, por isso não sei se o que disse do LISP se possa dizer do Haskell.
     
  7. Rui_Carlos

    Rui_Carlos 1st Folding then Sex

    aquilo que disseste para Lisp também se mantem no Haskell: é uma linguagem funcional (pura), usa listas em vez de array, usas recursividade em tudo quanto é lado, usas funções de ordem superior q.b., etc.
    no entanto, no Haskell não tens o inconveniente das operações serem pre-fixas e tens uma notação mais simples (na minha opinião), mas próxima da linguagem matemática e do lambda calculus.

    resumindo, Haskell é muito melhor do que Lisp :x2:
     
  8. Dan

    Dan Power Member

    Ok, ok, a notação prefixa já tinha admitido que é um pouco chata ao início, mas trabalha um pouco com ela que depois vais ver que não queres outra coisa :D
     
  9. Rui_Carlos

    Rui_Carlos 1st Folding then Sex

    em Haskell temos as duas alternativas (para operadores binários): se <op> é infixo, então (<op>) é prefixo (p.e. + / (+)) :D
     
  10. Baderous

    Baderous Banido

    Haskell r0x!
     
  11. Dan

    Dan Power Member

    huuuummmmm... :D , ok, ganhas-te este round. A ver se dou uma espreitadela a esse Haskell um dia destes. Tem compilador, interpretador ou ambos?
     
  12. Baderous

    Baderous Banido

    GHCi ou Hugs, mas GHCi é melhor!
     
  13. Dan

    Dan Power Member

    Vou experimentar então quando acabarem os meus exames :)

    Verdade seja dita que o paradigma funcional é o que precebo e uso menos, mas talvez seja esse o fascínio que tenho por ele, principalmente o "mix" do funcional com orientação a objectos, algo que o Common LISP oferece.
     

Partilhar esta Página