Crash en la consola

Iniciado por 7erran, 4 Abril 2021, 19:36 PM

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

7erran

Buenas tardes, estoy aprendiendo a usar funciones y lo que pasa es que necesito extraer datos de un for mientras este mismo se ejecuta, pero la solución que estoy dando al problema genera crash, ¿alguien podría ayudarme?, adjunto código, muchas gracias.


Código (cpp) [Seleccionar]
#include<iostream>
using namespace std;
/*• Promedio de edad de los estudiantes de Ingeniería.
• Porcentaje de hombres en la universidad.
• Porcentaje de mujeres que estudian Ingeniería.*/
int bucle(int x);
int PromEdadIng(int&, int&);

int estu, a, edad, sexo, carrera, edadtemp, edadconst, tempbucleedad, aux=0, tempbuclecarrera;

int main(){
int aretorno;
bucle(a);
cout<<"Favor ingresar el numero de estudiantes a tener en cuenta\n";
cin>>estu;

aretorno = (1-bucle(a))*-1;
cout<<aretorno;


}
int bucle(int a){
for(a=1; a<=estu; a++){
cout<<"Favor ingresar la edad del estudiante";
cin>>edad;
cout<<edad;
PromEdadIng(edad,aux);
cout<<"favor ingresar el sexo del estudiante, de la manera 1 si es masculino o 2 si es femenino";
cin>>sexo;
cout<<"Favor ingresar la carrera del estudiante, de la manera 1 si es ingenieria o 2 si es otra carrera";
cin>>carrera;
cout<<carrera;
PromEdadIng(aux,carrera);
}
return a;
}

int PromEdadIng(int& edad, int& carrera){
int promedad;
tempbuclecarrera=carrera;
cout<<tempbucleedad;
tempbucleedad+=edad;
cout<<tempbucleedad;
if(tempbuclecarrera=1){
promedad=tempbucleedad/a;
cout<<"El promedio de las edades de los estudiantes que estudian ingenieria es: "<<promedad;
}
else
return edad;
}



Crash:

Código (cpp) [Seleccionar]
cout<<"Que onda pa";

K-YreX

Bueno, vamos a ir viendo qué errores o mejoras hay en tu código...

  • No utilizar variables globales. Las variables globales, en contraposición con las variables locales, son las que se declaran fuera de cualquier función. Esto está desaconsejado. En todo caso se pueden utilizar para declarar constantes.

  • En la línea 11 llamas a la función bucle() pasando <a> (con valor 0) como argumento. Pasas un parámetro para ignorar su valor lo cual no debe hacerse y segundo que ese bucle no se va a ejecutar porque <estu> en ese punto vale 0 y <a> vale 1.

  • Después todo funciona normal hasta la línea 15. Aquí se llama de nuevo a bucle() y dentro de bucle() se llama a PromEdadIng() que tiene el error. Has definido que esa función devuelve un valor entero (int) pero en el caso de que se cumpla el if() no se devuelve nada.
    Si no se crea un bloque con llaves después de una estructura de control se entiende que únicamente la siguiente instrucción pertenece al bloque (no importa la indentación en C/C++).
Código (cpp) [Seleccionar]

// Esto:
if(condicion) cout << "Hola" << endl; cout << "Adios" << endl;
// es equivalente a esto:
if(condicion) {
  cout << "Hola" << endl;
}
cout << "Adios" << endl;

    En tu caso el <return edad> pertenece al bloque del else por lo que si se cumple la condición del if() no hay ningún return. Además la condición del if() va a ser siempre cierta. En C/C++ el operador '=' es el operador de asignación (asigna un valor a una variable) y si asignas a una variable cualquier valor distinto de 0, el resultado es true. El operador de comparación de igualdad es '=='.



Encontrado el error, a mejorar el código...
Primero, como ya he dicho, hay que evitar el uso de variables globales. Vamos a utilizar una constante para ver mejor su uso adecuado.
Código (cpp) [Seleccionar]

#include <iostream>
using namespace std;

const int MAX_ESTUDIANTES = 10; // Como maximo el programa admitira 10 estudiantes

int main() {
  int estudiantes; // variable local para el numero de estudiantes a introducir
  // Ahora pedimos el numero de estudiantes y debera estar entre 1 y el maximo que hayamos definido antes
  // Para ello se utiliza un filtro con un bucle do-while() que pedira un valor mientras el que se haya introducido no sea valido
  do {
    cout << "Introduce el numero de estudiantes [1 - " << MAX_ESTUDIANTES << "]: ";
    cin >> estudiantes;
  } while(estudiantes < 1 || estudiantes > MAX_ESTUDIANTES);
}


Ahora toca ver el resto de la funcionalidad. Primero voy a hacerlo todo en el main() sin utilizar más funciones y después utilizando funciones para ver el proceso. Según veo en el código, el propósito es mostrar la edad promedio de los estudiantes de ingeniería.
Código (cpp) [Seleccionar]

#include <iostream>
using namespace std;

const int MAX_ESTUDIANTES = 10; // Como maximo el programa admitira 10 estudiantes

int main() {
  int estudiantes; // variable local para el numero de estudiantes a introducir
  // Ahora pedimos el numero de estudiantes y debera estar entre 1 y el maximo que hayamos definido antes
  // Para ello se utiliza un filtro con un bucle do-while() que pedira un valor mientras el que se haya introducido no sea valido
  do {
    cout << "Introduce el numero de estudiantes [1 - " << MAX_ESTUDIANTES << "]: ";
    cin >> estudiantes;
  } while(estudiantes < 1 || estudiantes > MAX_ESTUDIANTES);

  int estudios;
  int edad, edadTotalIngenieria = 0; // Importante inicializar a 0 el acumulador
  for(int i = 0; i < estudiantes; ++i) { // Es mejor contar desde 0 para cuando avances mas en el lenguaje
    cout << "Introduce la edad del estudiante " << (i+1) << ": ";
    cin >> edad; // Guardamos la edad introducida en <edad>
    cout << "Introduce los estudios del estudiante " << (i+1) << "(1 - Ingenieria | 2 - Otro): ";
    cin >> estudios;
    if(estudios == 1) edadTotalIngenieria += edad; // Si es estudiante de ingenieria, sumamos su edad a la del resto de ingenieria
  }
  // Hay que convertir al menos una variable en double para que el resultado sea double y no int
  double edadPromedioIngenieria = (double)edadTotalIngenieria / estudiantes;
  cout << "La edad promedio de los estudiantes de ingenieria es: " << edadPromedioIngenieria << endl;
  return 0; // En la funcion main() no es necesario. En el resto de funciones que devuelven algo, el return es obligatorio
}


Ahora para crear una función hay que buscar un fragmento de código que forme como un bloque y que pueda ser utilizado varias veces preferiblemente. En este caso el mejor ejemplo que veo es el principio del programa. Hay un fragmento de código para pedir un valor entre dos límites y repetirse hasta que se introduce un valor válido.
Es una buena práctica que las funciones tengan verbos en su nombre para indicar lo que hacen. Por ejemplo se puede llamar pedirEstudiantesEnRango()
Código (cpp) [Seleccionar]

int pedirEstudiantesEnRango() {
  int estudiantes;
  do {
    cout << "Introduce el numero de estudiantes [1 - " << MAX_ESTUDIANTES << "]: ";
    cin >> estudiantes;
  } while(estudiantes < 1 || estudiantes > MAX_ESTUDIANTES);
  return estudiantes; // Importante devolver el valor
}

int main() {
  int estudiantes = pedirEstudiantesEnRango();
  // el resto del programa
}

En la función anterior podemos usar MAX_ESTUDIANTES sin pasarlo como argumento porque es una constante global. Sin embargo, ¿qué pasaría si en algún momento del programa queremos pedir un número de estudiantes en otro rango? Habría que cambiar todo el programa. Entonces podemos agregar parámetros para indicar el mínimo y el máximo.
Código (cpp) [Seleccionar]

int pedirEstudiantesEnRango(int minimo, int maximo) {
  int estudiantes;
  do {
    cout << "Introduce el numero de estudiantes [" << minimo " - " << maximo << "]: ";
    cin >> estudiantes;
  } while(estudiantes < minimo || estudiantes > maximo);
  return estudiantes; // Importante devolver el valor
}

int main() {
  int estudiantes = pedirEstudiantesEnRango(1, MAX_ESTUDIANTES);
  // el resto del programa
}

Como se ve en el código anterior, si se utilizan parámetros es para pasar valores necesarios de una función a otra.

A partir de todo esto ya te toca seguir a ti y siempre puedes preguntar de nuevo si tienes algún problema o alguna duda.
Suerte.  :-X


PD: Las dos siguientes líneas son iguales con la diferencia de que la primera se entiende mejor que la segunda...
Además, si cuentas el bucle for() desde 0, no hace falta ni restar 1. ;) ;)
Código (cpp) [Seleccionar]

int retorno = f() - 1;
int retorno = (1 - f()) * -1;
Código (cpp) [Seleccionar]

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

7erran

#2
Luego de unas horas dando vueltas e intentando aplicar diferentes cosas, llegue a esta solución que no se si sea la mas larga o si se pueda comprimir más el código pero, es la solución que hice y entendí, claramente con ayuda de las personas de este foro, en especial a el usuario @K-YreX y a @XSStringManolo, así que finalmente adjunto el código que funciona y creo que es una solución valida, muchas gracias por su tiempo.

Código (cpp) [Seleccionar]

#include<iostream>
using namespace std;

int PedirEstudiantesEnRango();

const int MAX_ESTUDIANTES = 10;
int estudiantes, TotalHombresUniversidad, MujerEstudiaIng;
double edadPromedioIngenieria;

int main(){
do{
cout<<"Favor ingresar el numero de estudiantes dentro del rango estipulado: [1 - " << MAX_ESTUDIANTES << "]: ";
cin>>estudiantes;
}while(estudiantes < 1 || estudiantes > MAX_ESTUDIANTES);

PedirEstudiantesEnRango();

cout << "La edad promedio de los estudiantes de ingenieria es: "<< edadPromedioIngenieria<<"\n";
cout << "El porcentaje de hombres que hay en la universidad es: "<<TotalHombresUniversidad<<"%\n";
cout << "El porcentaje de mujeres que hay en la universidad estudiando ingenieria es: "<<MujerEstudiaIng<<"%\n";

}

int PedirEstudiantesEnRango(){
bool EsMujer;
int edad, sexo, TotalMujeres, edadTotalIngenieria = 0, estudios;
for(int i = 0; i < estudiantes; ++i) {
EsMujer==false;
   cout << "Introduce la edad del estudiante " << (i+1) << ": ";
   cin >> edad;
   cout << "Introduzca el sexo del estudiante " << (i+1) << " (1 - Masculino | 2 - Femenino): ";
   cin >> sexo;
   if(sexo==1){
    TotalHombresUniversidad+=sexo;
}
else if(sexo==2){
EsMujer=true;
TotalMujeres++;
}
   cout << "Introduzca la carrera del estudiante " << (i+1) << " (1 - Ingenieria | 2 - Otro): ";
   cin >> estudios;
   if(estudios==1){
edadTotalIngenieria+=edad;
}
if(estudios==1&&EsMujer==true){
MujerEstudiaIng++;
}
}
TotalHombresUniversidad=(TotalHombresUniversidad*100)/estudiantes;
MujerEstudiaIng=(MujerEstudiaIng*100)/estudiantes;
edadPromedioIngenieria = (double)edadTotalIngenieria / estudiantes;
return edadPromedioIngenieria, TotalHombresUniversidad, MujerEstudiaIng;
}
Código (cpp) [Seleccionar]
cout<<"Que onda pa";

@XSStringManolo

Te ha quedado un poco caótico, con muchísimas variables innecesarias emy algunas expresiones que puedes eliminar y no pasa nada.

Lineas 6, 7 y 8 deberían ir dentro de main. El motivo es que si declaras las variables globales, estas van a poder ser accesibles por librerías de otros programadores que incluyas en tu código, tus propias funciones que no deberían de poder acceder a ellas, se malgasta memoria al estar siempre accesibles hasta que se acabe el programa, etc. Usa solo globales cuando sea imprescindible.

Linea 11 y demás; deberías de identar (dar espacios antes de la palabra) dentro de cada cuerpo de función, bucle, condicional, etc. Es recomendable dar entre 2 y 4 (ambos incluidos) espacios. A tu gusto pero el número que eligas úsalo de forma consistente en todo el código del programa. Dar espacios facilita la interpretación del código a simple vista, mejora la lectura y es más sencillo detectar errores como la falta de un corchete.

En tu función int PedirEstudiantesEnRango(), retornas números, pero en ningún moemento haces nada de nada con el valor que se retorna. Si quieres una función que haga algo pero que no retorne nada, entonces declárala como void en lugar de int y te ahorras la linea de return. Lo lógico cuando usas funciones, es que hagan tareas más concretas y especializadas, y no funciones que hagan todo.

En lugar de usar globales dentro de la función PedirEstudianteEnRango, lo correcto es declarar las variables dentro de main y enviárselas como argumento de la llamada a la función. Y en la propia funcion las pones como parámetros. Ejemplo de lo que haces:
Código (cpp) [Seleccionar]
int numero1, numero2;

int sumar();

int main(){
numero1 = 30;
numero2 = 40;
sumar();
return 0;
}

int sumar(){
int resultado=numero1+numero2;
cout<<"El resultado es: "<<resultado;
return resultado;
}


Ejemplo de lo que deberías hacer:
Código (cpp) [Seleccionar]
int sumar(int num1, int num2);

int main() {
  int numero1 = 30;
  int numero2 = 40;

  cout << "El resultado es: " << sumar(30, 40);
}

int sumar(int num1, int num2) {
  return num1 + num2;
}


La linea 28 no hace nada. Tu compilador debería de lanzarte un warning avisándote de que eso ahí no se está usando para nada.

En las linea 29 y 31 los paréntesis en (i+1) no hacen nada, es como no ponerlos.

En la linea 51 tienes que convertir a doble ambos valores primero antes de dividirlos para que no trunque los decimales. Tal como lo tienes si divides 3 / 2 te da 1 en lugar de 1.5


Te dejo como lo haría yo por si te sirve de orientación para mejorar tu versión del programa conjuntamente con los consejos que te dejo y los que te ha dejado K-YreX. Repasa sus consejos y trata de entenderlos todos.



Código (cpp) [Seleccionar]
#include <iostream>
#include <string>
#include <vector>

using namespace std;

struct Estudiante {
  int edad;
  string sexo;
  string carrera;
};

int promedioEdadEstudiantesIngenieria( vector<Estudiante> &listado );
int porcentajeHombresUniversitarios( vector<Estudiante> &listado );
int porcentajeMujeresEstudianIngenieria( vector<Estudiante> &listado );

int main() {
  int numeroEstudiantes = 0;
  cout << "Cuantos estudiantes vas a introducir?" << endl;
  cin >> numeroEstudiantes;

  vector<Estudiante> listadoEstudiantes;

  for (int i = 0; i < numeroEstudiantes; ++i) {
    Estudiante estudiante;
    cout << "Edad del estudiante?" << endl;
    cin >> estudiante.edad;

    cout << "Sexo del estudiante?" << endl;
    cin >> estudiante.sexo;

    cout << "Carrera que cursa el estudiante?" << endl;
    cin >> estudiante.carrera;

    listadoEstudiantes.push_back(estudiante);
  }

  cout << "Promedio de edad de los estudiantes de ingenieria: " << promedioEdadEstudiantesIngenieria(listadoEstudiantes) << endl;
  cout << "Porcentaje de universitarios masculinos: " << porcentajeHombresUniversitarios(listadoEstudiantes) << "%" << endl;
  cout << "El " << porcentajeMujeresEstudianIngenieria(listadoEstudiantes) << "% de las mujeres universitarias estudian ingenieria" << endl;

  return 0;
}


int promedioEdadEstudiantesIngenieria( vector<Estudiante> &listado ) {
  int promedio = 0;
  int numeroDeEstudiantesIngenieria = 0;
  for (int i = 0; i < listado.size(); ++i) {
    if (listado[i].carrera == "Ingenieria" || listado[i].carrera == "ingenieria") {
      promedio += listado[i].edad;
      ++numeroDeEstudiantesIngenieria;
    }
  }
  return promedio / numeroDeEstudiantesIngenieria;
}


int porcentajeHombresUniversitarios( vector<Estudiante> &listado ) {
  int numeroHombres = 0;;
  for (int i = 0; i < listado.size(); ++i) {
    if (listado[i].sexo == "Hombre" || listado[i].sexo == "hombre") {
      ++numeroHombres;
    }
  }
  return 100 / listado.size() * numeroHombres;
}


int porcentajeMujeresEstudianIngenieria( vector<Estudiante> &listado ) {
  int numeroMujeresEnTodasCarreras = 0,
  numeroMujeresEstudianIngenieria = 0;
  for (int i = 0; i < listado.size(); ++i) {
    if (listado[i].sexo == "Mujer" || listado[i].sexo == "mujer") {
      ++numeroMujeresEnTodasCarreras;
      if (listado[i].carrera == "Ingenieria" || listado[i].carrera == "ingenieria") {
        ++numeroMujeresEstudianIngenieria;
      }
    }
  }
  return 100 / numeroMujeresEnTodasCarreras * numeroMujeresEstudianIngenieria;
}