Consultas, desarrollo de programas y petición de presupuestos:

jueves, 12 de julio de 2012

Analisis de argumentos 2: << ( desplazamiento binario) y enmascaramiento binario

Programa: Para analizar los argumentos y que diga cuales son validos siendo los validos la secuencia de la a-f.


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

int procesarArgumentos(int, char **);
// procesa todos los argumentos que reciba, y devuelve un numero
// positivo= la suma de los valores de los argumentos
// negativo =hay argumentos pero no son validos
// cero= no hay ningun argumento

int argumento(char *); // procesa   cada argumento de forma

int esArgumento(char *); // comprueba que es un argumento

int main(int argc, char **argv) {
    int resul;

    resul = procesarArgumentos(argc, argv);

    if (resul > 0) { //
        if (resul & 1) { // Enmascaramiento Binario: pregunto por los numero &(=y logico a nivel de bits). (no es lo mismo que  &&) posicion 1, vease final
            printf("Usado argumento \"a\"\n");
        }
        if (resul & 2) {
            printf("Usado argumento \"b\"\n");
        }
        if (resul & 4) {
            printf("Usado argumento \"c\"\n");
        }
        if (resul & 8) {
            printf("Usado argumento \"d\"\n");
        }
        if (resul & 16) {
            printf("Usado argumento \"e\"\n");
        }
        if (resul & 32) {
            printf("Usado argumento \"f\"\n");
        }
    }
    return 0;
}

// Procesa la lista de argumentos.
// Devuelve un nº positivo indicando la suma de los argumentos empleados
// Negativo si alguna letra no es válida

int procesarArgumentos(int argc, char **argv) {
    char usados[100] = "";
    int c = 0;
    int suma = 0;
    char *argu; // para procesar la lista de argumentos
   
    int valor;
    char *posUsados;
// para buscar en la tabla de usados
// el argumento 0 no lo proceso ya que  es el nombre del programa, y empieza por el c=1
    for (c = 1; c < argc; c++) {
        argu = argv[c];
       
       
        if(esArgumento(argu)) {
        //sumo al puntero 1 posicion, me desplazo a la derecha una posicion
        //(salto al signo menos que no me interesa analizar ahora dentro de la cadena)
       
            argu++;

            //*argu=conenido a lo que apuntaba argu: la letra "a" en asci no vale cero,
            // por lo tanto cumple la condicion de que sea distinto de cero
            // cuando encuentre \0, el valor numerico es 0, con lo cual parará el while.
            while (*argu) {
                valor = argumento(argu);
               
                // 0 es cuando no tenga signo menos, y negativo cuendo no lo encuentra en la tabla
                if (valor > 0) {
                    posUsados = strchr(usados, *argu);
                    // si el usuario pone varias veces el mismo argumento, solo lo cuenta una vez
                   
                    //si no lo he encontrado lo meto en la tabla
                    if (posUsados == NULL) {
                        usados[strlen(usados)] = *argu;
                    } else {
                        // si la he encontrado, es porque ha repetido el valor
                        valor = 0;
                    }
                }
                // calculo la suma de todos los arguemntos
                suma += valor;
                //me desplazo al siguiente argumento
                argu++;
            }
        }
    }
    return suma;
}

// Procesa un argumento de forma individual
// Devuelve INT_MIN si no es válido y positivo si lo es (2 ^ posicion)


int argumento(char *argu) {

// los argumentos validos van a ser: a,b,c,d,e,f
 
  char valen[] = { "abcdef" };
      
         // tabla sin tamaño definido([]), el compilador cuenta los elementos "abcdef",
         // y lo dimensiona automaticamente, tambien valdria: char valen[6]={ "abcdef" }
   
    char *pos;
    int dif; // es la diferencia....

    if ((pos = strchr(valen, *argu[0]))) {
               // la asignación pos=strchr. La función strchr te busca un caracter en una cadena:
               // si lo encuentra lo que hace es que pos apunte al caracter,
               // y la expresion (pos=strchr(valen, *argu[0])) la evalua el if.
               // si strchr() devuelve una posicion, pos = esa posicion, con lo cual es correcto(verdadero)
               // si strchr() no devuelve nada (NULL), no lo ha encontrado, pos=NULL, con lo cual el falso
                                          
      dif = (pos - valen); // se pueden hacer operaciones aritmeticas con los puntero,
                                    // se estan restando las posiciones.
                                    // por ejemplo si pos marcaria 12034, y si valen marcaria 12035, dif=1
       
        return (1 << dif); // << operador binario que trabaja con bits, y hace desplazamiento a la izquierda
    } else {
        return INT_MIN; //
    }
}

int esArgumento(char *argu) {
// en el puntero *argu, (guarda la posicion donde esta apuntando)
//...y nos puede mostrar  el contenido a donde apunta:

    if (*argu == '-') {
       // si el primer carater es '-' es un argumento.
        return 1; // verdadero
    }
    return 0; // falso
}



Operador <<: Desplaza un bit
Por ejemplo 1<<dif, siendo dif=0,
devuelve 1
   128 64 32 16 8 4 2 1
   0 0 0 0 0 0 0 1


Por ejmplo 1<<dif, siendo dif=1, se desplaza hacia la izquierda 1 posicion:

   12864 32 16 8 4 21
   0 0 0 0 0 0 1 0

Analisis de distintas posiciones: Enmacarasmiento BinarioEnmascaramiento de bits consiste en combinar un valor binario con otro para aislar los bits que nos interesan.

No hay comentarios:

Publicar un comentario