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

#951
Programación C/C++ / Re: maximo y minimo
3 Marzo 2013, 17:24 PM
Siguiendo la linea de leosansan se puede asignar a la variable "menor" el valor máximo posible para el tipo float y a la variable "mayor" el mínimo. Mas o menos así:
#include <float.h> /* FLT_MAX y FLT_MIN */

/* ... */

float menor = FLT_MAX;
float mayor = FLT_MIN;


Un saludo
#952
Programación C/C++ / Re: ATOI + ITOA remake
27 Febrero 2013, 19:45 PM
Cita de: 85 en 27 Febrero 2013, 04:14 AMAmí me preocupa que esos códigos que publicaste tengan partes parecidas a esto:
http://foro.elhacker.net/programacion_cc/atoi_itoa_personalizadas-t358459.0.html;msg1735068#msg1735068
A no ser que seas blackzero.
No, el es otro usuario con quien he tenido el gusto de conversar en algunos temas, por ejemplo [Ayuda] Error con delete[]... algo extraño....

¿Que es lo que te preocupa?

Cita de: 85 en 27 Febrero 2013, 04:14 AMOtra cosa , las macros están hechas para simplificar y hacer el código más legible, entre otras cosas.. no se de qué libro aprendiste que no era así.
De uno que te recomendé al principio del tema: "The C Programming Language" de Brian W. Kernighan y Dennis M. Ritchie.

Cita de: 85 en 27 Febrero 2013, 04:14 AMTodos sabemos que el código en las macros se copia adonde es invocada, no es en sí resumir código sino para simplificar el entendimiento.
No es lo mismo copiar 2 veces el código de la macro FACTORES, que poner 2 veces una sóla línea que diga FACTORES(). Me extraña que no lo entiendas porque eras el más interesado en resumir líneas de TEXTO..
No. Yo estoy interesado en reducir el código fuente y eso no se consigue con macros (el numero de sentencias y expresiones es el mismo con o sin ellas). Ejemplos de ello los tienes en este tema, por ejemplo eliminar el array.

Cita de: 85 en 27 Febrero 2013, 04:14 AMSe entiende que el que usa la macro FACTORES la conoce, sabe su código, no necesita verlo repetido tantas veces. Si no entendés la macro no la uses porque en ese caso, si tenés razón, el código sería más ilegible.

Mi consejo entonces es que no uses macros que no entiendas.
Primero me cuestionas con una Falacia del hombre de paja y ahora con un Argumento ad hominem. Te aclaro: no respondo a ese tipo de comentarios.

Mi argumento es: la mayoría de tus macros no mejoran la claridad del código fuente como tampoco facilitan su desarrollo. Digo "la mayoría" y no "todas" porque haz estado actualizando tus programas.

Bueno, si piensas que mi argumento esta errado podemos discutirlo, no hay problema.

Cita de: 85 en 27 Febrero 2013, 04:14 AMITOA no fue mayormente revisada, sólo hice algunas pruebas generales, las que aparecen en el ENTRY. Tiene dos bloques de código bastante parecidos como muy bien notaste, y no estaría nada mal inventar algo para usar sólo un bloque de entre ambos.
OK. Solo una recomendación: coloca el código fuente de las funciones en un solo lugar (tu primer mensaje).

Un saludo
#953
Programación C/C++ / Re: ATOI + ITOA remake
27 Febrero 2013, 04:07 AM
El tema se inicia con el objetivo:
Cita de: 85antes de hacer una implementación lo primero es saber como funciona realmente la original.. en base a esto es que decidí arreglar estas funciones siguiendo la misma lógica de construcción, que por cierto es una que suelo usar seguido.

Empezando por ATOI
En mi primer mensaje publique el comportamiento de esa funcion, un consejo para reducir las expresiones en tus programas y dos ejemplos. ¿La intencion de estos ultimos? Tener a la vista el codigo fuente de otros realizando la misma operacion, a partir de ahi ya tienes un punto de referencia.

Acabas de publicar dos nuevas versiones de los programas con un comentario que, para decirlo de una forma amable, preocupa:
Cita de: 85SE AGREGARON VERSIONES MEJORADAS PARA NO HACER USO DE TABLAS, NI DE FUNCIONES INNECESARIAS COMO LOG, POW, STRLEN, de CTYPE, de STRING, etc SIN ASIGNACIONES DINÁMICAS, y USANDO MACROS PARA HACER EL CÓDIGO MÁS LEGIBLE
Si la intencion es desarrollar funciones propias con el mismo comportamiento que atoi (estandar) e itoa (extension) me temo que en el caso de la primera esta continua lejos del comportamiento indicado.

Esto lo puedes comprobar imprimiendo el resultado de atoi y tu version de ella, por ejemplo:
printf("%d, %d\n",  atoi("+123"),  mi_atoi("+123"));
printf("%d, %d\n", atoi(" +123"), mi_atoi(" +123"));
printf("%d, %d\n", atoi("  123"), mi_atoi("  123"));


Y al utilizar un array que para empezar no es necesario complicas las expresiones, un ejemplo de ello se da si la cadena a procesar es "0", la sentencia:
return tab1[((int)str[0]-48)-1];
Resulta en:
return tab1[-1];

Hay que eliminar el uso del array, de las macros y usar expresiones mejores, en el sentido de ser mas claras y con un minino de subexpresiones. Por ejemplo al expandirse una macro terminas con la expresion:
val1 = tab1[(int)(str[i]=='0' ? 9:(((int)str[i]-48)-1))]
Innecesariamente larga ya que se puede sustituir por:
val1 = str[i] - '0'

Por ultimo en el caso de las macros no entiendo porque piensas que hacen el codigo fuente mas legible cuando el efecto es el opuesto.

----

En cuanto a la funcion atoi los problemas aqui son un poco mas complejos. Para empezar las sentencias de retorno (salvo la ultima) estan demas debido a los condicionales.

Tambien debes analizar los dos bloques principales ya que salvo las dos operaciones en el caso de un numero negativo (almacenar el signo en la cadena y cambiarlo a positivo) son identicos. Aqui las dos opciones son restructurar la funcion para tener un solo bloque o bien crear una funcion.

Y como en el caso de la primera funcion hay que eliminar las macros.

Un saludo
#954
En el calculo de las partes no consideras si el numero de caracteres en el archivo no es múltiplo del tamaño de cada parte, en ese escenario perderías la ultima.

No necesitas de tres llamadas a función para generar el nombre, en su lugar puedes utilizar sprintf de esta forma:
sprintf(fich_dest_nombre, "%s.%03d", fich_nombre, i);

El nombre del archivo generado se almacena en el array "fich_dest_nombre" pero tu llamas a fopen usando el array "fitx_dest_izena", aquí no se si es un error del programa o de traducción. Caso similar con "fitxategi_orig".

Mejor publica el código fuente del programa (reducido al mínimo, por supuesto).

Un saludo
#955
Algunos comentarios sobre la función:
bool SonLetras(const char* buf)
{
#define MAX_ALFA 53
const char alfabetico[] = {
'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z',
'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z',0};
int ok=0;
int len = strlen(buf);
for(int i=0; i<len; i++){
for(int j=0; j<MAX_ALFA; j++){
if(buf[i]==alfabetico[j]){
ok++;
break;
}}}
if(ok==len) return true;
return false;
}


* No es una buena idea utilizar una macro como esta:
#define MAX_ALFA 53
Porque si nos equivocamos en la macro o en la lista de elementos del array la función ya no tendría el comportamiento esperado. Es mejor delegar la tarea al compilador utilizando el operador sizeof.

* No es necesario llamar a la función strlen ya que el final de la cadena se puede conocer al comparar al carácter siendo procesado con '\0'.

* Para evitar el condicional dentro del bucle interno se puede utilizar un centinela colocando el carácter a buscar en la ultima posición del array (la ocupada por el '\0').

* Si el objetivo es retornar verdadero solo si todos los caracteres son alfabéticos no se debe verificar toda la cadena una vez se encuentre un carácter que no cumpla esa condición.

Con los cambios:
bool SonLetras(const char *str)
{
   char abc[] = {
      "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
      "abcdefghijklmnopqrstuvwxyz"
   };
   size_t num_chars = sizeof abc - 1;
   size_t i;
   size_t j;
   
   for (i = 0; str[i] != '\0'; i++){
      abc[num_chars] = str[i];
     
      for (j = 0; abc[j] != str[i]; j++)
         ;
      if (j == num_chars)
         return false;
   }
   
   return true;
}


Un saludo
#956
Programación C/C++ / Re: Hilos C
25 Febrero 2013, 17:44 PM
Una introducción( buena pero en ingles) al tema de hilos y procesos es "Advanced Linux Programming". Puedes descargarla en formato PDF, solo es cuestión de buscarla en la red.

Un saludo
#957
Programación C/C++ / Re: Ayuda
25 Febrero 2013, 03:02 AM
Con solo esa información me quedo con la impresión de que te piden imprimir el resultado de cuatro operaciones:
el primero mas el segundo
el segundo menos el tercero
el cuarto por el tercero
el quinto entre el cuarto


Si es así debes utilizar la función printf en cuatro ocasiones para imprimir con "%d" el entero resultado de las expresiones:
primero + segundo
segundo - tercero
cuarto * tercero
quinto / cuarto


Tal vez si o tal vez no. Mejor (para evitar las dudas) publica el texto exacto del enunciado.

Un saludo
#958
Programación C/C++ / Re: Ayuda Con Un Programa!
25 Febrero 2013, 02:53 AM
El error en la linea:
alumno[i].nom=gets(nomb);
Se genera porque no es valido utilizar el operador "=" con arrays, tampoco necesitas la variable auxiliar "nomb". Para leer el nombre de la entrada estándar debes cambiar la sentencia a:
gets(alumno[i].nom);
Así ya no se generara el mensaje de error.

Sin embargo el uso de la función gets no es recomendable, el porque de ello (junto con alternativas) se describe en el tema |Lo que no hay que hacer en C/C++. Nivel basico|.

Un saludo
#959
Programación C/C++ / Re: ATOI + ITOA remake
24 Febrero 2013, 01:56 AM
Cita de: 85 en 24 Febrero 2013, 00:19 AMAún se puede cambiar las CTYPE por algo como
Citar>=48&&<=57
, evitaríamos código extra
No porque sin un motivo de peso se afectaría la claridad en el código fuente. En la misma linea mejor evitar el uso de 48 y 57 sustituyendo estos por '0' y '9', el valor es el mismo con la ventaja de indicar el contexto (proceso de caracteres).

Casi lo olvido, bucles como este:
int copia = num;
int unidades_decimales = 1;// unidad de 1
while(1)
{
if(copia>=10)
{
copia /= 10;
unidades_decimales++;
}
else
{
break;
}
}

Los puedes reducir a:
int unidades_decimales = 1;
int copia;
for (copia = num; copia >= 10; copia /= 10)
   unidades_decimales++;


Por ultimo, ¿Estas aprendiendo C en base a un buen libro? Si todavía no tienes uno de calidad te recomiendo "The C Programming Language" o bien "Pointers on C", puedes obtener mas información sobre ellos mediante el motor de búsqueda de los foros.

Un saludo
#960
Programación C/C++ / Re: ATOI + ITOA remake
23 Febrero 2013, 18:21 PM
Cita de: 85 en 22 Febrero 2013, 03:32 AMEl problema que enfrenta esta función es cuando alguien trata de pasarle un parámetro que no es una cadena, por ejemplo un 'char'
char str = 'B';
int entero = mi_atoi(&str);
La función atoi no puede conocer a prior si se pasa la dirección de una cadena o un carácter, esta literalmente confía en que sera usada correctamente. En otras palabras no tienes que preocuparte ya que eso es responsabilidad de quien llama a tu función.

Cita de: 85 en 22 Febrero 2013, 03:32 AM
se lo hace de esa forma especificando la dirección de la variable, pero en la función original ATOI esto devuelve 0, según mis pruebas.
El comportamiento de atoi es el siguiente:
1) Se descarta el espacio blanco.
2) Se procesa el signo.
3) Se procesan los dígitos hasta encontrar un carácter no valido.

Si por lo menos se procesa un dígito se retorna el numero, caso contrario la función debe retornar cero. No es lo ideal ya que ante una cadena como "123JKL" la función retorna 123 pero bueno, esa es su especificación.

----

En tus funciones no es necesario utilizar tablas. Para obtener el entero o carácter correspondiente solo debes sumar (o restar, dependiendo del caso) el valor '0':
'0' + Digito == '0', '1', '2', ... /* Digito == 0, 1, 2, ... */
Caracter - '0' == 0, 1, 2, ... /* Caracter == '0', '1', '2', ...*/


----

Una implementación de la función atoi con el comportamiento indicado:
#include <ctype.h>

int fn_atoi(const char *p)
{
   int num = 0;
   int sign = 1;
   
   while (isspace(*p))
      p++;
   
   if (*p == '-'){
      sign = -1;
      p++;
   }else if (*p == '+')
      p++;
   
   while (isdigit(*p)){
      num = num * 10 + *p - '0';
      p++;
   }
   
   return sign * num;
}


Y una implementación de itoa (que por cierto no es parte de la biblioteca estándar de C) es:
#include <math.h>

char *fn_itoa(int num, char *str)
{
   char *p = str + 1;
   
   if (num < 0){
      *str = '-';
      num = -num;
      p++;
   }
   
   if (num >= 10)
      p += (int) log10(num);
   
   *p = '\0';
   do {
     *--p = '0' + num % 10;
   }while ((num /= 10) > 0);
   
   return str;
}


Un saludo