Ayuda con ciclo for C++

Iniciado por andrex.125, 10 Mayo 2013, 02:53 AM

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

andrex.125

Buenas noches,  estoy haciendo un trabajo de la universidad es un programa sencillo, el programa tiene que calcular el producto escalar de dos vectores, los vectores son de tamaño n, el usuario digita el tamaño, tengo un método con un ciclo for que recorre el vector y llena los espacios, pero aquí me encuentro con un problema y es que si por ejemplo el usuario digita 2, el programa debería dejarme digitar 2 veces el valor del vector para cada espacio, pero solo me deja digitar 1 vez. quisiera que me ayudaran por que no se cual es mi error. Gracias.

Escalar.h
class Escalar
{
private:
double vectorV[];
double vectorW[];
int S;

public:
        Escalar();
Escalar(int s);
~Escalar();
void setS(int s);
int getS();
double llenarvectores();
double CalcularEscalar();

};


Escalar.cpp

using namespace std;
Escalar::Escalar()
{

}
Escalar::Escalar(int s)
{
    S=s;
vectorV[S];
vectorW[S];

}
int Escalar::getS()
{
return S;
}
void Escalar::setS(int s)
{
S = s;
}

double Escalar::llenarvectores()
{

for(int i=0;i<S;i++)
{
cout<< "digite el valor del vector V en la posicion " <<i <<" : ";
cin>>vectorV[i];
cout<< "digite el valor del vector W en la posicion " <<i <<" : ";
cin>>vectorW[i];

}
}
double Escalar::CalcularEscalar()
{
   
double multi = 0.0;
for(int i=0; i <S; i++)
{
multi = multi+vectorV[i]*vectorW[i];

}
cout<<multi;

}
Escalar::~Escalar()
{
}


main.cpp

using namespace std;
int main()
{
cout<<"Digite el tamaño de los vectores: ";
int s;
cin>>s;
Escalar Z(s);
Z.llenarvectores();
Z.CalcularEscalar();
cout<<endl;

}

ThePinkPanther

#1
Escalar::Escalar(int s)
{
   S=s;
vectorV[S];
vectorW[S];

}


No puedes realizar este tipo de cosas..

Si quieres usar arrays de forma dinamica dimensionados por el usuario ,deberas utilizar asignación dinamica de memoria, en c++ , tienes el operador new , y delete para asignar y liberar respectivamente, y en C tienes las funciones malloc,calloc, realloc y free .


tu clase modificada mas o menos quedaría..


class Escalar
{
private:
double *vectorV;
double *vectorW;
int S;

public:
       Escalar();
Escalar(int s);
~Escalar();
void setS(int s);
int getS();
double llenarvectores();
double CalcularEscalar();

};


Fijate, la declaración de vectorV y vectorW

Equitativamente, tu constructor va a iniciar tus punteros reservando memoria según la cantidad de datos que el usuario pidio..

Escalar::Escalar(int s)
{
   S=s;
vectorV=new double[s];
vectorW=new double[s];


}


Y por ultimo,no estoy muy familiarizado con la poo , pero creería que tu destructor , tendría que borrar la memoria reservada , antes que se termine el ámbito de los punteros
.

Esto se hace con delete vectorV[];  ( ejemplo borrando memoria reservada para vectorV )



Saludos , espero a ver sido claro y a verte ayudado .

andrex.125

Cita de: ThePinkPanther en 10 Mayo 2013, 03:39 AM
Escalar::Escalar(int s)
{
   S=s;
vectorV[S];
vectorW[S];

}


No puedes realizar este tipo de cosas..

Si quieres usar arrays de forma dinamica dimensionados por el usuario ,deberas utilizar asignación dinamica de memoria, en c++ , tienes el operador new , y delete para asignar y liberar respectivamente, y en C tienes las funciones malloc,calloc, realloc y free .


tu clase modificada mas o menos quedaría..


class Escalar
{
private:
double *vectorV;
double *vectorW;
int S;

public:
       Escalar();
Escalar(int s);
~Escalar();
void setS(int s);
int getS();
double llenarvectores();
double CalcularEscalar();

};


Fijate, la declaración de vectorV y vectorW

Equitativamente, tu constructor va a iniciar tus punteros reservando memoria según la cantidad de datos que el usuario pidio..

Escalar::Escalar(int s)
{
   S=s;
vectorV=new double[s];
vectorW=new double[s];


}


Y por ultimo,no estoy muy familiarizado con la poo , pero creería que tu destructor , tendría que borrar la memoria reservada , antes que se termine el ámbito de los punteros
.

Esto se hace con delete vectorV[];  ( ejemplo borrando memoria reservada para vectorV )



Saludos , espero a ver sido claro y a verte ayudado .

Muchas gracias, me sirvió mucho tu ayuda.
pero tengo una duda, mi compilador es dev C++, y estoy programando en C++, la profesora  nos dio un ejemplo para guiarnos, en ese ejemplo esta de la forma que escribí mi código, la diferencia es que a la profesora le corre el programa.
mira este es el ejemplo con que me base para hacer el mio.

class Calificacion
{
  private: 
  int codCurso;
  int cantidadEst;
  double notas[];

  public:   
    Calificacion();
    Calificacion(int cod, int cant);
    ~Calificacion();
     void setCurso(int c);
     int getCurso();
     void setCantidadEst(int est);
     int getCantidadEst();
     void llenarNotas();
     void mostrarNotas();
     double promedioNotas();
     double notaMayor();
   
   
};

#include "Calificacion.h"
#include <iostream>
using namespace std; 



Calificacion::Calificacion()
{
}

Calificacion::Calificacion(int cod, int cant)
{
     codCurso=cod;
     cantidadEst=cant;
     notas[cantidadEst];
}

void Calificacion::setCantidadEst(int est)
{
  cantidadEst=est;

  }
 
  int Calificacion::getCurso()
  {
      return codCurso;
  }
 
  int Calificacion::getCantidadEst()
  {
      return cantidadEst;
  }

void Calificacion::llenarNotas()
{
    for (int i=0;i<cantidadEst; i++)
      {
       cout<<" ingrese la nota["<<i<<"]\t";
       cin>>notas[i];
       cout<<endl;
      }
}

double Calificacion::notaMayor()
{
     double mayor=notas[0]; //para empezar se inicializa mayor con primer elemento del arreglo
      for (int i=1;i<cantidadEst; i++)
      {
         if (notas[i]>mayor)
            mayor=notas[i];
      }     
     return mayor;   
}

void Calificacion::mostrarNotas()
{
    cout<<"Las notas ingresadas son: "<<endl;
    for (int i=0;i<cantidadEst; i++)
      {
       cout<<"nota["<<i<<"]="<<notas[i];
       cout<<endl;
      }
}

Calificacion::~Calificacion()
{
}

void Calificacion::setCurso(int c)
{
  codCurso = c;
}

double Calificacion::promedioNotas()
{
     double prom=0.0;
   
    for (int i=0;i<cantidadEst; i++)
      {
       prom=prom+notas[i];
      }
     prom=prom/cantidadEst;
     
     
      return prom;
}

#include "Calificacion.h"
#include <iostream>
using namespace std; 

int main()
{
    int cant, cod;
     
   
    cout<<"Cual es el codigo del curso? ";
    cin>>cod;
    cout<<"Cuantas notas va a ingresar? ";
    cin>>cant;
    Calificacion cal(cod,cant);
    cal.llenarNotas();
    cal.mostrarNotas();
    cout<<"el promedio de las notas del curso "<<cal.getCurso()<<" es "<<cal.promedioNotas()<<endl;
    cout<<"La nota mayor es "<<cal.notaMayor()<<endl;
           
   
   system("PAUSE"); //Para que espere a que el usuario digite una tecla
   return EXIT_SUCCESS;
   
 
}

ThePinkPanther

#3
Si la profesora te dio eso no tengo idea entonces, hasta donde tengo entendido , si queremos generar un arreglo de x elementos ingresados por el usuario , deberemos reservar memoria , y guardar la dirección de memoria de la primera posición de memoria donde empieza la memoria dinámica..

esto se consigue , con el operador new , en c++ , por ejemplo :

int a;
int *arreglo;
cin>>a;
arreglo=new int [a]; // donde a es la cantidad de elementos que va a formar el arreglo.

A lo que voy, es que no se puede dimensionar un vector en tiempo de ejecución al menos, que utilicemos asignación dinámica de memoria.
O por lo menos es lo que tengo entendido.


O yo estoy re loco y no veo algo, o tu profesora esta re loca y yo estoy cuerdo.

andrex.125

ThePinkPanther

muchas gracias por la ayuda, ya comprendí un poco del operador new.
con respecto al ejemplo de la profesora ya me tocaría resolverlo con ella.

Muchas gracias.


ThePinkPanther

Cita de: andrex.125 en 10 Mayo 2013, 04:35 AM
ThePinkPanther

muchas gracias por la ayuda, ya comprendí un poco del operador new.
con respecto al ejemplo de la profesora ya me tocaría resolverlo con ella.

Muchas gracias.



De nada, puedes buscar en google, encuentras mucha referencia de como usar memoria dinámica, si haceme el favor,consúltale ese tema, y mándame un pm con lo que te respondio porque me sorprende. un saludo.

leosansan

#6
Tienes que inicializar la dimensión de los vectores a algún valor igual o superior al que vayas a utilizar, por ejemplo:

Código (cpp) [Seleccionar]
class Escalar
{
private:
double vectorV[10];
double vectorW[10];
int S;


Ya luego le das la dimensión correcta, por ejemplo tres y a mí me sale esto:

Código (cpp) [Seleccionar]
Digite el tama±o de los vectores: 3
S= 3
digite el valor del vector V en la posicion 0 : 1
digite el valor del vector W en la posicion 0 : 0
digite el valor del vector V en la posicion 1 : 1
digite el valor del vector W en la posicion 1 : 2
digite el valor del vector V en la posicion 2 : 2
digite el valor del vector W en la posicion 2 : 3
8


Saluditos!. ...  

ThePinkPanther

Tal cual, o dimensionas los vectores de entrada como explica leo , o usas asignación de memoria, en este caso recomiendo asignación dinámica de memoria porque a priori no se sabe cuando datos va a ingresar el usuario al arreglo, y tampoco da para sobre-dimensionar el vector y no usar toda la memoria.

Me parece que si , se confundió tu profe.xD

leosansan

#8
Cita de: ThePinkPanther en 10 Mayo 2013, 08:57 AM
Tal cual, o dimensionas los vectores de entrada como explica leo , o usas asignación de memoria, en este caso recomiendo asignación dinámica de memoria porque a priori no se sabe cuando datos va a ingresar el usuario al arreglo, y tampoco da para sobre-dimensionar el vector y no usar toda la memoria.

Me parece que si , se confundió tu profe.xD

Sí y no. Como indica andrex.125 el código de la profe va bien, sin dimensionar ni asignar memoria dinámica. ¿Por qué en el de ella sí y en el tuyo no?.. Pues por un simple cambio en los datos. Si pones:

Código (cpp) [Seleccionar]
class Escalar
{
private:
int S;
double vectorV[];
               double vectorW[];


fíjate que "int S" va antes de los double, podrás entrar todas las componentes de los vectores, tal como pudo hacer tu profe con la entrada de notas.

...Pero....sí, hay un pero . Ella sólo manejaba un array y tú dos. Y ocurre lo que ocurre, como no se ha "reservado" direcciones de memoria para cada uno, resulta que entras los datos de V, bien, entras los datos de W y "fatal", estos últimos sobrescriben los datos de V -al no haber hecho reserva de memoria el programa usa las mismas para ambos y los segundos datos de W sobrescriben los de V- y el resultado que obtienes es el producto escalar de W por W ¡ ¡ ¡ ¡, eso en el mejor de los casos, haz la prueba con el cambio de orden que te indique más arriba, te dejo una salida:

Código (cpp) [Seleccionar]
Digite el tama±o de los vectores: 3
digite el valor del vector V en la posicion 1 : 0
digite el valor del vector V en la posicion 2 : 0
digite el valor del vector V en la posicion 3 : 0
digite el valor del vector W en la posicion 1 : 1
digite el valor del vector W en la posicion 2 : 2
digite el valor del vector W en la posicion 3 : 3

1 : 1
2 : 4
3 : 9
14


Conclusión: o predimensionas como te indiqué yo o mejor aún asiganción dinámica de memoria como te indicó ThePinkPanther

De todas formas hay "detallitos" que "cantan" en cuanto al manejo del lenguaje, al menos para mí esto de tu profe:


Código (cpp) [Seleccionar]
prom=prom+notas[i];
     }
    prom=prom/cantidadEst;


hace que me  duelan los ojos, mejor visto estaría:

Código (cpp) [Seleccionar]
prom+=notas[i];
     }
    prom/=cantidadEst;


aunque reconozco que puede resultar que a otros les guste más la forma de tu profe..........

Saluditos!. .....  

Wofo

Si te interesa lo de los vectores dinámicos seguro que querrás revisar la clase "vector" que trae C++ (si buscas en Google encontrarás muchísimos recursos y ejemplos). Es impresionante lo mucho que simplifica las cosas y lo fácil de usar.

Siempre está la alternativa de hacerlo "a mano" usando el operador new, pero no vale la pena estar reinventando la rueda cada vez.

Espero que te sirva,
Wofo.