Sentencia switch vs tablas de búsqueda

Iniciado por kutcher, 4 Septiembre 2014, 17:45 PM

0 Miembros y 2 Visitantes están viendo este tema.

kutcher

Buenas, tengo las siguientes funciones:

Código (cpp) [Seleccionar]
char * func1(int condicion)
{
      switch(condicion)
     {
         case 0: return "EQ";
         case 1: return "NE";
         case 2: return "CS";
         case 3: return "CC";
         case 4: return "MI";
         case 5: return "PL";
         case 6: return "VS";
         case 7: return "VC";
         case 8: return "HI";
         case 9: return "LS";
         case 10: return "GE";
         case 11: return "LT";
         case 12: return "GT";
         case 13: return "LE";
         case 14: return "";
         default: return 0;
      }
}


Y

Código (cpp) [Seleccionar]
char * func2(int condicion)
{
    if ((unsigned) condicion >= 15)
return 0;
    return "EQ\0NE\0CS\0CC\0MI\0PL\0VS\0VC\0HI\0LS\0GE\0LT\0GT\0LE\0\0" +
               3 * condicion;
}


Se que ambas son equivalentes pero lo que me cuesta entender es como la función     con tabla de búsqueda logra aislar la cadena requerida según la condición especificada, si alguien podría explicarme como sucede esto...

Saludos kutcher 

Eternal Idol

#1
Tal vez asi te resulte mas claro:
char *cadena_base = "EQ\0NE\0CS\0CC\0MI\0PL\0VS\0VC\0HI\0LS\0GE\0LT\0GT\0LE\0\0";

cadena_base es un puntero a char * que apunta en realidad a varias cadenas.

Entonces func2 retorna un puntero siempre dentro de la misma cadena_base (para eso comprueba que el valor de condicion no sea mayor a 14) usando: cadena_base + (3 * condicion).

3 es el tamaño de cada cadena dentro de cadena_base con su cero terminador y condicion actua como indice.

Ejemplos, si condicion es 0:
cadena_base + 3 * 0 = cadena_base, como hay un \0 despues de EQ ahi terminara la cadena.

Si condicion es 2:
cadena_base + 3 * 2 = cadena_base + 6 = al apuntar a seis caracteres despues de cadena_base entonces el puntero retornado apunta a la cadena CS.
La economía nunca ha sido libre: o la controla el Estado en beneficio del Pueblo o lo hacen los grandes consorcios en perjuicio de éste.
Juan Domingo Perón

kutcher

Cita de: Eternal Idol en  4 Septiembre 2014, 20:19 PM
cadena_base es un puntero a char * que apunta en realidad a varias cadenas.

@Eternal Idol: Entonces tu dices que func2 retorna la dirección de la cadena solicitada :

Código (cpp) [Seleccionar]
"EQ\0NE\0CS\0CC\0MI\0PL\0VS\0VC\0HI\0LS\0GE\0LT\0GT\0LE\0\0"

Acaso este tipo de cadenas también poseen una dirección de almacenamiento

Eternal Idol

Si claro, por eso su tipo de retorno es char *; si tambien, todos los bytes de esas cadenas estan en la sección de datos (tanto en func1 como en func2).
La economía nunca ha sido libre: o la controla el Estado en beneficio del Pueblo o lo hacen los grandes consorcios en perjuicio de éste.
Juan Domingo Perón

kutcher

Cita de: Eternal Idol en  4 Septiembre 2014, 20:43 PM
Si claro, por eso su tipo de retorno es char *; si tambien, todos los bytes de esas cadenas estan en la sección de datos (tanto en func1 como en func2).

Ya entonces esto seria lo mas parecido a un array de caracteres aunque no la hayamos declarado como tal, en cuanto a tu comentario: los bytes de esas cadenas están en la sección de datos no comprendo como va esto..

Saludos

Eternal Idol

Si, un conjunto de bytes, con el cero terminador es una cadena.

En un ejecutable hay secciones, por lo general .text para el codigo binario, .data para las variables globales (donde estaran estas cadenas) y .rdata para constantes.
La economía nunca ha sido libre: o la controla el Estado en beneficio del Pueblo o lo hacen los grandes consorcios en perjuicio de éste.
Juan Domingo Perón

kutcher

Cita de: Eternal Idol en  5 Septiembre 2014, 02:01 AM
Si, un conjunto de bytes, con el cero terminador es una cadena.

En un ejecutable hay secciones, por lo general .text para el codigo binario, .data para las variables globales (donde estaran estas cadenas) y .rdata para constantes.

Solo una ultima consulta mas; como ya sabemos func2 retorna una dirección de memoria que correspondería a una cadena local de func2 pero si al salir de tal función se perdería la referencia a ella

Saludos

Eternal Idol

Cita de: kutcher en  5 Septiembre 2014, 18:25 PM
Solo una ultima consulta mas; como ya sabemos func2 retorna una dirección de memoria que correspondería a una cadena local de func2 pero si al salir de tal función se perdería la referencia a ella

Saludos

No, como te decia esta en la sección de datos, es como una variable global. Si usaras un array de caracteres definido en la funcion entonces si seria una variable local, estaria en la pila y al salir de la funcion estaria fuera de su ambito. Igual no hay ninguna diferencia entre func1 y func2 en este aspecto.
La economía nunca ha sido libre: o la controla el Estado en beneficio del Pueblo o lo hacen los grandes consorcios en perjuicio de éste.
Juan Domingo Perón

kutcher

Cita de: Eternal Idol en  5 Septiembre 2014, 19:06 PM
No, como te decia esta en la sección de datos, es como una variable global. Si usaras un array de caracteres definido en la funcion entonces si seria una variable local, estaria en la pila y al salir de la funcion estaria fuera de su ambito.

Si efectivamente tiene ámbito global lo he comprobado con este código:

Código (cpp) [Seleccionar]
#include<stdio.h>

char *func2(int condicion)
{
    if ((unsigned) condicion >= 15)
        return 0;
    return "A\0B\0C\0D\0E\0";
}

int main(void)
{
    int i;
    char *p =  func2(0);

    for (i = 0; p[i] != '\0'; i += 2)
       printf("%c ", *(p + i));

    return 0;
}


Muchas gracias por toda la ayuda  ;-)

Saludos kutcher

Eternal Idol

La economía nunca ha sido libre: o la controla el Estado en beneficio del Pueblo o lo hacen los grandes consorcios en perjuicio de éste.
Juan Domingo Perón