Dudas varias

Iniciado por Alien-Z, 18 Agosto 2011, 00:56 AM

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

Alien-Z

Buenas:

Después de varios días siguiendo los video-tutoriales de Jesus Conde y apoyándome en algunos libros que encontré, he llegado al final de las clases y objetos (o al menos por ahora se pasa a otro tema). Asi pues aqui comento las dudas que me han quedado:

1- En algunas guías añaden el siguiente código después de llamar a las librerías:

using namespace std;

Mientras que en otras pone lo siguiente dentro de main:

using std::cout;
using std::cin;
usgin std::endl;


¿Para qué es este código?, podría suponer que es para que funcione "cout, cin y endl", sin embargo eso va dentro de la librería "iostream", ¿entonces qué hace este código exactamente?.

2- En este ejemplo:

#include <iostream>
int myFunc(unsigned short int x);
int main()
{
   unsigned short int x, y;
   x = 7;
   y = myFunc(x);
   std::cout << "x: " << x << " y: " << y << "\n";
   return 0;
}

int myFunc(unsigned short int x)
{
   return (4*x);
}


Es obligatorio mandarle un valor a "unsigned short int x" desde:

Citary = myFunc(x);

Sé que este valor se puede modificar dentro de la función, ¿pero no hay ninguna forma de dejarlo vacio, es decir, no inicializarlo?.

3- He dado la herramienta "inline", sin embargo, ¿cuántas líneas como máximo puede tener una función para que el usar inline sea efectivo?, ya que según he leído llegado a un punto degrada el programa.

4- ¿El siguiente prototipo de función es considerado como inline por el compilador (como en el caso de las clases) o hay que añadirle la palabra "inline"?, mi duda surje debido a que se define la función en el prototipo:

Citar#include <iostream>
using namespace std;

int funcion1 (int numero) { return numero * 5; }

int main ()

{
int x;
x = funcion1 (5);
cout << "Prueba.";

return 0;
}

5- Entre los ejercicios de un libro escrito por Pello Xabier Altadill Izura encontré este:

#include <iostream>
using namespace std;

int main ()
{
// Sacamos el tamaño de cada tipo
cout << "El tamaño del int es:\t\t" << sizeof(int) << " bytes.\n";
cout << "El tamaño del short es:\t" << sizeof(short int) << " bytes.\n";
cout << "El tamaño del long es:\t" << sizeof(long int) << " bytes.\n";
cout << "El tamaño del char es:\t\t" << sizeof(char) << " bytes.\n";
cout << "El tamaño del float es:\t\t" << sizeof(float) << " bytes.\n";
cout << "El tamaño del double es:\t" << sizeof(double) << " bytes.\n";
// Sacamos por salida standar un mensaje
cout << "Termino el programa\n";
return 0;
}


Me ha extrañado un poco el ver que el tamaño de "int," el de "long int" y el de "float" es de 4 bytes, si ocupan lo mismo ¿por qué uno puede almacenar números más altos que otro?.

6- Cuando creamos una clase declaramos algunas variables y funciones miembro como públicas y otras como privadas. Luego están las funciones "accessor", que sirven para poder acceder a un miembro privado atraves de uno público, hasta ahi lo entiendo. ¿Pero qué necesidad hay de declarar una variable o función como privada y luego manejarla através de una función accessor?, ¿qué problema puede haber con declararlo todo público (o al menos lo que sabes que vas a usar fuera de la clase)?.

|----------------------------------------------------------------------------------------------------------------------------|

Creo que eso es todo, aunque hay demasiadas preguntas... :-\ las he ido acumulando para hacer un pack de dudas y no crear 9392 temas :xD

Saludos!

Valkyr

1. Un espacio de nombres (namespace) es un mecanismo para agrupar un conjunto de elementos (clases, enumerados, funciones, etc.) relacionados. Evita la colisión de los nombres de identificadores. El orden de declaración de elementos es relevante. Puede estar definido en varios ficheros.

cout, cin y demás están en dicho espacio de nombres y por tanto debes hacer uso de el para no tener que especificar en que espacio de nombres se encuentran.

2. No entiendo qué quieres decir.

3. Supongo que no habrá un número concreto de líneas, dependerá del número de veces que realices llamadas a dicha función principalmente. Por ejemplo, sí llamas a la función 100 veces durante el código, y dicha función tiene 400 líneas de código, sería una burrada (y he puesto un ejemplo con cantidades pequeñas, imaginate con cantidades mayores).

4. No estoy seguro, pero creo que no. Para que sea considerado inline debe especificarse explicitamente.

5. No tienen el mismo tamaño.

int: 4 bytes
long int: 8 bytes
short int: 2 bytes
char: 1 byte
float: 4 bytes
double: 8 bytes

6. Te respondo desde lo que he estudiado en Java de programación orientada a objetos.

Todos los atributos de una clase deben declararse como privados para respetar el principio de ocultación:

Principio: la estructura de datos está sujeta a más variaciones que las operaciones. Los atributos se ocultan aplicando visibilidad privada. Los métodos pueden ofrecerse con distintos niveles de visibilidad.

De esta forma aislamos al cliente de los cambios en la estructura de datos ya que hemos declarado los métodos para acceder a estos atributos y los métodos para modificar estos atributos.

Espero haber solucionado en gran parte tus dudas.

Saludos.


PiroskY

Cita de: Con ClaseLas variables enteras almacenan números enteros dentro de los límites de cada uno de sus tamaños. A su vez, esos tamaños dependen de la plataforma, del compilador, y del número de bits que use por palabra de memoria: 8, 16, 32... No hay reglas fijas para saber el tamaño, y por lo tanto, el mayor número que podemos almacenar en cada tipo entero: short int, int o long int; depende en gran medida del compilador y del sistema operativo. Sólo podemos estar seguros de que el tamaño de un short int es menor o igual que el de un int, y éste a su vez es menor o igual que el de un long int.

El resto de las preguntas, coincido con valkyr.

Alien-Z

#3
Muchas gracias a los dos, ya lo veo más claro. Si no lo he entendido mal el namespace sirve para que el compilador no "confunda" un elemento propio de C++ (cout, cin, endl, etc.) con una variables que nosotros declaremos ¿cierto?.

Y sobre el punto 6, los atributos de una clase se ocultan para evitar modificaciones inesperadas por parte del cliente. Si es asi entonces lo he comprendido todo correctamente.

Con respecto al punto 2, a ver si con este ejemplo me explico mejor:

Citar# include <iostream>
using namespace std;

int Funoperacion (short int x, short int y, int operacion);

int main ()
{
   int x, y, resultado;
   cout << "Escribe un numero: ";
   cin >> x;
   cout << "\nEscribe otro numero: ";
   cin >> y;
   
   resultado = Funoperacion (x, y);
   cout << "\nEste es el resultado: " << resultado << endl;
   
   return 0;
}

int Funoperacion (short int x, short int y, int operacion)
{
   operacion = x*y;
   return operacion;
}

Lo primero que he marcado en rojo es el prototipo de la función y como vemos dentro declaro 3 variables (short int x, short int y, int operacion). A continuación a las dos primeras variables les asigno un valor dentro de main (línea en rojo Nº2), sin embargo yo no quiero darle un valor a la tercera variable en main, sino en la definición de la función (línea en rojo Nº3).

Esto se le conoce como "no-inicializar una variable" según las guías que he consultado, pero no he encontrado la forma de hacerlo con una función, si no le asigno un valor a "int operacion" dentro de main, me salta error.

Espero haberme explicado bien. Gracias de nuevo, saludos.

Valkyr

Cita de: Alien-Z en 18 Agosto 2011, 14:30 PM
Lo primero que he marcado en rojo es el prototipo de la función y como vemos dentro declaro 3 variables (short int x, short int y, int operacion). A continuación a las dos primeras variables les asigno un valor dentro de main (línea en rojo Nº2), sin embargo yo no quiero darle un valor a la tercera variable en main, sino en la definición de la función (línea en rojo Nº3).

Esto se le conoce como "no-inicializar una variable" según las guías que he consultado, pero no he encontrado la forma de hacerlo con una función, si no le asigno un valor a "int operacion" dentro de main, me salta error.

Espero haberme explicado bien. Gracias de nuevo, saludos.

A ver si te he entendido.

Tú lo que quieres es darle un valor a la variable resultado dentro de una función, y que el compilador no lo tome como error. ¿Es a eso a lo que te refieres?.

Sí pruebas este código verás que te da error un Warning porque estás usando la variable sin inicializarla:

Código (cpp) [Seleccionar]

#include<iostream>
using namespace std;

int funcion(int var1, int var2, int operacion);

int main(void){
int x, y, resultado;
cin>>x>>y;
resultado = funcion(x, y, resultado);
cout<<resultado;
}

int funcion(int var1, int var2, int operacion){
operacion = var1*var2;
return operacion;
}


Y es lógico que lo de, porque aunque tú en la función estás asignandole un valor, el paso que estás haciendo del parametro es por valor (es decir, se realiza una copia) y por tanto, los cambios que realices dentro de la función, no tendrán efecto fuera de ella.

Sin embargo, si en lugar de hacerlo así, lo haces de esta manera:

Código (cpp) [Seleccionar]

#include<iostream>
using namespace std;

int funcion(int var1, int var2, int &operacion);

int main(void){
int x, y, resultado;
cin>>x>>y;
resultado = funcion(x, y, resultado);
cout<<resultado;
}

int funcion(int var1, int var2, int &operacion){
operacion = var1*var2;
return operacion;
}


Entonces el compilador ya no te mostrará el Warning que sí lo hacía antes puesto que estás inicializando la variable dentro de la función (estás haciendo un paso por referencia, y por tanto las modificaciones en la variable se mantienen).

Espero que fuese eso a lo que te referías. Sí no es así, pues comenta e intentaré ayudarte.

Saludos.

Alien-Z

#5
Muchas gracias, eso era exactamente lo que preguntaba, ya que me ha quedado claro. Aprovecho el mismo tema para preguntar sobre un ejercicio que no se ejecuta correctamente:

Citar# include <iostream>
using namespace std;

class Juego
{
     public:
            unsigned int obtenerEdad () const;
            void modificarEdad (unsigned int edad);
           
            unsigned int obtenerPuntuacion () const;
            void modificarPuntuacion (unsigned short int puntuacion);
           
     private:
             unsigned int suEdad;
             unsigned short int suPuntuacion;
};

unsigned int Juego::obtenerEdad () const
{
                   return suEdad;
}

void Juego::modificarEdad (unsigned int edad)
{
                    edad = suEdad;
}

unsigned  int Juego::obtenerPuntuacion () const
{
                   return suPuntuacion;
}

void Juego::modificarPuntuacion (unsigned short int puntuacion)
{
                   puntuacion = suPuntuacion;
}

int main ()
{
   Juego FF;
   Juego KH;
   
   int x, x2, y, y2;
   
   cout << "Edad de FF: ";
   cin >> x;
   FF.modificarEdad(x);
   cout << "Puntuacion de FF: ";
   cin >> x2;
   FF.modificarPuntuacion(x2);
   cout << "Edad de KH: ";
   cin >> y;
   FF.modificarEdad(y);
   cout << "Puntuacion KH: ";
   cin >> y2;
   KH.modificarPuntuacion(y2);
   
   cout << "Esta es la edad de FF: " << FF.obtenerEdad();
   cout << "\nEsta es la puntuacion de FF: " << FF.obtenerPuntuacion();
   cout << "\nEsta es la edad de KH: " << KH.obtenerEdad();
   cout << "\nEsta es la puntuacion de KH: " << KH.obtenerPuntuacion();
   cout << endl;
   
   return 0;
}

Se compila y ejecuta sin darme ningún error, sin embargo después de introducir una edad y una puntuación para cada juego, me salen cifras raras al pedirlas en:

Citarcout << "Esta es la edad de FF: " << FF.obtenerEdad();
cout << "\nEsta es la puntuacion de FF: " << FF.obtenerPuntuacion();
cout << "\nEsta es la edad de KH: " << KH.obtenerEdad();
cout << "\nEsta es la puntuacion de KH: " << KH.obtenerPuntuacion();
cout << endl;

No veo el fallo, en qué me he equivocado.

Gracias de nuevo, saludos.

EDITO: He vuelto a hacer otro programa muy similar, y me pasa exactamente lo mismo, al querer imprimir por pantalla los valores de las variables me salen números exagerados.

Valkyr

Estás haciendo mal las modificaciones, tú haces esto:

Código (cpp) [Seleccionar]

void Juego::modificarEdad (unsigned int edad)
{
                     edad = suEdad;
}


es decir, a la variable que te pasan como parámetro le asignas suEdad, cuando debería ser al contrario, es decir:

Código (cpp) [Seleccionar]

void Juego::modificarEdad (unsigned int edad)
{
                     suEdad = edad;
}


De la forma que tú lo hacías es lógico que te diese valores raros, los atributos estaban sin inicializar y por tanto lo que hay en la memoria es Dios sabe qué xD.

Saludos.

Alien-Z

Totalmente acertada tu respuesta, ahora si me va bien, muchísimas gracias.

Creo que eso es todo por ahora. Nos vemos.  :)