Curset de C avancat: Funcio aplica
Vamos a ver, estaba llorl hasiendo la practica del department cuando se macurrio intentar hacer la funcion aplica (du yu rimember? La que aplica una funcion a todos los elementos de la lista). Dicha funcion le tienes que pasar como parametro el puntero a una funcion, pero como sabes el numero de parametros que tiene esa fuancion que le pasas como parametro? eh? eh? Ahi queda la preguntita de marras. Si todavia no tas caido del asiento y por punyetera casualidas sabes la solucion... Por tus muelas! Dimela! que no me deja dormir!!!!!
Signat: Un follao en logica y puteao en practicas.
PD: Lo de que no me deja dormir es conya, eh?
Llorl
La funcion 'aplica' es una funcion que podeis implementar en el TAD llista generica opcionalmente. No es requisito de la practica pero es una buena forma de testearla, i a parte de que os pueda puntuar mejor o peor si la haceis, pensad que puede iros de perla para los programas en los que utiliceis la lista. Ya lo vereis.
Si no teneis las ideas claras, no os aconsejo que os leais esto hasta que tengais la practica 'ben paida'. Eso si pensad que es muy, pero que MUY util.
Imaginaros una lista del personal del DSIO (o DI) que habeis hecho utilizando vuestra flamante llista_generica, vale? Imaginad que cada elemento de esta lista tiene un campo que contiene la antiguedad. Imaginad que pasa un anio. Cap problema, haceis una funcion que se patee toda la lista i incremente la antiguedad de cada elemento.
Imaginaros que un alumno, dezkiziado por haber cateado por kinta vez logika, quiere enviar un mail subversivo a los profes del depar. Kap problema, el se implementa una funcion que se patee toda la lista, comprueve si el elemento en question es un profe i que en el caso de que lo sea envie el susodicho e-mail.
A donde os kiero llevar? Al huerto, claro. Despues de tanta pateada, no se os ocurre una forma de ahorrar faena? Que tal si hacemos una funcion 'aplica' que aplique una funcion f2 sobre todos i cada uno de los elementos de la lista?
Esta funcion recibiria un puntero a la lista i un puntero a la funcion a aplicar. La definiriamos en el TAD llista_gen i su cabecera seria asi:
void aplica (llista *l, void* (*f2) (void*) );
para incrementar a todos la antiguitat podriamos hacer la llamada:
aplica (llistapersonalDSIO, incrementa_antiguitat);
i simplemente implementar la funcion incrementa_antiguitat sobre un elemento que ni siquiera tiene que estar en una lista.
void* incrementa_antiguitat (void *fitxa) { (tipus_fitxa *) fitxa -> antiguitat ++; return (fitxa); }
La funcion que le pasas como parametro a 'aplica' es del tipo que recibe un puntero al elemento i retorna otro del mismo palo. El puntero que retorna en el ejemplo no caldria pues da la casualidad que trabajamos sobre el mismo elemento. Pero imaginaos que la funcion lo cambia; como se lo decimos? Para tener en cuenta tambien este caso mejor que lo retorne.
(del mismo palo=del mismo tipo; perdon)
Lo que tu me dices viendo esto veras que no tiene mucho sentido. Simplemente haces otra funcion que la meta dentro i que quede pendiente el parametro que ocupara el elemento de la lista.
Otra question que a ti ya te plantee pero que me gustaria plantear a los otros. Komo se las apanyara el alumno dezkiziado para enviar el e-mail subversivo solo a los profes del Depar. Habra que aplicar una funcion envia-mail solo a los profes. I si en vez de aplicar la funcion envia-mail aplicamos la funcion envia-mail-si-es-profe a toda la lista?
Como veis sirve para casi todo. Pero aun quedan lagunillas. Imaginaos que tenemos vuestra lista de complejos i queremos saber quanto suman todos ellos.
Tenemos que patearnos otra vez la lista pero la funcion aplica no nos sirve porque tendriamos que guardarnos un valor. La solucion facil passa, bien por utilizar una variable externa a la funcion f2 a la cual se accede mediante un puntero, o bien anyadiendo un parametro de resultado parcial pero en este caso la cosa se complica muuucho.
Si os pica la curiosidad lo podemos comentar en otro momento pero ahora lo dejo que sino saturo mucho esta pagina.
Vokimon (is04069)