Consulta - Punteros

Iniciado por Cero++, 12 Diciembre 2018, 16:59 PM

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

Cero++

Buenas, otra vez yo! Necesito me aclaren esto, porque la verdad es que no entiendo para qué debería hacer la función que me están pidiendo, a ver si me pueden esclarecer un poco.
Consigna:
Código (cpp) [Seleccionar]
Escriba una funcion busca_mayor() que permita buscar el mayor elemento de un arreglo de structs segun diferentes criterios.
La funcion debe recibir como argumentos el arreglo de structs de tipo alumno, el tamanio del mismo, y un puntero a otra funcion que utilizara para comparar dos elementos de tipo alumno y saber cual es el mayor de ellos.
struct alumno {
char nombre[50];
int dni, edad, calificacion;
};
Implemente funciones que comparen dos alumnos segun su dni, segun su edad,
segun su calificacion, y segun su nombre alfabeticamente, y genere un programa cliente que permita ingresar los datos de N alumnos y buscar el mayor segun el
criterio que el usuario seleccione mediante un menu.


Esto fue lo que hice yo:  //No quiero que me hagan los ejercicios, solo que me ayuden en las dudas que tengo, así puedo terminar de comprenderlos, sino nunca voy a poder razonarlos si me los hacen
#include <iostream>
using namespace std;
struct alumno {
char nombre[50];
int dni, edad, calificacion;
};
alumno Busca_mayor(alumno a[], int size);
alumno Compara_nombre(alumno a[], int size);
alumno Compara_dni(alumno a[], int size);
alumno Compara_edad(alumno a[], int size);
alumno Compara_calificacion(alumno a[], int size);
int main(int argc, char *argv[]) {
alumno *A=nullptr; int size;
/*Carga del arreglo*/
....
....
/*Ejemplo de seleccion de funcion*/
switch(op){
case 1:
alumno aux=Compara_nombre(A,size);
cout<<"El mayor es: "<<aux.nombre; //Solo es un ejemplo...
case 2:
case 3:
case 4:
default:
}

return 0;
}
/*Como deberia usar esta funcion, no entiendo, si ya con las otras
funciones ya puedo obtener el mayor de los alumnos, cual es la funcion que cumple?*/
alumno Busca_mayor(alumno a[], int size, int *p){ //Como usaria el tercer argumento? no entiendo

}
alumno Compara_nombre(alumno a[], int size){
alumno aux;
for(int i=0;i<size;i++) {
if(a[i].nombre<a[i+1].nombre){
aux=a[i+1];
}
}
return aux;
}
alumno Compara_dni(alumno a[], int size){
alumno aux;
for(int i=0;i<size;i++) {
if(a[i].dni<a[i+1].dni){
aux=a[i+1];
}
}
return aux;
}
alumno Compara_edad(alumno a[], int size){
alumno aux;
for(int i=0;i<size;i++) {
if(a[i].edad<a[i+1].edad){
aux=a[i+1];
}
}
return aux;
}
alumno Compara_calificacion(alumno a[], int size){
alumno aux;
for(int i=0;i<size;i++) {
if(a[i].calificacion<a[i+1].calificacion){
aux=a[i+1];
}
}
return aux;
}
Ser diligente es lo ÚNICO que importa para lograr el éxito[c/ode]

MAFUS

El tercer argumento es un puntero a función por el cual le pasarás la función que realmente va a comparar.
Es cómo la función qsort, fíjate en ella.

La idea es: cada función que compara dos elementos por [lo que sea] devuelve:

  • un entero negativo si al_1 es menor a al_2
  • 0 si al_1 es igual a al_2
  • un entero positivo si al_1 es mayor a al_2

La firma de estas funciones auxiliares sería algo así:
int funcion(alumno *al_1, alumno *al_2);
Las funciones reciben punteros para no andar copiando estructuras enteras cada vez, por tanto dentro de la función tendrás que usar notación de punteros para acceder a los miembros.

La firma de tu función principal sería
alumno* Busca_mayor(alumno *base, size_t size, int (*comparar) (alumno *al_1, alumno *al_2))

Dentro de ella tendrás que buscar el mayor de tu array haciendo uso de la función de comparación para ir encontrado el mayor de los elementos comparados.

K-YreX

Cita de: MAFUS en 12 Diciembre 2018, 17:27 PM
La firma de estas funciones auxiliares sería algo así:
int funcion(alumno *al_1, alumno *al_2);
Las funciones reciben punteros para no andar copiando estructuras enteras cada vez, por tanto dentro de la función tendrás que usar notación de punteros para acceder a los miembros.

Otra alternativa, ya que el programa es en C++ y no en C es pasar los parámetros por referencia.
Código (cpp) [Seleccionar]

int funcion(const alumno &al_1, const alumno &al_2)

Personalmente prefiero usar está opción y evitas usar la notación de punteros. Te lo dejo como alternativa. :-X
Código (cpp) [Seleccionar]

cout << "Todos tenemos un defecto, un error en nuestro código" << endl;

Cero++

Estuve pensando desde ayer las respuestas que me dieron, pero, no entiendo, no importa, gracias de todos modos  ;D
Ser diligente es lo ÚNICO que importa para lograr el éxito[c/ode]

K-YreX

Si tienes que buscar el mayor de un array de enteros, es simple:
Código (cpp) [Seleccionar]

int BuscaMayor(int *array, int size){
    int mayor = array[0];
    for(int i = 1; i < size; i++)
        if(array[i] > mayor)
            mayor = array[i]
    return mayor;
}

Pero esto es porque para saber si un número es mayor que otro basta con el operador ">". Sin embargo cuando comparas estructuras tú decides que campo indica que objeto es mayor que otro. Entonces ya no sirve usar el operador ">", tienes que usar una función que haga lo mismo que ese operador, es decir, que de dos objetos te diga cual es mayor.
Imagina un stuct de persona, con nombre y edad:
Código (cpp) [Seleccionar]

struct Persona{
    string nombre;
    int edad;
    int dni;
};

Nosotros decidimos cuando una persona es mayor que otra, lo más lógico es con la edad, entonces hacemos una función que reciba dos personas y devuelva un entero positivo (1) si el primero es mayor, un entero negativo (-1) si el primero es menor y un 0 si son iguales...
Código (cpp) [Seleccionar]

int compararPorEdad(Persona p1, Persona p2){
    int comparacion = 0;
    if(p1.edad > p2.edad)
        comparacion = 1;
    else if(p1.edad < p2.edad)
        comparacion = -1;
    return comparacion;
}


Entonces ahora para buscar el mayor de un array de personas sería algo así:
Código (cpp) [Seleccionar]

Persona mayorPersona(Persona *personas, int size){
    Persona mayor = personas[0];
    for(int i = 1; i < size; i++)
        if(compararPersonas(personas[i], mayor) == 1)
            mayor = personas[i];
    return mayor;
}

Aquí en vez de usar el operador ">" hemos tenido que usar la función que hemos creado porque si usas el operador ">" con dos estructuras, el programa no sabe cual es mayor (a no ser que sobrecargues ese operador, que eso lo estudiarás más adelante).

Entonces si tienes más de un criterio de ordenación, por ejemplo quieres que el mayor sea e que tiene el DNI más alto. Entonces tendrías una función como <int compararPorEdad(Persona p1, Persona p2)> pero que será <int compararPorDni(Persona p1, Persona p2)>.

El objetivo es que puedas usar la función <Persona personaMayor(Persona *personas, int size)> con el criterio que quieras. Entonces ese criterio lo pasas como tercer parámetro, pasas la función que compara.
Código (cpp) [Seleccionar]

Persona personaMayor(Persona *personas, int size, int (*comparacion)(Persona p1, Persona p2));

Y usas la función <int comparacion(Persona p1, Persona p2)> para comparar cada dos personas del array. Suerte :-X
Código (cpp) [Seleccionar]

cout << "Todos tenemos un defecto, un error en nuestro código" << endl;

Cero++

Cita de: YreX-DwX en 13 Diciembre 2018, 20:51 PM
Y usas la función <int comparacion(Persona p1, Persona p2)> para comparar cada dos personas del array. Suerte :-X
Te soy sincero, no entiendo la aplicación, tengo una forma de hacerlo, pero no usaría ese maldito puntero  >:(
Hice esto, pero hasta ahí llegue con lo que me explicaste y llegue a entender, obviamente, no funciona
Código (cpp) [Seleccionar]
alumno Busca_mayor(alumno a[], int size, int (*p)(alumno a1, alumno a2)){
alumno aux;
for(int i=0;i<size;i++) {
if(*p(a[i],a[i+1])<0){
aux=a[i+1];
}else{
if(*p(a[i],a[i+1])>0){
aux=a[i];
}
}
}
return aux;
}
int Compara_nombre(alumno a1, alumno a2){
if(a1.nombre<a2.nombre){
return -1;
}else{
if(a1.nombre==a2.nombre){
return 0;
}
}
return 1;
}
Ser diligente es lo ÚNICO que importa para lograr el éxito[c/ode]

CalgaryCorpus

Cuando invoques la funcion usando el puntero p, elige una de estas 2 opciones, ambas deberian funcionar.

- Usa p sin *,  osea  p( parametros... )
- Desreferencia primero,      (*p)( parametros .. )
Aqui mi perfil en LinkedIn, invitame un cafe aqui