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 - eferion

#721
Cita de: Proweb en  6 Marzo 2014, 16:59 PM
Ando buscando vídeos para aprender C++, algunos que encontre eran bastante buenos, pero quería pedirles su opinión/experiencia.

Donde esté un buen manual que se quiten los videos, en serio... no necesitas ver cómo alguien escribe texto en una pantalla... necesitas un tema que te explique en mayor o menor profundidad cómo funcionan las cosas.

Cita de: Proweb en  6 Marzo 2014, 16:59 PM
Otra duda que tenía, era que si el C++ de Microsoft y el de todos los demás son iguales, o si pasa lo mismo que con Basic (lenguaje del cual vengo) que depende del compilador no siempre se escribe igual.

C++, al igual que VisualBasic, Perl, Java, C, Modula2, javascript, C#, PHP, ... cualquier lenguaje de programación en general está sujeto a un estándar ( ya sea éste oficial o no ). Dicho estándar especifica el formato de las instrucciones y, en mayor o menor medida, una serie de librerías básicas para poder hacer algo de provecho con dicho lenguaje.

Esta parte, el núcleo duro que rodea a un programa, es siempre igual y no cambia.

Otra cosa son las librerías adicionales que añade cada compañía con el fin de darle valor añadido a su producto... esas librerías, como cualquier otra que te descargues o tengas que usar, puede tener una interfaz de lo más variopinta y tendrás que empollarte su API para poder hacer algo con ella... y por supuesto estos conocimientos sólo te servirán para programar con esa librería... porque otra distinta funcionará de forma diferente.

Cita de: Proweb en  6 Marzo 2014, 16:59 PM
O sería mejor aprender antes C? Dicen que ya esta obsoleto, y para perder el tiempo prefiero no perderlo...

C ni está obsoleto ni creo que lo esté en bastantes años ( al igual que C++, Fortran, Cobol, ... ) La razón es que hay tanto dinero invertido en programas escritos con estos lenguajes que es inasumible cambiarlos... y mientras la situación siga igual éstos lenguajes tendrán el futuro garantizado.

Lo que sí que es cierto es que C te lleva a comprender mejor determinados aspectos de la programación que con C++ pueden pasar un poco por alto... como por ejemplo cómo usar la memoria de forma eficiente. Yo personalmente aprendí primero C y después pasé a C++... y de ahí ya a Perl, PHP, C#, Java.... lo complicado no es aprender a programar en un lenguaje determinado... lo difícil es aprender a programar.
#722
Cita de: dato000 en  6 Marzo 2014, 16:55 PM
dejo una pequeña modificación del código porque no corria correctamente, solo detalles.
Esa era justamente la idea... no corre porque al ser virtual pura no puedes instanciar clases de ese tipo.

Lo que has conseguido con ese cambio es que 'A' no sea abstracta y, por tanto, puede ser instanciable.

Cita de: dato000 en  6 Marzo 2014, 16:55 PM
Vaya genial explicación, habia visto esa parte para c#, pero no para c++, virtuales yeah!!!!!!!

Celebro que te haya gustado.

Para más dudas aquí estamos :)

#723
Programación C/C++ / Re: Error c++
6 Marzo 2014, 16:47 PM
Cierto... no me había fijado en las dos llamadas consecutivas.

Bien visto.
#724
Programación C/C++ / Re: tableros
6 Marzo 2014, 16:25 PM
Solo un detalle tonto yoel_alejandro. Se te olvidó liberar la memoria.

Se que el programa al finalizar la va a liberar por sí mismo... pero no hay que perder las buenas costumbres :D
#725
El código que usas para convertir a números es un poco raro... sobretodo porque arrastras el bit de negativo para hacer la conversión final en otro sitio diferente.

Además, el offset en los 16 bits es siempre positivo... al menos según el enunciado que has copiado.

He desacoplado los diferentes tipos de indexados para dotarlo de más flexibilidad y capacidad de crecimiento.


#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define _4BITS  0x0F
#define MIN_IDX_5BITS -16
#define MAX_IDX_5BITS 15
#define MIN_IDX_9BITS -256
#define MAX_IDX_9BITS 255
#define MIN_IDX_16BITS 256
#define MAX_IDX_16BITS 65535

int verificarRegistro(char *cadena);
void verificarRangoIndexado_5_9_16bits(int num);
void modoDireccionamiento(char *operando);
void indexado_5bits_9bits_16bits(char *operando,int x);
int indexado_5bits( int offset, char* registro );
int indexado_9bits( int offset, char* registro );
int indexado_16bits( int offset, char* registro );
int indexado_indirecto( int offset, char* registro, int min, int max );
int indexado_preincremento( int offset, char* registro );
int indexado_postincremento( int offset, char* registro );

int convertir_a_numero(char *cadena);

int main()
{
 printf( "5 bits ----------\n");
 char *operando = "15,X";
 modoDireccionamiento(operando);
 operando = "-16,Y";
 modoDireccionamiento(operando);

 printf( "9 bits ----------\n");
 operando = "16,SP";
 modoDireccionamiento(operando);
 operando = "-17,PC";
 modoDireccionamiento(operando);
 operando = "255,X";
 modoDireccionamiento(operando);
 operando = "-256,Y";
 modoDireccionamiento(operando);

 printf( "16 bits ---------\n");
 operando = "256,SP";
 modoDireccionamiento(operando);
 operando = "65535,PC";
 modoDireccionamiento(operando);

 printf( "preincremento ---\n");
 operando = "8,+PC";
 modoDireccionamiento(operando);
 operando = "4,-PC";
 modoDireccionamiento(operando);

 printf( "postincremento --\n");
 operando = "1,PC+";
 modoDireccionamiento(operando);
 operando = "7,PC-";
 modoDireccionamiento(operando);

 printf( "No validos -----\n" );
 operando = "-6000,PC";
 modoDireccionamiento(operando);
 operando = "200,A";
 modoDireccionamiento(operando);
 operando = "24,+PC";
 modoDireccionamiento(operando);
 return 0;
}

void modoDireccionamiento(char *operando)
{
 char buffer[255];
 strcpy( buffer, operando );

 int length = strlen( operando );
 char* op1 = strtok( buffer, "," );
 char* op2 = strtok( NULL, "," );

  int continuar = 1;
 if ( strlen( op1 ) != length && strlen( op2 ) != 0 )
  {
    int offset = convertir_a_numero( op1 );

    continuar = !indexado_5bits( offset, op2 );

    if ( continuar )
     continuar = !indexado_9bits( offset, op2 );

    if ( continuar )
     continuar = !indexado_16bits( offset, op2 );

    if ( continuar )
     continuar = !indexado_postincremento( offset, op2 );

    if ( continuar )
     continuar = !indexado_preincremento( offset, op2 );
  }

 if ( continuar )
   printf( "Indexado no reconocido.\n" );
}

int indexado_5bits( int offset, char* registro )
{
 int ok = indexado_indirecto( offset, registro, MIN_IDX_5BITS, MAX_IDX_5BITS );

 if ( ok )
   printf("Indexado de 5 bits, (IDX)\n");

 return ok;
}

int indexado_9bits( int offset, char* registro )
{
 int ok = indexado_indirecto( offset, registro, MIN_IDX_9BITS, MAX_IDX_9BITS );

 if ( ok )
   printf("Indexado de 9 bits, (IDX)\n");

 return ok;
}

int indexado_16bits( int offset, char* registro )
{
 int ok = indexado_indirecto( offset, registro, MIN_IDX_16BITS, MAX_IDX_16BITS );

 if ( ok )
   printf("Indexado de 16 bits, (IDX)\n");

 return ok;
}

int indexado_indirecto( int offset, char* registro, int min, int max )
{
 int ok = ( offset >= min && offset <= max );

 if ( ok )
   ok = verificarRegistro( registro );

 return ok;
}

int indexado_preincremento( int offset, char* registro )
{
 int ok = ( ( offset & _4BITS ) == offset );

 if ( ok )
   ok = (registro[0] == '-') || (registro[0] == '+');

 if ( ok )
   ok = verificarRegistro( registro + 1 );

 if ( ok )
   printf( "Indexado con preincremento, (IDX)\n" );

 return ok;
}

int indexado_postincremento( int offset, char* registro )
{
 char buffer[10];
 strcpy(buffer, registro);

 int ok = ( ( offset & _4BITS ) == offset );

 if ( ok )
 {
   int pos_inc = strlen( buffer ) - 1;
   ok = (buffer[pos_inc] == '-') || (buffer[pos_inc]=='+');
   buffer[pos_inc] = 0;
 }

 if ( ok )
   ok = verificarRegistro( buffer );

 if ( ok )
   printf( "Indexado con postincremento, (IDX)\n" );

 return ok;
}

int convertir_a_numero(char *cadena)
{
 int numero = 0;
 int index = 0;
 int neg = 0;
 if ( cadena[0] == '-' )
 {
   neg = 1;
   index = 1;
 }

 for ( ; index < strlen(cadena); index++ )
 {
   numero *= 10;
   numero += cadena[index] - '0';
 }

 if ( neg )
   numero *= -1;

 return numero;
}

int verificarRegistro(char *cadena)
{
 int i;
 char *registro[] = {"X","Y","SP","PC"};
 for(i = 0;i < 4;i++)
 {
   if((strcmp(cadena,registro[i])) == 0)
     return 1;
 }
 return 0;
}


Salida:


5 bits ----------
Indexado de 5 bits, (IDX)
Indexado de 5 bits, (IDX)
9 bits ----------
Indexado de 9 bits, (IDX)
Indexado de 9 bits, (IDX)
Indexado de 9 bits, (IDX)
Indexado de 9 bits, (IDX)
16 bits ---------
Indexado de 16 bits, (IDX)
Indexado de 16 bits, (IDX)
preincremento ---
Indexado con preincremento, (IDX)
Indexado con preincremento, (IDX)
postincremento --
Indexado con postincremento, (IDX)
Indexado con postincremento, (IDX)
No validos -----
Indexado no reconocido.
Indexado no reconocido.
Indexado no reconocido.


Dado que todas las funciones de comprobación de índices tienen la misma firma, se podría crear un puntero con todas las comprobaciones y ejecutarlas de forma iterativa en un bucle for... pero eso ya lo dejo de tu mano.

Un saludo.
#726
Programación C/C++ / Re: Error c++
6 Marzo 2014, 09:14 AM
Varias cosas:

1. int a???? que co** es a????, vale, si inviertes unos minutillos en analizar el código descubres que a es una variable global que la usas para almacenar la cantidad de registros... ¿es necesario llamarla a?? ¿no había un nombre un poco más apropiado? no se algo quizás del tipo 'numeroDeRegistros'. No se, yo creo que si alguien se encuentra con una variable que se llama 'numeroDeRegistros' se hace una idea bastante aproximada del uso que tiene esa variable y puede llegar a entender el código con más rapidez.

2. No uses variables globales. No cuesta nada poner un argumento más en las funciones y con eso consigues que seguir el programa sea más sencillo.

3. Por si no te has dado cuenta, no has inicializado tu querida 'a'... si ejecutas el programa y no pasas por la opción 1 el resultado no te va a gustar.

4. En cargar_arch... si falla la carga del archivo TAMPOCO actualizas el valor de 'a'...

5. ¿Por qué el buffer de nombres es de 25 y el de apellidos de 30?? ¿por qué 'aux' es de 25 si también va a almacenar apellidos? Lo mejor para evitar este tipo de inconsistencias es usar macros para definir valore fijos:


#define MAX_REGS 1000
#define LONG_REG 30

char nombres[MAX_REGS][LONG_REG],apellidos[MAX_REGS][LONG_REG];

// ...

char aux[LONG_REG];

// ...


6. fscanf y scanf pueden provocar desbordamiento de buffer si intentas cargar una cadena más grande que el buffer... en tu caso 25 o 30 caracteres... deberías hechar un vistazo a |Lo que no hay que hacer en C/C++. Nivel basico|.

7. Da la sensación de que en la opción 2 intentas ordenar el vector antes de mostrarlo... No hace falta comprobar un registro contra sí mismo para hacerlo.


for(int con=0;con<a;con++)
{
  for(int con2=con+1;con2<a;con2++)
  {
    if(strcmp(apellidos[con],apellidos[con2])<0)
    {
      strcpy( aux, apellidos[con] );
      strcpy( apellidos[con], apellidos[con2] );
      strcpy( apellidos[con2], aux );
      strcpy( aux, nombres[con] );
      strcpy( nombres[con], nombres[con2] );
      strcpy( nombres[con2], aux );
    }
  }
}


Si además metes ese código repetitivo en una función, el código se simplifica:


void SwapStrings( char* string1, char* string2 )
{
  char aux[30];
  strcpy( aux, string1 );
  strcpy( string1 , string2  );
  strcpy( string2 , aux );
}

// ...

for(int con=0;con<a;con++)
{
  for(int con2=con+1;con2<a;con2++)
  {
    if(strcmp(apellidos[con],apellidos[con2])<0)
    {
      SwapStrings( apellidos[con], apellidos[con2] );
      SwapStrings( nombres[con], nombres[con2] );
    }
  }
}


Y no parece buena idea que este código se ejecute SIEMPRE que se vayan a visualizar los registros... deberías aislar este código en una función y llamarlo después de que el usuario introduzca los datos y después de cargar los datos del archivo.

8. Tu programa no está en C++, está en C puro y duro.

9. Al guardar tienes el siguiente código:


for(int c=0;c<a;c++)
{
  for(int c2=0;c2<a;c2++)
  {
    fprintf(arch,"%s\n",&nombres[c]);
    fprintf(arch,"%s\n",&apellidos[c]);
  }
}


el bucle de c2 no solo es redundante, sino que tiene un efecto dañino y es que la lista va a aparecer repetida en el archivo tantas veces como elementos tengas en la lista, 2 nombres aparecerán 2 veces, 20 nombres aparecerán 20 veces cada uno... 1000 nombres....

10. El siguiente código está mal:


printf("Nombre: ",nombres[c]);
scanf("%s",&nombres[c]);
printf("Apellido: ",apellidos[c]);
scanf("%s",&apellidos[c]);


Por varios motivos:

* para sacar el nombre y los apellidos por pantalla te falta '%s':

printf( "Nombre: %s", nombres[c] );

Y lo mismo para los apellidos... además si no añades ni espacios ni saltos de línea te van a salir pegados y el efecto es feo.

Otra cosa es que no desees mostrar el nombre que había anteriormente en la lista, lo cual es más lógico... en ese caso te puedes ahorrar pasar por argumentos en el printf el nombre y los apellidos:

printf("Nombre: " );

* Los scanf, en el caso de vectores, matrices y punteros en general, no necesitan el '&'. Esto es así porque scanf necesita punteros para almacenar los valores... y un vector es un puntero... no necesitas pasar referencias:

scanf( "%s", nombres[c] );

11. Fíjate en la función carga_arch:


int cargar_arch()
{
  if(fopen("dato.txt","r"))
  {
    // ...
    return 1;
  }               
  else if (!fopen("dato.txt","r"))
  {
    return 0;
  }
}


No tiene sentido que intentes abrir dos veces el archivo, porque... ¿Y si falla la primera vez pero funciona la segunda? el else se inventó precisamente para tratar el caso del "y si no...". Y no sufras por esto, el compilador, a diferencia del programador, no se confunde con estas cosas.


int cargar_arch()
{
  if(fopen("dato.txt","r"))
  {
    // ...
    return 1;
  }               
  else
  {
    return 0;
  }
}


12. En guardar_arch...


arch=fopen("dato.txt","w");
fprintf(arch,"%i\n",&a);


¿Y si no se puede abrir el archivo? Aprende y aplica esta regla de oro: "Valida que los punteros son válidos antes de usarlos".

Y bueno, con esto creo que a grandes rasgos esto es todo. Espero que no se me haya olvidado nada.

Un saludo.
#727
Sin problemas.

Tu pregunta que seguro que alguien sabe la respuesta ;)
#728
Programación C/C++ / Re: ayuda
5 Marzo 2014, 17:07 PM
Cita de: yoel_alejandro en  5 Marzo 2014, 16:57 PM
Estimados engelx y leosansan,

Me acuso culpable de tener problemas de visión al no haber leído la palabra "centenar". A cualquiera le ocurre un lapsus de lectura, y esto no es motivo para descalificar la preparación de la persona. La solución que propuse es correcta de no ser por la condición i + j + k = 100 que sinceramente no había leído. ¡Sencillamente eso!

Y me parece que ustedes han exagerado este caso con el único motivo de descalificarme. Si me quieren fuera del foro, pues díganmelo, o dirijan una petición al moderador sustentada con los delitos de que me acusan.

El programa se corrige al añadir la condición i + j + k == 100 dentro del if y ajustar los valores de i_MAX, j_MAX y k_MAX para que no excedan de 98.

Respecto al código complejo, pues traté de hacer un programa un poco elaborado, que "hablara" con el usuario y fuera flexible en el sentido de que las constantes A, B, C, T pudieran ser cambiadas para resolver un problema con valores diferentes. Me acuso también culpable de estos delitos!!! Ah, ..... y la línea

printf("%d, %d, %d, %d\n", i_MAX, j_MAX, k_MAX, i_MAX*j_MAX*k_MAX);

no iba, era sólo con propósitos de debug  :D


Yo creo que los roces han tenido lugar por la forma en la que has explicado las cosas... da la sensación de que intentabas quedar por encima de los demás.

Seguramente no sea el caso... pero si los demás podemos interpretar eso de tus palabras es perfectamente lógico que tu hayas malinterpretado la intención que va detrás de las palabras de leosansan.

No hay que ponerse así, yo creo que en el foro todos intentamos aportar nuestro granito de arena a la causa... unas veces unos meten la pata y en otras lo meten otros... no pasa nada.

Lo que sí hay que tener en cuenta es que en un foro... como en cualquier medio de comunicación escrita, no se transmiten sentimientos en la conversación, por lo que es complicado hacerse una idea clara y acertada acerca de la motivación del interlocutor que se encuentra al otro lado de la conversación.

No hay que llegar a los extremos que se han visto en esta conversación.
#729
Puedes crearte una página base que contenga el código de autenticación y hacer que las páginas de tu portal hereden de ésta.
#730
Cita de: amchacon en  5 Marzo 2014, 13:33 PM
Pues yo veo unos cuantos métodos privados...

El único miembro de la clase ArbolBinario... una instancia de tipo Nodo... es público... todo lo que se añada después de eso es absurdo. Si yo puedo modificar el estado de un objeto a mi antojo sin pasar por su interfaz no tiene sentido la encapsulación.