Autor Tema: Funciones  (Leído 5313 veces)

0 Usuarios y 2 Visitantes están viendo este tema.

Desconectado jezus

  • PIC10
  • *
  • Mensajes: 44
Funciones
« en: 27 de Agosto de 2009, 21:33:08 »
Tengo una duda....¿en C,es correcto llamar a una función desde otra función?

Desconectado MLO__

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 4581
Re: Funciones
« Respuesta #1 en: 27 de Agosto de 2009, 22:01:27 »
Si claro que se puede.

De hecho, en ANSI C se puede llamar la funcion desde la misma funcion -recursividad- ... pero en CCS naaaa -o ya se puede?-

Saludos
El papel lo aguanta todo

Desconectado fabianjsm

  • PIC18
  • ****
  • Mensajes: 255
    • fabianjsm is on twitter
Re: Funciones
« Respuesta #2 en: 27 de Agosto de 2009, 22:22:29 »
Claro! Si llamas a una funcion que se define después (más abajo pero en el mismo archivo) es necesario declararla antes especificando su prototipo, y si la funcion se define externamente (en otro fuente C o ya compilado en una libreria que pudo ser escrita en C, pascal, asm o cualquier lenguaje) debes anteponer la palabra reservada 'extern' al prototipo (todo esto si el compilador es ANSI C, los demas tienen sus reglas). En cuanto a la recursividad, hay que tener en cuenta que la pila del PIC solo tiene seis niveles y muchos compiladores no te permiten o te permiten advirtiendote con un warning que debes tener cuidado.
@fabianjsm is on twitter

Desconectado MLO__

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 4581
Re: Funciones
« Respuesta #3 en: 27 de Agosto de 2009, 22:40:40 »
Hola Fabian.

Respecto a lo que mencionas, me causa mucha curiosidad lo que dices acerca de que puede llamar a una función que ha sido compilada desde otro archivo fuente. Como sería el manejo de ese tipo de funciones?
El papel lo aguanta todo

Desconectado pajaro

  • PIC24H
  • ******
  • Mensajes: 1121
Re: Funciones
« Respuesta #4 en: 28 de Agosto de 2009, 10:56:30 »
Hola amigos

El compañero dijo llamar a una funcion, desde otra, creo que hay una diferencia con respecto a la recursividad que consiste en que una funcion se llama a si misma.

int suma(int a, int b)
{
int c;
c=a+b;
retun(c);
}

////una funcion llama a otra
void resultado()
{
suma1(5,4);
}

//la funcion se llama a si misma.

suma1(suma1(2,3),5);

para la recursividad creo que habia una forma, porque se trabajaba con la pila, la recursivada la mirare un dia de estos mas a fondo.  


de todas formas yo tambien tuve problemas con con esto de las funciones en CCS.

tengo una pregunta?.

como le pasas a una una funcion mas de un valor desde otra funcion, si cuando termina la ejecucion de la primera las varibles parciales desaparecen.

y me reservo dos preguntas más si contestan a esta.

Un saludo.
« Última modificación: 28 de Agosto de 2009, 10:58:39 por pajaro »

Desconectado Suky

  • Moderador Local
  • DsPIC33
  • *****
  • Mensajes: 6758
Re: Funciones
« Respuesta #5 en: 28 de Agosto de 2009, 11:31:35 »
No se si entendí la pregunta, pero una forma de devolver mas de un resultado sería:

Código: C
  1. int Lee_dispositivo(char& Valor1, long& Valor2, int32& Valor3);
  2. void Funcion_x(void);
  3.  
  4.  
  5. void Funcion_x(void){
  6. char A;
  7. long B,
  8. int32 C;
  9.     .
  10.     .
  11.     .
  12.     if(Lee_Dispositivo(A,B,C)==0){
  13.         return(0); //Error.-
  14.     }
  15. }
  16. int Lee_dispositivo(char& Valor1, long& Valor2, int32& Valor3){
  17.     .
  18.     .
  19.     .
  20.      Valor1=read_disp();
  21.     .
  22.     .
  23.     .
  24.  
  25. }

« Última modificación: 28 de Agosto de 2009, 11:34:03 por Suky »
No contesto mensajes privados, las consultas en el foro

Desconectado pajaro

  • PIC24H
  • ******
  • Mensajes: 1121
Re: Funciones
« Respuesta #6 en: 28 de Agosto de 2009, 12:15:11 »
No se si entendí la pregunta, pero una forma de devolver mas de un resultado sería:

Código: C
  1. /////declaro cabecera funcion
  2. int Lee_dispositivo(char& Valor1, long& Valor2, int32& Valor3);     //le pasas y te devuelve
  3. void Funcion_x(void);                    //no le pasas ni te devuelve, nada solo llamas a la otra función
  4.  
  5. /////funcion principal o de llamada
  6. void Funcion_x(void)
  7.   {
  8.       char A; //
  9.       long B,
  10.       int32 C;
  11.     .
  12.     .
  13.     .
  14.     if(Lee_Dispositivo(A,B,C)==0)      //si no le pasaste nada, es decir a=0,b=0,c=0  te devuelve 0
  15.        {
  16.           return(0);   //Error.-
  17.        }
  18.   }
  19.  
  20. /////////////funciones
  21. int Lee_dispositivo(char& Valor1, long& Valor2, int32& Valor3)
  22.  {
  23.     .
  24.     .
  25.     .
  26.      Valor1=read_disp();
  27.     .
  28.     .
  29.     .
  30.  
  31. }



Hola suky

Deduzco que para que las variables parcieles no se pierdan lo que haces es anidar funciones.
Entonces para poder conectar la salida multiple de una funcion (su retorno) a la entrada de otra necesitariamos una tercera.
se puede retornar mas de un valor?

pero si se deja de estar en ejecucion la funcion y no exportas dato, que es lo que recibira la otra funcion, no se perdera por el camino.
voy a probar unas ideas..


Un saludo,

nota: las otras dos preguntas no las olvide jejeje... cachito a cachito.


« Última modificación: 28 de Agosto de 2009, 12:20:26 por pajaro »

Desconectado Suky

  • Moderador Local
  • DsPIC33
  • *****
  • Mensajes: 6758
Re: Funciones
« Respuesta #7 en: 28 de Agosto de 2009, 12:28:23 »
Si mejor proba, porque no te entendí  :mrgreen:  :D
No contesto mensajes privados, las consultas en el foro

Desconectado cerebro

  • Colaborador
  • PIC24F
  • *****
  • Mensajes: 735
Re: Funciones
« Respuesta #8 en: 28 de Agosto de 2009, 12:37:17 »
Hola Fabian.

Respecto a lo que mencionas, me causa mucha curiosidad lo que dices acerca de que puede llamar a una función que ha sido compilada desde otro archivo fuente. Como sería el manejo de ese tipo de funciones?

Como una DLL, que las funciones se linkean en tiempo de ejecución.... (creo que a eso se hace referencia).... la directiva extern  se utiliza por ejemplo si planteamos una libreria de funciones en c++ y vamos  a utilizarlas en C por lo general se suelen poner mas de una directiva para aumentar la compatibilidad entre compiladores.
LAS MALVINAS SON ARGENTINAS!

Desconectado pajaro

  • PIC24H
  • ******
  • Mensajes: 1121
Re: Funciones
« Respuesta #9 en: 28 de Agosto de 2009, 13:55:01 »
hola cerebro

Una cosa, extern solo lo vi antes en los script de linux, y desconozco si el uso en c y en ccs es el mismo.

En linux si tememos un script "pepito" este será el padre y este llama a otro script "juanito",
 si pepito tenía una variable c=5, cuando llamas desde "pepito" a "juanito" y "juanito" trabaja también con la misma variable de "pepito", cuando usa la variable   c   , con extern, la variable c , conserva el valor de "pepito" (proceso padre) si no se usa extern cuando llamamaos al proceso hijo, "juanito", su valor sera de c=0 o el que tenga scrip hijo.

Alguien sabe si el EXTERN en c y en ccs el uso es el mismo.
En compracion con linux.


Un saludo
 
« Última modificación: 28 de Agosto de 2009, 14:41:48 por pajaro »

Desconectado cerebro

  • Colaborador
  • PIC24F
  • *****
  • Mensajes: 735
Re: Funciones
« Respuesta #10 en: 28 de Agosto de 2009, 14:10:46 »
hola cerebro

Una cosa, extern solo lo vi antes en los script de linux, y desconozco si el uso en c y en ccs es el mismo.

En linux si tememos un script "pepito" este será el padre y este llama a otro script "juanito",
 si pepito tenía una variable c=5, cuando llamas desde "pepito" a "juanito" y "juanito" trabaja también con la misma variable de "pepito", cuando usa la variable   c   , con extern, la variable c , conserva el valor de "pepito" (proceso padre) si no se usa extern cuando llamamaos al proceso hijo, "juanito", su valor sera de c=0 o el que tenga scrip hijo.

Alguien sabe si el EXTERN en c y en ccs el uso es el mismo.


Un saludo
 

estoy de acuerdo pero no era a lo que me estaba refiriendo..... yo estaba hablando de DLL y extern se utiliza, lo que no se si es a eso lo que hacia referencia fabian "o me fui por la tangente"...
LAS MALVINAS SON ARGENTINAS!

Desconectado fabianjsm

  • PIC18
  • ****
  • Mensajes: 255
    • fabianjsm is on twitter
Re: Funciones
« Respuesta #11 en: 28 de Agosto de 2009, 16:44:07 »
Hola MLO__, parece que siempre nos encontramos en el foro.
La forma de trabajar con varios lenguajes es esta:
Compilas todos los codigos fuentes, obteniendo un codigo objeto por cada uno y luego enlazas a todos.
Obviamente, el enlazador debe reconocer el formato de cada objeto!
Los formatos más empleados para objetos son COFF y ELF. C30 por ejemlo soporta estos formatos.
Te paso un ejemplo utilizando C30.

Esta demás este comentario, pero pude ser de ayuda a alguien:

Con el compilador pic30-coff-as genero el OBJ con formato COFF a partir del fuente en ASM.
Con el compilador pic30-gcc genero el OBJ con formato COFF a partir del fuente en C.
Con el enlazador pic30-coff-ld enlazo a todos los anteriores en un solo binario.
Con el pic30-bin2hex cambio el formato del binario (para a ser hex).

Para trabajar con formato ELF las herramientas serian pic30-elf-as, etc (ver directorio BIN de C30).
Todo esto para C30, pero con otros lenguajes es lo mismo: compilar todo en el mismo formato OBJ y despues enlazar. También existen herramientas para convertir un formato OBJ en otro.

En realidad todos estos pasos siempre ocurren de forma transparente, incluso cuando solo tenemos un archivo escrito en C: finalmente todo es enlazado con crt0.o y alguna libreria que hubieramos empleado.

Las carpetas 01, 02 y 03 contienen lo mismo: primero los tres fuente, despues agregue un bat, y en el ultima ejecuta el bat.

A esta altura podemos concluir esto sobre el especificador extern: Sirve para indicar al compilador que toda referencia a dicha funcion deve resolverse durante el enlazado, porque la definición de la función talvez se encuentra en otro fichero (pero si se define en el mismo no esta mal, hice esto en la funcion llamada 'recursiva' en el ejemplo adjunto).

yo estaba hablando de DLL y extern se utiliza...

extern se utiliza para enlace estatico, no dinámico (DLL, Dynamic Link Library, biblioteca de enlace dinámico), y del enlace dinamico al micro pic hay un largo trecho compañero...

el EXTERN en c y en ccs el uso es el mismo.

Si bien CCS no es el ANSI C, extern se utliza de igual modo.

Esperamos poder ayudarte con todo esto jezus, tu iniciaste el hilo :-/
« Última modificación: 28 de Agosto de 2009, 17:02:44 por fabianjm »
@fabianjsm is on twitter

Desconectado Suky

  • Moderador Local
  • DsPIC33
  • *****
  • Mensajes: 6758
Re: Funciones
« Respuesta #12 en: 28 de Agosto de 2009, 17:10:19 »
mmm  :? Me parece que eso no es posible hacerlo con CCS.
No contesto mensajes privados, las consultas en el foro

Desconectado RICHI777

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 1498
Re: Funciones
« Respuesta #13 en: 28 de Agosto de 2009, 17:51:45 »
Hola Fabian, esta todo perfecto lo que pusiste ! a mi entender solo falto aclarar algo. Cuando se trabaja en multiples lenguajes, aparte de las cosas que describiste, es necesario tener en cuenta cual es la convención de llamada o invocación de las funciones para que podamos usar funciones escritas en otro lenguaje, las mas conocidas aunque no todos los compiladores la soportan son estas:

  • Convencion Pascal
  • Convención C
  • Convecion fastcall

Las mismas tratan de como el compilador coloca los parametros en el stack, puede ser de derecha a izquierda, a la inversa y el fastcall se intenta pasar parametros ( los que se puedan ) en los registros. Otra cosa tambien es quien se encarga de limpiar el stack a la salida de la funcion ( variables locales ) en C se encarga el llamador y en Pascal se encarga la propia función.

Saludos !

Desconectado fabianjsm

  • PIC18
  • ****
  • Mensajes: 255
    • fabianjsm is on twitter
Re: Funciones
« Respuesta #14 en: 28 de Agosto de 2009, 19:10:02 »
Gracias RICHI777, tenes razón, era uno de los detalles mas importante y ni lo mensione  :oops:

parece que eso no es posible hacerlo con CCS.
Para que el objeto generado tenga formato COFF se utiliza la opcion +DF (página 17 de ccs_c_maual.pdf).
Esto dice el manual de CCS sobre extern(página 50 de ccs_c_maual.pdf): External variable used with multiple compilation units.  No storage is allocated.  Is used to make otherwise out of scope data accessible.  there must be a non-extern definition at the global level in some compilation unit.
Desde la linea de comandos no es coplicado, y si son muchos archivos un script no viene mal.
Sobre como llamar al compilador desde la linea de comandos, tenes un ejemplo en la página 18 del manual. Nose como se configura el IDE porque no lo ocupo, deberias hacer la pruba y despues contarnos ;-)

En cuanto a las convensiones, en el caso particular de C30, se explica en la página 71 de MPLAB_C30user.pdf (4.13, function call conventions). La idea descrita es una pila implementada por software, ya que no esta disponible la tradicional pareja PUSH-POP para acceder directamente a la pila del hardware, almacenando los arguemntos en registros, asi como el valor de retorno. Algo similar se emplea en los micros pic pequeños, pero en vez del registro W se empleea los de proposito general. Existe ademas una convension de nombres: la funcion declarada como funcionx en C, es definida como _funcionx en ASM (algunos compiladores C suele agregar un guion bajo a todos los símbolos con liga externa).

Ahora si, creo que nos fuimos del hilo no?
@fabianjsm is on twitter