Problema con vector y direcciones

Iniciado por OnLOL, 21 Noviembre 2010, 03:47 AM

0 Miembros y 1 Visitante están viendo este tema.

OnLOL

Estoy precticando, e intente hacer un "ordenador" de numeros, los numeros dentro de un vector, se los deberia ordenar de menor a mayor, pero el compilador me esta dando problemas, se que es con las direcciones pero no se donde tocar, fuero de eso el programa no esta terminado, por que no se como automatizar que se de cuenta si ya se termino de ordenar o le falta.

Código (cpp) [Seleccionar]
#include <iostream>
using namespace std;

int OrdenarMeMa(int);

int array[10];
int main()
{
int a=0, *arrayrta[10];
for(a==0;a<10;a++){//obteniendo valores
cout<<"ingrese el valor numero "<<a<<" de "<<sizeof(array)/sizeof(int)<<": "<<endl;
cin>>array[a];
}
cout<<"Estado:"<<endl;//muestra el array obtenido
for(a==0;a<10;a++)
{
cout<<array[a]<<" | ";
}
(int)arrayrta=OrdenarMeMa(array);

for(a==0;a<10;a++)//Muestra el array ordenado
{
cout<<arrayrta[a]<<" | ";
}
return 0;
}

int OrdenarMeMa(int array)
{
int aux, a=0, b=0, array2[10];
bool listo;
while (0==listo)//ordena el array
{
a++;
b = a+1;
if (array2[a]>array2[b])
{
aux = array2[b];
array2[b] = array2[a];
array2[a]= aux;

}
return (int)array2;
}

}



Aca los Errores:
  19:32: error: conversión inválida de 'int*' a 'int'
  19:32: error:   argumento de inicialización 1 de 'int OrdenarMeMa(int)'
  19:32: error: se requiere un l-valor como operando izquierdo de la asignación
  30: aviso: se devolvió la dirección de la variable local 'array2'

para compilar uso el GCC, saludos y desde ya muchas gracias

Mr.Blue

Hola, bueno primero usa las etiquetas geshi para poder ver bien el codigo. :xD
Si no me quedo siego. :P

En primer lugar tenes unos problemas de sintaxis en tu codigo como por ejemplo esto

Citarfor(a==0;a<10;a++){//obteniendo valores

a==0  // Estas comparando o preguntando si a es igual a cero
no es necesario en este caso inicializar int a=0, y menos aun, no podes preguntar en el for si a efectivamente es 0.

Citarfor(a=0;a<10;a++){//obteniendo valores

Ahi quedaria

Respecto a usar un puntero, me parece q te hiciste mucho lio, primero trata de entender como es la logica del ordenamiento, y luego implementa punteros, detodas formas, no usastes los punteros correctamente.
Mirate este post

http://foro.elhacker.net/programacion_cc/c_iniciacion_al_manejo_de_los_punteros-t299174.0.html

en la funcion no entiendo que haces ahi con declarar, bool listo;
y en el while (0==listo), no entiendo q haces ahi.

entodo caso podes inicializar una variale ej int k=0;
y luego hacer esto

while (k==0){
k=1;
............

y ahi dentro ir preguntado con if si la cadena en la posicion i es mayo q cadena en la posicion i+1.
algo asi


if (cad>cad[i+1]){
aux=cad[a];
cad[a]=cad[a+1];
cad[a+1]=aux;
}


saludos.

OnLOL

#2
Lei lo de punteros, y lo modifique pero me sigue diciendo lo mismo, creo que el problema esta en el return, va me suena por ahi, lo que queria hacer con la variable boleana ("listo" ahora se llama "ordenado") era  pasar el valor a True cuando estuviera ordenado todo el vector, para que salga del while y devuelva el valor.

Código (cpp) [Seleccionar]
#include <iostream>
using namespace std;

int OrdenarMeMa(int);



int main()
{
int a=0,array[10], *arrayord=NULL;
for(a=0;a<10;a++){//obteniendo valores
cout<<"ingrese el valor numero "<<a<<" de "<<sizeof(array)/sizeof(int)<<": "<<endl;
cin>>array[a];
}
cout<<"Estado:"<<endl;//muestra el array obtenido
for(a==0;a<10;a++)
{
cout<<array[a]<<" | ";
}
arrayord=OrdenarMeMa(array);

for(a=0;a<10;a++)//Muestra el array ordenado
{
cout<<*arrayord[a]<<" | ";
}
return 0;
}

int OrdenarMeMa(int* array)
{
int aux, a=0,i, array2[10];;
bool ordenado=false;
while (false==ordenado)//ordena el array
{


if (array2[a]>array2[a+1]) //compara si el antecedente es mayor al consecuente
{
aux = array2[a+1]; //pasa el consecuente a una varialbe auxiliar
array2[a+1] = array2[a];//pasa el antecedente a la pocicion del consecuente
array2[a]= aux;//pasa el valor de la variable auxiliar al antecedente

}
for(i=0;i<10;i++)//Comprobador
{
if(array[i]<array[i+1]) ordenado=true;//si el antecedente es menor al consecuente, ordenando cambia a True y sale del while
ordenado=false;
}
a++;
}
return &array2;

}


Lo que no entiendo es por que si yo devuelvo los valores de "array2" al puntero "arrayord" me da el error de la conversion.

Aca los errores:

  20:27: error: conversión inválida de 'int*' a 'int'
  20:27: error:   argumento de inicialización 1 de 'int OrdenarMeMa(int)'
  20:27: error: conversión inválida de 'int' a 'int*'
  24:20: error: argumento de tipo inválido del unario '*'
  51:10: error: conversión inválida de 'int*' a 'int'


Littlehorse

#3
Los arreglos locales declarados en una función permanecen solamente en el ámbito de la función respectiva.

Todo esto:

Código (cpp) [Seleccionar]
int aux, a=0,i, array2[10];;

desaparece al finalizar la función "OrdenarMeMa" por lo tanto no puedes acceder a "array2" desde otro modulo por mas que trates de retornar su dirección; al finalizar la función "OrdenarMeMa", "array2" es inaccesible.
No se que le pasara a tu GCC, porque como mínimo te tendría que haber dado un warning al retornar la dirección de una variable local desde una función.




Luego, el valor de retorno de la función "OrdenarMeMa" es incorrecto, ya que esta declarada como para retornar un entero y vos estas retornando un puntero a entero:

Debería ser algo así:

Código (cpp) [Seleccionar]
int* OrdenarMeMa(int* array)

o simplemente retornar un valor entero (0,1 u bool: true, false, como gustes) para chequear si la función fallo o cumplió su tarea correctamente. Si estas pasando el arreglo a ordenar mediante un puntero, no necesitas retornar nada, ya que los arreglos locales se pasan automáticamente por referencia dado que su identificador (su nombre) actúa en forma similar a un puntero.




Seguís teniendo los errores que ya te mencionaron:

Código (cpp) [Seleccionar]
for(a==0;a<10;a++)

== es para comparar, = es para asignar.

Código (cpp) [Seleccionar]
cout<<*arrayord[a]<<" | ";

Estas tratando a un puntero como a un doble puntero.





Dale un repaso al tema de punteros, parece difícil al principio pero luego se hace mas fácil.

Saludos
An expert is a man who has made all the mistakes which can be made, in a very narrow field.

OnLOL

Me baje un manual de punteros , y pude arreglar el programa, sin embargo parece que no era lo unico :P, ahora que me deja ejecutar lo fui viendo con el depurador el gdb creo que es, uso CodeLite que me viene todo junto, y al llegar a

Código (cpp) [Seleccionar]
for(a=0;a<10;a++)
{
//cout<<array[a]<<" | ";
cout<<"aux: "<<*aux<<" | ";

aux++;
}


El cout no me muestra el valor de donde apunta el puntero "aux", lo raro es que en el debuger, el valor de la direccion incrementa y tambien me muestra el valor de "*aux" que son correctos ambos, hice un programa aparte  y si me lo muestra.

Aca el codigo completo:
Código (cpp) [Seleccionar]
#include <iostream>
using namespace std;

int* OrdenarMeMa(int*);


int array2[10],array[10];
int main()
{
int a=0, *arrayord=NULL,*aux;
for(a=0;a<10;a++){//obteniendo valores
cout<<"ingrese el valor numero "<<a<<" de "<<sizeof(array)/sizeof(int)<<": "<<endl;
cin>>array[a];
}
cout<<"Estado:"<<endl;//muestra el array obtenido
aux=&array[0];
for(a=0;a<10;a++)
{
//cout<<array[a]<<" | ";
cout<<"aux: "<<*aux<<" | ";

aux++;
}
arrayord=OrdenarMeMa(array);

for(a=0;a<10;a++)//Muestra el array ordenado
{
//cout<<*arrayord[a]<<" | ";
cout<<*arrayord<<" | ";
arrayord++;
}

return 0;
}

int* OrdenarMeMa(int *array)
{
int aux, a=0,i ;
bool ordenado=false;
while (false==ordenado)//ordena el array
{
if (array2[a]>array2[a+1]) //compara si el antecedente es mayor al consecuente
{
aux = array2[a+1]; //pasa el consecuente a una varialbe auxiliar
array2[a+1] = array2[a];//pasa el antecedente a la pocicion del consecuente
array2[a]= aux;//pasa el valor de la variable auxiliar al antecedente

}
for(i=0;i<10;i++)//Comprobador
{
if(array[i]<array[i+1]) ordenado=true;//si el antecedente es menor al consecuente, ordenando cambia a True y sale del while
ordenado=false;
}
a++;
}
return array2;

}



Littlehorse

#5
No he visto todo el código porque deje de leer cuando vi los arreglos globales. Yo te recomendaría que te bajes "Como programar en C/C++" de Deitel y Deitel y en todo caso vayas directo al capitulo de punteros.
Si no entendes algo de lo mencionado anteriormente, postea las dudas puntuales y las vemos.

Esto te lo digo porque al parecer no entendiste lo que te mencione antes, y me pareció que estaba bien explicado. Es decir, en vez de modificar el diseño del programa para pasar el array por referencia, optaste por usar un array global logrando que no tenga sentido siquiera pasar nada por referencia. Es decir, un array declarado en un scope global permite que puedas acceder a ese array desde cualquier función sin necesidad de ningún tipo de pasaje ni de ningún tipo de retorno, por tanto el uso de los punteros en este caso en particular pierde el sentido completamente.

Mira este ejemplo:

Código (cpp) [Seleccionar]
#include <iostream>
using namespace std;

void imprimir(); //Funcion que retorna void, no acepta ningun parámetro.

int array[]={1,2,3,4,5}; //Array global

int main()
{
imprimir(); //Llamando funcion

cin.get();
}

void imprimir()
{
for(int i=0;i<5;i++)//Imprimiendo elementos del array global
cout<<array[i]<<endl;
}


Como podrás ver, accedes perfectamente desde cualquier función al array global sin necesidad de pasarlo siquiera como parámetro, por eso mismo se denomina global. Es una mala practica declarar variables/objetos globales dado que cualquier función puede modificar su contenido y por ende se hace mas difícil validar los datos u controlar los errores.




Por otro lado, el manejo de punteros es bastante amplio y dependiendo de como se utilicen depende el significado de la sentencia, no es lo mismo hacer esto:

Código (cpp) [Seleccionar]
cout<<*ptr<<endl;
ptr++;


que hacer esto:

Código (cpp) [Seleccionar]
cout<<ptr[i]<<endl; // == *(ptr+i);

Un ejemplo:


Para ordenar un array pasándolo como referencia a una función, te basta con seguir este pequeño bosquejo:


Código (cpp) [Seleccionar]
#include <iostream>
using namespace std;

void imprimir(int*); //Puede ser bool o int, dependiendo si queres retornar algun valor util para chequeo de errores

int main()
{
int array[]={1,2,3,4,5};

imprimir(array); // Pasaje por referencia automatico, el identificador del array es como si fuese un puntero

cin.get();
}

void imprimir(int *ptr)
{

for(int i=0;i<5;i++)
cout<<ptr[i]<<endl;
}


Añadiendo las funciones de ordenamiento y por supuesto del ingreso de datos. El proceso a seguir es similar.

Pero recomiendo que te bajes el libro que te mencione al principio, explica los punteros de manera bastante amigable y comprensible.

Saludos
An expert is a man who has made all the mistakes which can be made, in a very narrow field.

OnLOL

Bueno, lei lo que me dijeron, y con la mano de un amigo el programa funciona y esta mejorado, por supuesto le faltan cosas, como comprobar si hay valores repetidos, o si pongo un numero grande da cualquier cosa :P, Muchas gracias a ambos por ayudar ^.^ dejo el codigo.

Código (cpp) [Seleccionar]
#include <iostream>
using namespace std;



#define SIZE_ARRAY 10
void ordenarMeMa(int* array, int* arrayOrd);
void copiarArray(int* array, int* arrayCopia,  int size);
bool intercambio(int* array, int nroPasada);



int main() {
int a=0, *aux;
int array[SIZE_ARRAY], arrayOrd[SIZE_ARRAY];

for(a=0; a<10; a++) {  //obteniendo valores
cout << "ingrese el valor numero " << a << " de " << (sizeof(array)/sizeof(int))-1 << ": " << endl;
cin>>array[a];
}

aux = array;
cout<<" Vector desordenado: "<<endl;
for(a=0; a<10; a++) {//muestra el vector desordenado
//cout<<array[a]<<" | ";
if(a==0){cout <<"| ";}
cout << *aux <<" | ";
aux++;
}
cout << endl << endl;

ordenarMeMa(array, arrayOrd);
cout<<" Vector ordenado: "<<endl;
for(a=0; a<10; a++) {  // Muestra el array ordenado
if(a==0){cout <<"| ";}
cout << arrayOrd[a]<< " | ";
}
//cout<<endl;

cin>>a;

return 0;
}

/** Pre: Los arrays pasados por parámetros deben poseer el mismo tamaño
*/
void copiarArray(int* array, int* arrayCopia, int size) {
int i;

for(i=0; i< size; i++)
arrayCopia[i] = array[i];
}

void ordenarMeMa(int* array, int* arrayOrd) {
int i;
int nroPasada = 0;
bool ordenado=false;

copiarArray(array, arrayOrd, SIZE_ARRAY);

while(ordenado != true) {
for(i=0; i < SIZE_ARRAY-1; i++) {
ordenado = intercambio(arrayOrd,nroPasada);
nroPasada++;
}
}

}

bool intercambio(int* array, int nroPasada) {
int aux, i;

for(i=0; i< SIZE_ARRAY - nroPasada; i++) {
if( array[i] > array[i+1]) {
aux = array[i];
array[i] = array[i+1];
array[i+1] = aux;
}
}
if(i==0) return true;
else return false;
}


Saludos, y gracias :D