Foros del Web » Programación para mayores de 30 ;) » C/C++ »

problemas con "contadores"

Estas en el tema de problemas con "contadores" en el foro de C/C++ en Foros del Web. Hola de nuevo ^^U aqui vuelvo con mis dudas ^^U primero de todo, siento no especificar en el titulo un tema mas concreto (como la ...
  #1 (permalink)  
Antiguo 05/06/2006, 07:07
 
Fecha de Ingreso: mayo-2006
Mensajes: 11
Antigüedad: 18 años, 8 meses
Puntos: 0
problemas con "contadores"

Hola de nuevo ^^U aqui vuelvo con mis dudas ^^U
primero de todo, siento no especificar en el titulo un tema mas concreto (como la otra vez que puse "ficheros"), pero no se a que tema corresponde esta duda ^^U

Vereis, lo que me pasa esta vez, es que en una funcion para ordenar vectores(varias de hecho, pero como son casi iguales solo pongo una), uso 2 contadores para ver el numero de intercambios y pasadas que hace. Pues bien, durante la función me cuenta bien ambas cifras, pero si le pido el valor de la variable "contador" y la variable "intercambio" fuera de la función, me pasa el valor inicial (0 en mi caso) en vez del final. Pongo el trozo de programa que corresponde (el main no esta cerrado, porque no pongo todo):
____________________________________________

typedef int *p_int;

int main()
{
int intercambio;
int contador;
long largo;
p_int v,copia;

_____
copia=malloc(sizeof(v));
memcpy(copia1,v,largo*sizeof(int));
contador=0; intercambio=0;
seleccion(copia, largo, contador, intercambio);
printf("\nHas hecho %d intercambios i %d pasadas.\n", intercambio, contador);
system("pause");
_____

void seleccion (p_int v, int medida, int contador, int intercambio)
{
int i, j, min,t,c;
for ( i=0 ; i<medida-1; i++)
{ contador++;
min = i;
for ( j = i+1 ; j < medida ; j++)
{contador++;
if (v[j] < v[min])
{min = j;}
}
if (min != i)
{intercambio+=3;;
t=v[i];
v[i]=v[min];
v[min]=t;
}
}
}
_________________________________

Pues bien, de lo que he puesto ahi, en el 2º trozo, el "printf" me da el valor inicial (el 0) de ambos contadores, y quiero que me de el que tienen estos al acabar la funcion "seleccion".
Como son 2 cosas no puedo usar el return, asi que intente crear una variable nueva con 2 enteros y darle a esta los valores de los contadores (dentro de la funcion) y devolver la variable esta (debajo pongo el trozo de esto), pero de esta forma, solo me deja usar 2 metodos de ordenar (los que sean) a la que le doy al 3º se sale del programa o_O y no es porque alguna función esté mal, porque todas funcionan si las uso en 1º o 2º lugar ^^U
Lo pongo (una, porque todas son casi iguales):
__________________________________________

typedef int *p_int;
typedef struct c_i
{
int i;
int c;
}c_i;

________________________________________
main()
{
c_i c1,c2,c3,c4;
long largo;
p_int v,copia;

______________________________

copia=malloc(sizeof(v));
memcpy(copia,v,largo*sizeof(int));
c1=seleccion(copia, largo);
printf("\nHas hecho %d intercambios i %d pasades.\n",c1.i,c1.c);
system("pause");
_______________________________________

c_i seleccion (p_int v, int medida)
{
int i, j, min,t,contador=0, intercambio=0;
c_i devuelve;
for ( i=0 ; i<medida-1; i++)
{ contador++;
min = i;
for ( j = i+1 ; j < medida ; j++)
{contador++;
if (v[j] < v[min])
{min = j;}
}
if (min != i)
{intercambio+=3;;
t=v[i];
v[i]=v[min];
v[min]=t;
}
}
devuelve.i=intercambio;
devuelve.c=contador;
return(devuelve);
}
________________________________________

Ahi está todo lo que influye en el fallo. No se que hago mal ^^U Uno no imprime bien los resultados, y el otro se cuelga si lo uso mas de 2 veces xD
Si me ayudais me hareis un gran favor ^^ y si necesitais mas información para ayudarme, decirlo ^^
Gracias.
  #2 (permalink)  
Antiguo 05/06/2006, 17:19
 
Fecha de Ingreso: abril-2006
Ubicación: Acapulco Gro. México
Mensajes: 483
Antigüedad: 18 años, 8 meses
Puntos: 2
Todo parece estar bien, si tus algoritmos de ordenacion son optimos o no, tu lo tienes que ver, con respecto a el problema que tienes te dire:

C y C++ usan parametros por valor en sus funciones, esto significa que las variables que usas dentro de tu funcion no son las mismas que le pasaste sino una copia:

ejemplo:

int a = 1;
int b = 2;

void add(int a, int b)
{
a += b;
}

add(a, b);

//en este punto a es 1 y b es 2

por que? pr que en realidad lo que se hace es algo como esto.

void add(_a, _b)
int a = _a;
int b = _b;
{
a += b;
}

(Esta es la sintaxis del viejo C, para las funciones.)
.

para poder mantener los cambios se usan parametros punteros en C/C++ o referencias en C++.

punteros:
void add(int* a, int* b)
{
(*a) += (*b);
}

referencias:
void add(int& a, int& b)
{
a += b;
}

eso es lo basico...

Saludos
  #3 (permalink)  
Antiguo 06/06/2006, 11:51
 
Fecha de Ingreso: mayo-2006
Mensajes: 11
Antigüedad: 18 años, 8 meses
Puntos: 0
Bueno, he cambiado el "int" por "*int" y "contador/intercambio" por
"(*contador)/(*intercambio)" pero ahora el programa peta al entrar en la función. He añadido "printf" para saber donde se bloquea, y es en el 1º bucle "for". La funcion es la misma (salvo los 2 cambios que puse arriba), pero la pongo igualmente:
_____________________________________________

void seleccion (p_int v, int medida, int* contador, int* intercambio)
{
int i, j, min,t,c;
for ( i=0 ; i<medida-1; i++)
{ (*contador)++;
min = i;
for ( j = i+1 ; j < medida ; j++)
{(*contador)++;
if (v[j] < v[min])
{min = j;}
}
if (min != i)
{(*intercambio)+=3;;
t=v[i];
v[i]=v[min];
v[min]=t;
}
}
}
_____________________________

¿Hay algo mal heho en el bucle? ¿ o yo entendi mal y no debia cambiar lo que cambié?
Gracias.

P.D: Se me olvido decirlo y no se si importa mucho, pero programo en C, y no en C++ ^^U
  #4 (permalink)  
Antiguo 06/06/2006, 16:15
 
Fecha de Ingreso: abril-2006
Ubicación: Acapulco Gro. México
Mensajes: 483
Antigüedad: 18 años, 8 meses
Puntos: 2
Tu variable puntero copia solo reserva memoria para un índice y tu lo accedes según largo esto probablemente te cause errores de acceso.

Para evitar esto tendrías que hacer:
Antes de usar copia:
scanf(”%d”,& largo);

copia = (p_int)malloc(sizeof(int)*largo);


Además de esto mencionar, que tienes llamar a la función selección:

selección(copia, largo, &contador, &intercambio);


Revísalo y me cuentas.

Saludos.
  #5 (permalink)  
Antiguo 07/06/2006, 04:21
 
Fecha de Ingreso: mayo-2006
Mensajes: 11
Antigüedad: 18 años, 8 meses
Puntos: 0
Bueno, eso que has puesto lo tenia en la funcion para crear el vector, lo que me faltaba era el "&". Aunque aun asi, en las otras funciones, no me va bien o.O y ademas, me da el mismo error que en la otra (la de abajo) xD

Pero he mirado de nuevo en la otra version (en la que cree un tipo de estructura para los contadores) y ahora va, pero solo si el vector es menor que 5, es decir, si tiene de 1 a 4 nodos. En caso de tener 5 o mas, solo me deja hacerlo 2 veces, a la que selecciono el 3º metodo para ordenar sale del programa (aunque sea todo el rato el mismo). Y si tiene un numero de 3 o mas cifras (mas de 100) peta directamente xD
Lo pongo:

__________________________________________________ _________

#include <time.h>
#include <stdlib.h>
#include <stdio.h>
#include <mem.h>
#include <string.h>

typedef int *p_int;
typedef struct c_i
{
int i;
int c;
}c_i;

char menu();
int *genera(int);
c_i seleccion(p_int v, int medida);
...
void mostrar(p_int v, long mida);

______________________________
int main()
{ int opcion,final=1,entrarA=0;
c_i c1,c2,c3,c4;
long largo;
p_int v,copia1,copia2,copia3,copia4;
printf("Si pulsas una tecla, aparecera el menu:\n ");
getche();
system("cls");

do {
opcion=menu();
switch(opcion)
{
case'a':{
printf("\nEscrive la longitud del vector.\n");
scanf("%ld",&largo);
v=genera(largo);
mostrar(v, largo);
entrarA=1;
}
break;
case'b': {if(entrarA==0)
{printf("\nNo hay un vector entrado.\n");
system("pause");
}
else
{copia1=malloc(sizeof(v));
memcpy(copia1,v,largo*sizeof(int));
c1=seleccion(copia1, largo);
printf("\nHas hecho %d intercambios i %d pasades.\n",c1.i,c1.c);
system("pause");
}
}
break;
...(aqui van el case'c', etc, del resto de las funciones, son iguales).

case'h': final=0;
}
}
while (final);
}

____________________________________

El menu no lo pongo porque lo use en otros programas y si funciona.

int *genera(int largo)
{
int i, *vector, *p;
vector=(int*)calloc(sizeof(int),largo);
p=vector;
srand(clock());
for(i=0;i<largo;i++,p++) *p=rand();
return vector;
}


c_i seleccion (p_int v, int medida)
{
int i, j, min,t,contador=0, intercambio=0;
c_i devuelve;
for ( i=0 ; i<medida-1; i++)
{ contador++;
min = i;
for ( j = i+1 ; j < medida ; j++)
{contador++;
if (v[j] < v[min])
{min = j;}
}
if (min != i)
{intercambio+=3;;
t=v[i];
v[i]=v[min];
v[min]=t;
}
}
devuelve.i=intercambio;
devuelve.c=contador;
return(devuelve);
}

...(aqui va el resto de funciones de ordenacion, son como la de seleccion mas o menos, asi que no las pongo)

void mostrar(p_int v, long medida)
{int i;
for (i=0;i<=medida;i++)
{printf("v[%d]=%d \t",i,v[i]);}
system("pause");
}

____________________________________

Espero que eso sea suficiente para que me podais ayudar. Las funciones de ordenacion, tienen todas la misma estructura (salvo el modo en que hacen los cambios, pero eso no es lo que da fallo) por eso solo pongo una a modo de ejemplo, porque no creo que el fallo sea de ahi, puesto que aunque en unas condiciones concretas (vectores pequeños) funcionan.
Gracias por las molestias y siento rayaros tanto ^^U
  #6 (permalink)  
Antiguo 07/06/2006, 16:28
 
Fecha de Ingreso: abril-2006
Ubicación: Acapulco Gro. México
Mensajes: 483
Antigüedad: 18 años, 8 meses
Puntos: 2
hay errores muy sutiles, y sin el codigo totalmente completo me es dificil seguirlo.

uno que puede ver es que intentas retornar un puntero des la funcion genera():

esto es imposible.

esdecir un puntero declarado dentro de una funcion es una variable atomatica, como tal sera destruida al salir de la funcion.

esto dejara al puntero receptor sin una direccion valida..
intenta pasando tu puntero a la funcion como un parametro.

Saludos.
  #7 (permalink)  
Antiguo 09/06/2006, 13:29
 
Fecha de Ingreso: mayo-2006
Mensajes: 11
Antigüedad: 18 años, 8 meses
Puntos: 0
Siento no haber escrito antes, pero no me iva la pagina xD

Al final he podido solucionarlo poniendo esto que me dijiste:
copia = (p_int)malloc(sizeof(int)*largo);

en lugar de lo que tenia y funciono (y eso que el que tenia me lo dijo mi profesor... -_-U cada dia pienso mas que es un inutil xD)

gracias por toda la ayuda prestada.
Atención: Estás leyendo un tema que no tiene actividad desde hace más de 6 MESES, te recomendamos abrir un Nuevo tema en lugar de responder al actual.
Respuesta




La zona horaria es GMT -6. Ahora son las 18:20.