Menú

Mostrar Mensajes

Esta sección te permite ver todos los mensajes escritos por este usuario. Ten en cuenta que sólo puedes ver los mensajes escritos en zonas a las que tienes acceso en este momento.

Mostrar Mensajes Menú

Mensajes - K-YreX

#711
Esto sucede porque una variable creada en un <case> del <switch> sigue existiendo en el resto de <case>. Pero no tienen el valor inicializado y por eso si escribes la inicialización junto a la declaración, te va a dar un error.

Una forma de solucionar eso es separando la inicialización de la declaración como has visto tú. Y otra forma es usar llaves {} para crear un bloque. :-X
Código (cpp) [Seleccionar]

switch(indice){
    case 0:
    {
        int edad = 0;
        // ya funciona
        break; // no olvidar el break
    }
    case 1:
        // lo que sea
        break;
    default:
        // lo que sea
        break; // opcional ya que es el ultimo
}
#712
Creo que puramente en C no se puede ya que C no está orientado a objetos como podría estarlo C++.
Decirte que lo que sí puedes hacer es crear un <struct> en C++ y entonces si puedes declarar una función miembro del <struct>.
Pero tienes algunos errores como inicializar la variable y luego tu función no tiene sentido, devuelve un <int> y no tiene ningún <return>...

Te dejo el siguiente código que compilado como un fuente de C++ sí funciona (g++ test.cpp -o test).
Si lo tratas como un fuente C, no va a funcionar (gcc test.c -o test).
Código (cpp) [Seleccionar]

#include <stdio.h> // #include <cstdio> para C++ mejor

struct foo{
    int x;
    int sumar(int y){
        return x+y;
    }
};

int main(){
    foo my_foo;
    my_foo.x = 3;
    printf("%d\n", my_foo.x); // salida: 3
    int suma = my_foo.sumar(5);
    printf("%d\n", suma); // salida: 8
}


No sé si te sirve  :-X
#713
Programación C/C++ / Re: Necesito ayuda
25 Febrero 2019, 00:58 AM
Bueno, vamos a ir revisando cosas del código:
Lo primero de todo, cuando pongas un código usa las etiquetas de código GeSHi.
  • <gets()> no es muy recomendable para guardar cadenas ya que es poco seguro. Su variante más segura es <fgets()> (tiene otros parámetros pero puedes encontrar información al respecto en cualquier web/libro.

  • En el filtro del <do while> tienes un condicional <if> vacío. Además es más usual hacerlo con (s/n) y así sólo tienes que manejar un caracter en al comprobación y no una cadena.
    Código (cpp) [Seleccionar]

    char opcion;
    do{
        cout << "Empezar (s/n): ";
        cin >> opcion;
    }   while(opcion != 's' || opcion != 'S');


  • Te recomiendo usar strings en lugar de cadenas de caracteres estilo C. Son más fáciles de manejar y no tienes que reservar arrays de tamaño aleatorio.

  • Te recomiendo usar <getline()> mejor que <gets()> o <fgets()>. También puedes encontrar cómo funciona en webs/libros.

  • Usa nombres de variables que te ayuden a seguir el programa. Imagina un programa enorme donde usas <t> <r1> <r2>... :-\ Mejor nombres como <puntuacion> <respuesta_usuario> <respuesta_correcta>...

  • No es necesario el 0 en <t = 0 + 10> ni en <t = 0 - 5>. Como mucho para acumular resultados pero en ese caso sería <t += 10> y <t -= 5>.

  • Cambia el <system("pause")> por <cin.get()>. La función va a ser la misma y evitas hacer una llamada al sistema totalmente innecesaria y costosa.
#714
Tenía la intuición de que no parece un problema que se resuelva con una única fórmula. Por lo que intenté ir sacando relaciones a ver si llegaba a algo... Empecé encontrando algunas recurrencias que al final resultaron ser más sencillas. Mi planteamiento era el siguiente:
  • La espiral podemos verla como si fueran anillos concéntricos (el 1 es el anillo 0).
  • El máximo valor del anillo n es (2*n+1)*(2*n+1) y se encuentra en la esquina inferior derecha de su anillo correspondiente.

    El problema es que no tengo demasiado tiempo y como me parece un problema entretenido dejo aquí mis avances por si alguien quiere continuar con ello y que no se quede abandonado. (Tengo algunas recurrencias más por si le interesan a alguien... aunque creo que no son demasiado importantes).

    Luego he visto que por ahí se me iba a complicar mucho la cosa así que he pensado que se puede hacer una matriz donde dibujar la espiral calculando antes el número de anillos necesarios para que la espiral contenga el número que desea buscar el usuario. De ahí he sacado que:
  • El orden de la matriz que contiene n anillos es (2*n-1).

    Me parece que la forma más sencilla es esta segunda (aunque sea un poco limitada).

    crear matriz con la forma de la espiral
    valor_actual := valor introducido por el usuario
    mientras valor_actual != 1
        comparar con arriba, abajo, izquierda, derecha (cuidado con los limites)
        valor_actual := menor de los 4 valores anteriores
        distancia++

    Cuando tenga tiempo intentaré acabarlo :-X
#715
Cita de: avesudra en 23 Febrero 2019, 16:34 PM
Código (cpp) [Seleccionar]

const char* cadenaA = "HOLA";
char* cadenaB = new char[5];
strncpy(cadenaB, cadenaA, 5);

Persona personaA = new Persona();
Persona personaB = new Persona();

personaA.IngresarNombre(cadenaA);

personaB.IngresarNombre(cadenaB);

delete[] cadenaB;


Un pequeño apunte. Los objetos de tipo persona los estás creando dinámicamente:
Código (cpp) [Seleccionar]

Persona *personaA = new Persona();
Persona *personaB = new Persona();
// ...
delete personaA;
delete personaB;


Si los creas estáticamente no necesitas usar <new>:
Código (cpp) [Seleccionar]

Persona personaA; // ya llama al constructor sin parametros sin especificarlo nosotros
// ...
// no es necesario liberar memoria ya que no se ha reservado memoria dinamicamente
#716
Las dos opciones que tienes son:
Código (cpp) [Seleccionar]

void Persona::IngresarNombre(const char *nombre);

void Persona::IngresarNombre(const char nombre[]);


Y en ambos casos estás haciendo lo mismo. Estás pasando como parámetro la dirección del elemento 0, es decir, el inicio del array en este caso (ya que doy por hecho que ese puntero contiene una cadena/array de caracteres).

No tienes que liberarlo; y te explico. Un puntero se libera con <delete> si se ha usado antes <new> sobre él. Es decir, sólo si estás usando memoria dinámica. En otro caso el puntero se libera solo cuando finaliza la ejecución del programa como cualquier otra variable.
En el caso de que SÍ estés usando memoria dinámica, debes liberar el puntero cuando ya no vayas a usarlo más. Y si has asignado el valor de ese puntero a otro puntero y borras el primero, también estarás borrando el segundo. Ya que lo que haces en realidad es liberar la memoria a la que está apuntando.

Mi recomendación es que no borres el puntero dentro de la función y así te servirá para pasar punteros dinámicos como no dinámicos. Si dentro de la función borras el puntero y en un caso determinado le pasas un puntero no dinámico (osea el comienzo de un array creado sin <new>) tendrás problemas.

Te dejo aquí un par de ejemplos simples para que veas las diferencias :-X:
Código (cpp) [Seleccionar]

int main(){
   char *p_dinamico;
   p_dinamico = new char [20]; // tendras que liberarlo antes de acabar la ejecucion del programa
   char p_estatico[20]; // se liberara solo al acabar

   Persona my_person;
   my_person.InsertarNombre(p_dinamico); // p_dinamico lo puedes liberar en el main mas adelante
   my_person.InsertarNombre(p_estatico); // p_estatico se liberara solo

    delete [] p_dinamico; // como hemos dicho antes
}
#717
Exacto, mientras estés en una posición de memoria perteneciente a ese programa no, pero si accedes a memoria que no le pertenece te debería saltar un error y no se ejecutaría. Lo que se conoce como "violación de segmento" o "segmentation fault".

Y respecto al array, si lo que quieres es usar un array, tienes que declararlo como un array. Sino sólo estás reservando memoria para un objeto, no para un array de objetos. Y una vez creado mantenerte dentro de los límites para evitar errores en ejecución.  :-X
#718
Eso es erróneo aunque no aparezca ningún mensaje de error del compilador. Por ejemplo eso era un error que yo veía más en C que trabaja un poco a más bajo nivel que C++...

Un programa reserva memoria para la ejecución completa del mismo. Si no me equivoco, mientras la posición a la que intentas acceder siga dentro del marco de ese programa, no dará error (pero puede ocasionar problemas si tenías otros datos en esa posición). En cambio, cuando la posición sobrepasa los límites de memoria del programa es cuando se sucede un error en tiempo de ejecución para evitar que modifiques un espacio de memoria que puede estar usando tu ordenador para otras cosas.
Si no es exactamente así, pueden corregirme. A mí me suena que era algo así... :-X
#719
Programación C/C++ / Re: Necesito ayuda
19 Febrero 2019, 14:29 PM
Además de lo ya comentado no puedes usar <cin> para la entrada de datos. Ya que <cin> sólo almacena hasta el primer espacio. Por lo que si introduces "el nombre" mediante un <cin>, en la variable sólo se almacenará "el".
Para solucionar eso te recomiendo usar <getline()>. Suerte :-X

PD: Si quieres ampliar un poco el programa te recomiendo transformar toda la solución a minúsculas y comparar sólo con "el nombre". Por si se da el caso de que alguien lo escribe en mayúsculas.
#720
Cita de: digimikeh en 13 Febrero 2019, 13:38 PM
Estuve observando el ostream que mencionas, pero por mas que veo, se me pasa el error, no lo veo, en qué linea está ?..

En tu fichero Persona.cpp en la declaración de la sobrecarga del operador <<. Y si lo quieres ver en el primer mensaje de este tema, el segundo bloque de código:
Cita de: digimikeh en 13 Febrero 2019, 04:44 AM
Código (cpp) [Seleccionar]

//Persona.cpp

#include "Persona.h"

using namespace std;

//Sobrecarga operador
ostring & operator<<(ostring & os, const Persona & _estaPersona){
     os << "Nombre : " << _estaPersona.LeerNombre() << endl;
     os << "Edad     : " << _estaPersona.LeerEdad() << endl;
     return os;
}