1

En el caso 2 intento imprimir las variables, pero me muestra valores erroneos intenté hacerlo en una función y pasaba lo mismo, con punteros y tampoco, el programa en la función ingresar hace todo bien intente imprimir desde ella y mostraba lo debido. El problema es al mostrar todo en otra función.

#include <iostream>
#include <math.h>
#include <windows.h>

using namespace std;
struct datos{
    int n;
    float m, b, sx, sy, sx2, sxy, X[20], Y[20];
};
typedef datos v;

void inicio();
void menu();
void ingresar_operaciones(struct datos d);
v mostrar(struct datos d);
int i;

int main() {
    int op;
    v D;
    inicio();
    do {
        menu();
        cin >> op;
        switch(op) {
            case 1:
                ingresar_operaciones(D);
            break;
            case 2:
                for(i = 0;i<D.n;i++) {
                    cout << D.X[i] << endl;
                    cout << D.Y[i] << endl;
                }
                cout << D.sx << endl;
                cout << D.sy << endl;
                cout << D.sx2 << endl;
                cout << D.sxy << endl;
                cout << D.m << endl;
                cout << D.b << endl;
            break;
            case 3:
                cout << "saliendo del programa" << endl;
                system("pause");
                return 0;
            default:
                cout << "opcion invalida" << endl;
            break;
        }
    } while(op! = 3);
}

void menu () {
    cout << "#1 ingresar" << endl;
    cout << "#2 mostrar" << endl;
    cout << "#3 salir" << endl;
}

void ingresar_operaciones(struct datos d) {
    float ms2, ms1, mi1, mi2, mbi, bs1, bs2;
    d.sx = 0,  d.sx2 = 0,  d.sxy = 0,  d.sy = 0;
    bool c = false;
    cout << "ingrese cantidad de datos" << endl;
    cin >> d.n;
    do {
        for(i = 0;i<d.n;i++) {
            cout << "ingrese el valor #" << i+1 << " de las X(variables independientes)"  << endl;
            cin >> d.X[i];
            cout << "ingrese el valor #" << i+1 << " de las Y(variables dependientes)" << endl;
            cin >> d.Y[i];
            d.sx = (d.sx+d.X[i]);
            d.sy = (d.sy+d.Y[i]);
            d.sx2 = (d.sx2+(pow(d.X[i], 2)));
            d.sxy = (d.sxy+(d.X[i]*d.Y[i]));
        }
        cout << "estan correctos los datos? S(1)/N(0)" << endl;
        cin >> c;
    } while(c =  = false);
    ms2 = (d.n*d.sxy);
    mi1 = (pow(d.sx, 2));
    mi2 = (d.n*d.sx2);
    mbi = (mi1-mi2);
    ms1 = (d.sx*d.sy);
    d.m = ((ms1-ms2)/mbi);
    bs1 = (d.sxy*d.sx);
    bs2 = (d.sy*d.sx2);
    d.b = ((bs1-bs2)/mbi);
    cout << d.m << endl;
    cout << d.b << endl;
    cout << "Y(x) = " << d.m << "x+" << d.b << endl;
    system("pause");
}

v mostrar(datos d) {
}

void inicio() {
    cout << "bienvenido" << endl;
}
meegle84
  • 343
  • 2
  • 17
Joni
  • 67
  • 6

2 Answers2

3

Antes de comentar el fallo que describes, quiero compartir contigo unos problemas que tiene tu código:

  • La cabecera <math.h> es de no de . Esta cabecera dispone de una versión adaptada a C++ que tiene el prefijo c y carece de extensión. Si realmente necesitas usar las cabeceras de C (que nunca será el caso) debes usar los equivalentes de C++ <cmath> . Lee este hilo para saber por qué.
  • No hay obligación de usar la cláusula using namespace std; pues es sólo es una ayuda a la escritura de código; si decides usar esta cláusula no lo hagas en el ámbito global, úsala en el ámbito más pequeño posible. Lee este hilo para saber por qué.
  • Tus variables no tienen nombres auto-explicativos: Los nombres de una sola letra como n, m, b, v, D, d, i, X o Y no explican nada del objetivo ni función de las variables, los nombres como como sx, sy, sx2, sxy, op, ms2, ms1, mi1, mi2, mbi, bs1, bs2 tampoco aportan información alguna. El nombre de una variable debería permitir saber de un vistazo su cometido, haciendo que el código sea menos propenso a errores y haciendo que sea más fácil de leer y entender, cosa que cualquier persona que trabaje contigo (incluso tu yo futuro) agradecerá mucho.
  • En C++ la palabra clave struct no forma parte del tipo, así pues no es necesaria para definir variables de tipo struct.
  • Deja que tu código respire: en los 90 teníamos pantallas de 80 caracteres de ancho y 25 líneas de alto (no había más remedio que compactar el código), pero hace décadas que no tenemos esas limitaciones, pon unos espacios en el código: hará que sea más fácil de leer y tu yo del futuro te lo agradecerá.

Ahora, el fallo que describes.


Como ya señala SJuan76, estás pasando por copia tus datos a la función ingresar_operaciones, por lo que se rellena una copia de datos la cuál, será inaccesible fuera de la función.

Dado que el tipo datos carece de constructor o inicializador, las variables miembro quedan sin inicializar y en consecuencia obtienen valores residuales; como tampoco modificas los valores en la función de ingresar_operaciones, verás los valores erróneos que describes.

Para solucionarlo te aconsejo lo siguiente:

Propuesta.

Añade inicializadores a tu estructura:

struct datos{
    int n = 0;
    float
        m = .0f,
        b = .0f,
        sx = .0f,
        sy = .0f,
        sx2 = .0f,
        sxy = .0f,
        X[20]{},
        Y[20]{};
};

Esto hará que todos los elementos de tu estructura estén a valor cero. También deberías pasar la estructura por referencia:

void ingresar_operaciones(datos &d) { // En C++ no necesitas 'struct'
    //         Referencia ----> ^

    // ...
}
PaperBirdMaster
  • 44,474
  • 6
  • 44
  • 82
2
void ingresar_operaciones(struct datos d);
v mostrar(struct datos d);

ingresar_operaciones(D);

Al llamar a estas funciones, dentro de la función trabajas con una copia de la variable que enviaste originalmente. Así que en ingresar_operaciones guardas datos en una copia que desaparece al salir del método, los datos de la variable original no se modifican.

Al menos en los métodos que quieras usar para modificar los datos de la variable original, tienes que hacer uno de estos cambios:

  • pasar un puntero. De esta forma lo que se copia es el puntero, pero el puntero copiado sigue apuntando a la misma variable original.

    void ingresar_operaciones(struct datos *d);
    ingresaro_operaciones(&D); // Le pasas la dirección de la variable local D.
    

    Naturalmente, tendrás que cambiar el código de ingresar_operaciones para que use -> en vez de ., porque ahora d es un puntero a una estructura y no una estructura.

  • devolver el valor resultante y escribirlo en la variable:

    struct datos ingresar_operaciones(struct datos d);
    

    y al finalizar ingresar_operaciones:

    return d;
    

    y lo invocas:

    D = ingresar_operaciones(D);
    
SJuan76
  • 10,771
  • 5
  • 17
  • 31