Autor Tema: :: CCS :: Funciones fuera del main :: (SOLUCIONADO)  (Leído 3824 veces)

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

Desconectado pajaro

  • PIC24H
  • ******
  • Mensajes: 1121
:: CCS :: Funciones fuera del main :: (SOLUCIONADO)
« en: 29 de Junio de 2012, 14:34:52 »
Hola

Hace unas semanas implemente una funcion , miren este enlace:

http://www.todopic.com.ar/foros/index.php?topic=38644.0

La cual es muy util para generar aleatorios distintos,
cuando la cree la cree dentro del main y funcionaba perfecta
el problema viene ahora cuando quiero exportarla para su uso desde fuera del main
como una funcion cualquiera.

esta funcion trabaja con "vectores", y con tamaños del vector,
la cosa es que al exportarla fuera el tamaño de uno de los vectores no lo coge bien
y si se lo defino tamaño como 4 me lo detecta como 2:

la funcion es esta:
bbb[4];
t1_g=sizeof(bbb);

t1_g= 4 me da en el main

desde funcion 2...

si se ejecuta dentro del main perfecto pero
desde otra funcion dentro del main.. como que se queja..

he probado a declarar bbb como varaiblae global y se sigue quejando..


esto seria una forma de declararla
Código: C++
  1. void funcion(int8 *v1[], int8 *v2[], int8 t1, int8 t2){
  2.  
  3. }

para llamarla seria
Código: C++
  1. funcion(v1, v2, t1, t2);

otra forma seria:

Código: C++
  1. //v1 y v2 de la misma dimension
  2. int8 funcion(int8 *v1[], int8 t1){
  3.  
  4. int8 v2[];
  5. ..
  6. ..
  7. return v2[];
  8. }


para llamarla seria

Código: C++
  1. ...
  2. funcion(v1, t1);
  3. ...

de esta segunda forma creo que no se como se pueden exportar todo un vector
y aun mas dificil cargar los valores en otro vector.

¿Se podria exportar la dirección del vector resultante como un puntero?

... bueno y lo de cargar en otro vector...


voy a seguir investigando..




« Última modificación: 30 de Junio de 2012, 16:32:25 por pajaro »

Desconectado BrunoF

  • Administrador
  • DsPIC30
  • *******
  • Mensajes: 3865
Re: :: CCS :: Funciones fuera del main ::
« Respuesta #1 en: 29 de Junio de 2012, 14:54:02 »
Hola pájaro.

Cuando se pasa un array a una función en C, excepto tengas un caracter delimitador (como en un String es el ''\0') la función dentro no tiene forma de saber el tamaño. Tenés que pasarle el tamaño del arreglo también.

Código: C
  1. void cmp_n_v(int8 n, int8 *v[],int8 t){
  2. int8 a;
  3.  
  4. for (a=0;a<t;a++){
  5.  if(v[a] == n){
  6.     v[a] = 0;
  7.  }
  8. }
  9.  
  10. }

si dentro de dicha función hiciese:

sizeof(v)

obtendría el valor 2, ya que lo que el compilador sólo ve un puntero, no el arreglo en sí, y por lo tanto recupera el tamaño del puntero, que por lo general, en CC es de 2 bytes. Nunca va a poder obtener el tamaño del arreglo ya que no tiene forma de saberlo. Sólo recibe una posición de memoria, nada más.

Podrías poner el contenido de la función que pretendés implementar?


"All of the books in the world contain no more information than is broadcast as video in a single large American city in a single year. Not all bits have equal value."  -- Carl Sagan

Sólo responderé a mensajes personales, por asuntos personales. El resto de las consultas DEBEN ser escritas en el foro público. Gracias.

Desconectado pajaro

  • PIC24H
  • ******
  • Mensajes: 1121
Re: :: CCS :: Funciones fuera del main ::
« Respuesta #2 en: 29 de Junio de 2012, 15:30:45 »
Hola pájaro.

Cuando se pasa un array a una función en C, excepto tengas un caracter delimitador (como en un String es el ''\0') la función dentro no tiene forma de saber el tamaño. Tenés que pasarle el tamaño del arreglo también.

Código: C
  1. void cmp_n_v(int8 n, int8 *v[],int8 t){
  2. int8 a;
  3.  
  4. for (a=0;a<t;a++){
  5.  if(v[a] == n){
  6.     v[a] = 0;
  7.  }
  8. }
  9.  
  10.  
  11.  
  12. }

si dentro de dicha función hiciese:

sizeof(v)

obtendría el valor 2, ya que lo que el compilador sólo ve un puntero, no el arreglo en sí, y por lo tanto recupera el tamaño del puntero, que por lo general, en CC es de 2 bytes. Nunca va a poder obtener el tamaño del arreglo ya que no tiene forma de saberlo. Sólo recibe una posición de memoria, nada más.

Podrías poner el contenido de la función que pretendés implementar?





Hola BrunoF

la funcion esta en el enlace que he colgado, en el primer post

pero en el main tambien se la pasaba como puntero
y ahi no se quejaba,...
y si le pasara lo que ocupa el dato de donde apunta el puntero, un puntero de puntero..
me coge el dato delpuntero pero to quiero el dato de lo que apunta el puntero..

me has dado una idea ...voy a probar..

teorica mente tendria que funcionar no,
si le pasas la variable del valor 5 mirara cuanta dirección ocupa.

sigo indagando..

« Última modificación: 29 de Junio de 2012, 16:33:07 por pajaro »

Desconectado pajaro

  • PIC24H
  • ******
  • Mensajes: 1121
Re: :: CCS :: Funciones fuera del main ::
« Respuesta #3 en: 29 de Junio de 2012, 15:41:09 »
Hola BrunoF

Pongo el codigo:

lo que va para funcion y estaba en el main:

Código: C++
  1. ..
  2. // TODO: USER CODE!!
  3.  
  4.    int8 va1[6];                  //vector inicial
  5.    int8 g_post[6];               //vector destino
  6.    int8 t1;                      //tamaño vector inical
  7.    int8 t1_g;                    //tamaño vector destino
  8.    
  9.    int8 cnt_p_vf=0;              //pos wr en vector destino
  10.    int8 n_z_va1=0;               //numero de ceros en v inicial
  11.    int8 n_en_v;                  //numero a wr en v destino
  12.    int8 pos_z;                   //posicon del cero en v inicial
  13.    int8 mi_n;                    // n ale del gen aleatorio
  14.    
  15.  
  16.    t1=sizeof(va1);               // tamaño del vector
  17.    t1_g=sizeof(g_post);          // tamaño del vector
  18.    ini_v_es(va1,t1);             // inicia vector 1234
  19.    ini_v(g_post,t1_g,0);         // inicia vector 0000
  20.    muestra_v(va1,t1);            // muestra vector va1
  21.    
  22.    while(t1!=0){
  23.    
  24.    printf("\n\r ------- vector va1  -------R ");
  25.    muestra_v(va1,t1);            // muestra vector
  26.    
  27.    mi_n=genera_aleatorio(t1);          // genera aleatorio
  28.    printf("\n\r num rnd: %d "mi_n);    // muestra aleatorio
  29.    
  30.    t1_g=sizeof(g_post);                // tamaño del vector de guardado
  31.    printf("\n\r g_post size: %d"t1_g); // muestra tamaño
  32.    
  33.    //ini_v(g_post,t1_g,0);             // inicializa a 0 vector guarda posiciones
  34.    printf("\n\r ------- vector g_post  -------1 ");
  35.    muestra_v(g_post,t1_g);              // muestra vector g__post
  36.    n_en_v=guarda_n_v_v(va1,g_post,mi_n,cnt_p_vf); //guarda el numero de post en v
  37.    
  38.  
  39.    
  40.    printf("\n\r ------- vector g_post  -------2 ");
  41.    muestra_v(g_post,t1_g);       // muestra vector con el valor cargado
  42.    
  43.    cmp_n_v(n_en_v, va1,t1);      // marca con cero el ale en v inicio
  44.    
  45.    printf("\n\r ------- vector va1  -------3 ");
  46.    muestra_v(va1,t1);            // muestra vector inicial
  47.    printf("\n\r ------------");
  48.    n_z_va1=cnt_0(va1,t1);         // cnt n ceros en v inicial
  49.    pos_z=post_cero(va1,0,t1);     // posicion del cero en v ini
  50.    
  51.    printf("\n\r ini(0)pos del cero: %d"pos_z);   // muestra posicion del cero
  52.    desplaza_0(va1,pos_z,t1);      // desplaza cero 0123 -> 1230
  53.    
  54.    printf("\n\r ------- vector va1  -------4 ");
  55.    printf("\n\r T1 tamaño: %d"t1);       // muestra tamaño de v ini
  56.    printf("\n\r n_ ceros: %d"n_z_va1);   // muestra n ceros de v ini
  57.    muestra_v(va1,t1);                    // muestra vector
  58.    n_z_va1=cnt_0(va1,t1);                //-- cnt n ceros en v
  59.    t1=reduce_v(n_z_va1,t1);       // reduce busqueda
  60.    
  61.    printf("\n\r ------- vector va1  -------5 ");
  62.    printf("\n\r --- vector va1 --- ");   // vector va1
  63.    muestra_v(va1,t1);             // muestra vector va1 t1=0 => usar t1_g
  64.    printf("\n\r --- vector g_post --- ");   // vector va1
  65.    muestra_v(g_post,t1_g);        // muestra vector g_post_g
  66.    cnt_p_vf=cnt_p_vf+1;           // inc post de guardado de vector
  67.    
  68.    printf("\n\r ------- xxxxxxxxxx  -------5 ");
  69.    
  70.    }
  71. ..


Ahi esta Bruno

Como se muestra es tal cual lo tengo en el main.



---
Creo que ya se lo que ocurre,
al pasarla como puntero como dice Bruno
solo ve la cantidad que ocupa un puntero
es decir si durante la llamada a la funcion se redefiniere dentro de la funcion en ejecucion,
si que veria ese tamaño, lo malo es lo que ocuparia menos mal que al salir de la funcion ese espacio se libera.

El problema es como hago para redefinir una variable dinamica en proceso de ejecucion
variable de los propios parametros de la función.
..

voy a investigar...



« Última modificación: 29 de Junio de 2012, 16:35:25 por pajaro »

Desconectado BrunoF

  • Administrador
  • DsPIC30
  • *******
  • Mensajes: 3865
Re: :: CCS :: Funciones fuera del main ::
« Respuesta #4 en: 29 de Junio de 2012, 22:55:46 »
Hola. Realmente no entiendo cuál es el problema. Creo entender parte de tu pregunta, pero no del toda.

Si la idea es poder tomar dos vectores: un origen y un destino y someterlo a una función  para modificar el destino a partir del origen, pues te doy un ejemplo:

Código: C
  1. void compara(unsigned int8 * vectorEntrada, unsigned int8 * vectorSalida, unsigned int8 elementosEnVectorEntrada, unsigned int8 valorASumar){
  2.     while(elementosEnVectorEntrada--){
  3.         *vectorSalida = *vectorEntrada + valorASumar;
  4.         vectorEntrada++;
  5.         vectorSalida++;
  6.     }
  7. }
  8.  
  9. void main(void){
  10.     unsigned int8 entradas[10] = {0,1,2,3,4,5,6,7,8,9};
  11.     unsigned int8 salidas[10];
  12.  
  13.     compara(&entradas, &salidas, sizeof(entradas), 10);
  14. }

Debería llenar el vector salidas[] con los elementos de entrada, pero sumados en 10 unidades c/uno.

Cuál es tu duda puntual? Que dentro de la función no logras obtener el tamaño del arreglo?

Saludos.
"All of the books in the world contain no more information than is broadcast as video in a single large American city in a single year. Not all bits have equal value."  -- Carl Sagan

Sólo responderé a mensajes personales, por asuntos personales. El resto de las consultas DEBEN ser escritas en el foro público. Gracias.

Desconectado pajaro

  • PIC24H
  • ******
  • Mensajes: 1121
Re: :: CCS :: Funciones fuera del main ::
« Respuesta #5 en: 30 de Junio de 2012, 09:56:29 »
Hola. Realmente no entiendo cuál es el problema. Creo entender parte de tu pregunta, pero no del toda.

Si la idea es poder tomar dos vectores: un origen y un destino y someterlo a una función  para modificar el destino a partir del origen, pues te doy un ejemplo:

Código: C
  1. void compara(unsigned int8 * vectorEntrada, unsigned int8 * vectorSalida, unsigned int8 elementosEnVectorEntrada, unsigned int8 valorASumar){
  2.     while(elementosEnVectorEntrada--){
  3.         *vectorSalida = *vectorEntrada + valorASumar;
  4.         vectorEntrada++;
  5.         vectorSalida++;
  6.     }
  7. }
  8.  
  9. void main(void){
  10.     unsigned int8 entradas[10] = {0,1,2,3,4,5,6,7,8,9};
  11.     unsigned int8 salidas[10];
  12.  
  13.     compara(&entradas, &salidas, sizeof(entradas), 10);
  14. }

Debería llenar el vector salidas[] con los elementos de entrada, pero sumados en 10 unidades c/uno.

Cuál es tu duda puntual? Que dentro de la función no logras obtener el tamaño del arreglo?

Saludos.



Hola Bruno

Si Bruno asi es, al hacer uso de funciones:


programa principal:

void main (){

..

//desde aca llamare a mi funcion cuando la tenga creada como funcion
//con ella obtendre un vector aleatorio
}



programa de dentro del main que quiero convertir en funcion:


Código: C++
  1. aca dentro tengo muchas cosas una de ellas es:
  2. vector 1
  3. vector 2
  4. tamaño vector 1
  5. tamaño vector 2
  6.  
  7. funcion que me da el tamaño del vector-->sizeof()

el problema es que al pasarle como puntero solo me detecta el tamaño del puntero
deberia detectarme si el vector es de 4 retornarme 4 no dos que es lo que ocupa el puntero,

la funcion  que me genera aleatorio como depende el tamaño tambien enloquece.

lo primero que pense fue en esto,

void aleatorio_vector(int8 *va1[],int8 *g_post[],int8 t1,int8 t1_g)



si se los paso asi:

aleatorio_vector(int8 va1[],int8 g_post[],int8 t1,int8 t1_g)

tambine lo hace mal:

toda la funcion esta ligada al tamano del vector que continuamnete calcula su tamaño.


la unica solucion que se ocurre es crear un vector dentro de la funcion, de tamaño mayor al que nunca se llegue
y sobre el volcar los valores del vector pasado como parametro, ...

no se como lo subsanare porque si meto todo en una funcion o procedimineto
sin pasarle prametros funciona,
pero yo lo que quiero es que sea variable..

ya vere como lo apaño...


Otra cosa...

Como exporto el vector genereado?

¿como un puntero y su tamaño?


Un saludo...

sigo con el codigo..


« Última modificación: 30 de Junio de 2012, 16:34:49 por pajaro »

Desconectado pajaro

  • PIC24H
  • ******
  • Mensajes: 1121
Re: :: CCS :: Funciones fuera del main ::
« Respuesta #6 en: 30 de Junio de 2012, 16:27:55 »
Hola
Ya he solucionado el problema
solo le paso el tamaño del vector de salida
y funciona.

queda asi la cabecera:

Código: C++
  1. [color=blue]aleatorio_vector(int8 *v_sale,int8 t1e){}[/color]

quedo algo asi:
Código: C++
  1. void aleatorio_vector(int8 *v_sale,int8 t1e){
  2. // para ver paso a paso descomentar linea debug
  3.    
  4.    int8 va1[9];                  //vector inicial
  5.    int8 g_post[9];               //vector destino
  6.    int8 t1;                     //tamaño vector inical
  7.    int8 t1_g;                  //tamaño vector destino
  8.    
  9.    int8 cnt_p_vf=0;              //pos wr en vector destino
  10.    int8 n_z_va1=0;               //numero de ceros en v inicial
  11.    int8 n_en_v;                  //numero a wr en v destino
  12.    int8 pos_z;                   //posicon del cero en v inicial
  13.    int8 mi_n;                    // n ale del gen aleatorio
  14.    
  15.    //int8 t1e=7;
  16.  
  17.    t1=sizeof(va1);               // tamaño del vector
  18.    t1_g=sizeof(g_post);          // tamaño del vector
  19.    //--- añado para pasar tamaño como parametro
  20.    t1=t1e;
  21.    t1_g=t1e;
  22.    //---- xxxxxxxxxxxxxxxxxxxxx  -----------------
  23.    ini_v_es(va1,t1);             // inicia vector 1234
  24.    ini_v(g_post,t1_g,0);         // inicia vector 0000
  25.    muestra_v(va1,t1);            // debug muestra vector va1
  26.    
  27.  
  28.  
  29.    while(t1!=0){
  30.    
  31.    //printf("\n\r ------- vector va1  -------R "); //debug
  32.    //muestra_v(va1,t1);            // debug muestra vector
  33.    
  34.    mi_n=genera_aleatorio(t1);          // genera aleatorio
  35.    //printf("\n\r num rnd: %d "mi_n);    // debug muestra aleatorio
  36.    
  37.    //t1_g=sizeof(g_post);                //mmm tamaño del vector de guardado
  38.    //printf("\n\r g_post size: %d"t1_g);   //debug muestra tamaño
  39.    
  40.    //ini_v(g_post,t1_g,0);             // inicializa a 0 vector guarda posiciones
  41.    //printf("\n\r ------- vector g_post  -------1 "); //debug
  42.    //muestra_v(g_post,t1_g);              //debug muestra vector g__post
  43.    n_en_v=guarda_n_v_v(va1,g_post,mi_n,cnt_p_vf); //guarda el numero de post en v
  44.    
  45.  
  46.    
  47.    //printf("\n\r ------- vector g_post  -------2 ");// debug
  48.    //muestra_v(g_post,t1_g);       //debug muestra vector con el valor cargado
  49.    
  50.    cmp_n_v(n_en_v, va1,t1);      // marca con cero el ale en v inicio
  51.    
  52.    //printf("\n\r ------- vector va1  -------3 ");//debug
  53.    //muestra_v(va1,t1);            //debug muestra vector inicial
  54.    //printf("\n\r ------------");  //debug
  55.    n_z_va1=cnt_0(va1,t1);          // cnt n ceros en v inicial
  56.    pos_z=post_cero(va1,0,t1);      // posicion del cero en v ini
  57.    
  58.    //printf("\n\r ini(0)pos del cero: %d"pos_z);   //debug muestra posicion del cero
  59.    desplaza_0(va1,pos_z,t1);      // desplaza cero 0123 -> 1230
  60.    
  61.    //printf("\n\r ------- vector va1  -------4 "); //debug
  62.    //printf("\n\r T1 tamaño: %d"t1);       // debug  muestra tamaño de v ini
  63.    //printf("\n\r n_ ceros: %d"n_z_va1);   // debug  muestra n ceros de v ini
  64.    //muestra_v(va1,t1);                    // debug  muestra vector
  65.    n_z_va1=cnt_0(va1,t1);                //-- cnt n ceros en v
  66.    t1=reduce_v(n_z_va1,t1);       // reduce busqueda
  67.    
  68.    //printf("\n\r ------- vector va1  -------5 "); //debug
  69.    //printf("\n\r --- vector va1 --- ");           // debug  vector va1
  70.    //muestra_v(va1,t1);             // debug  muestra vector va1 t1=0 => usar t1_g
  71.    //printf("\n\r --- vector g_post --- ");   // debug  vector va1
  72.    //muestra_v(g_post,t1_g);        // debug  muestra vector g_post_g
  73.    cnt_p_vf=cnt_p_vf+1;           // inc post de guardado de vector
  74.    
  75.    //printf("\n\r ------- xxxxxxxxxx  -------5 "); //debug
  76.    
  77.    }
  78.    copy_v(g_post,v_sale,t1e);
  79.  
  80. }
  81.    
  82.    int8 ocupa_1(int8 *v1[4]){
  83.    int8 t1;
  84.    int8 t2[6];
  85.    t1=sizeof(v1);
  86.    return t1;
  87.    
  88.    }

para llamar a la funcion desde el main:

Código: C++
  1. main(){
  2. int8 vector[4];
  3.  
  4.  aleatorio_vector(vector,4);
  5.  
  6.  
  7. }


Un Saludo

Gracias por su colaboracion.


Desconectado Geo

  • Colaborador
  • PIC24F
  • *****
  • Mensajes: 922
    • Mexchip
Re: :: CCS :: Funciones fuera del main ::
« Respuesta #7 en: 30 de Junio de 2012, 16:55:58 »
Solo para aclarar, en C, la longitud de un array no se puede obtener a partir de un array recibido como parámetro en tiempo de ejecución.
La obteción de los bytes de un array usando sizeof se hace en tiempo de compilación, el compilador sustituye la llamada a sizeof para un array por el tamaño en bytes del array, pero el tamaño de dicho array no se guarda en ningún lugar en memoria, por lo que no es posible obtenerlo al momento de ejecutar.

Esa es la razón de que te funcionara diferente en main y en la función que recibía el vector como parámetro, y por la cual es necesario que pases a la función también el tamaño del vector con el que va a trabajar.
« Última modificación: 30 de Junio de 2012, 16:58:10 por Geo »
La imaginación es el límite.
Visita mi blog, en inglés o en español :).
Mini curso de introducción a VHDL en MEXCHIP :-/

Desconectado matyvico

  • PIC10
  • *
  • Mensajes: 20
Re: :: CCS :: Funciones fuera del main ::
« Respuesta #8 en: 28 de Enero de 2013, 13:25:07 »
Solo para aclarar, en C, la longitud de un array no se puede obtener a partir de un array recibido como parámetro en tiempo de ejecución.
La obteción de los bytes de un array usando sizeof se hace en tiempo de compilación, el compilador sustituye la llamada a sizeof para un array por el tamaño en bytes del array, pero el tamaño de dicho array no se guarda en ningún lugar en memoria, por lo que no es posible obtenerlo al momento de ejecutar.

Esa es la razón de que te funcionara diferente en main y en la función que recibía el vector como parámetro, y por la cual es necesario que pases a la función también el tamaño del vector con el que va a trabajar.

Me salvaste la vida! estaba intentando hacer algo como:

Código: [Seleccionar]
for(i=0;i<=strlen(pepe);i++){
...
}

Y era para dibujar un menú, casualmente la función que hacia eso iba fuera del main y no me permitía avanzar mas allá del 4to elemento... (supongo que esta relacionado directamente a los 2 bytes que considera como longitud de los punteros). Aclaro que pepe era un array de dos dimensiones, así que supongo que de ahí los 4 bytes y los 4 elementos de menú que me dejaba avanzar)
« Última modificación: 28 de Enero de 2013, 13:34:15 por matyvico »


 

anything