INF1018 - Software Básico

Aulas de Laboratório

Laboratório 4 - Inteiros com e sem sinal

  1. Considere o programa a seguir:
    #include <stdio.h>
    
    void dump (void *p, int n) {
      unsigned char *p1 = p;
      while (n--) {
        printf("%p - %02x\n", p1, *p1);
        p1++;
      }
    }
    
    int main (void) {
      char c = 254;
      short s = -3;
      int i = -129;
      printf("dump de c: \n");
      dump(&c, sizeof(c));
      printf("dump de s: \n");
      dump(&s, sizeof(s));
      printf("dump de i: \n");
      dump(&i, sizeof(i));
      return 0;
    }
    
    Analisando o programa e sem executá-lo, faça contas para determinar o que será impresso por ele. Só depois de determinar todos os valores, execute o programa e verifique se você acertou. Explique os valores impressos.

  2. O operador ~ de C inverte cada bit de um valor. Considere o seguinte programa:
    int main (void) {
      short a = 4;
      printf("a = %d\n", a); 
      a = ~a;
      printf("a = %d\n", a); 
      a += 1;
      printf("a = %d\n", a); 
      return 0;
    }
    
    Novamente analise o programa e diga o que será impresso antes de executá-lo. Depois execute o programa para conferir suas respostas. Explique os valores impressos.

  3. Execute o programa abaixo e explique o resultado.
    #include <stdio.h>
    
    void dump (void *p, int n) {
      unsigned char *p1 = p;
      while (n--) {
        printf("%p - %02x\n", p1, *p1);
        p1++;
      }
    }
    
    int main (void) {
      short l = -32765;
      unsigned short k = 32771;
      printf("l=%d, k=%u \n", l, k);
      printf("dump de l: \n");
      dump(&l, sizeof(l));
      printf("dump de k: \n");
      dump(&k, sizeof(k));
      return 0;
    }
    
    Troque a linha
     printf("l=%d, k=%u \n", l, k);
    
    por:
     printf("l=%u, k=%d \n", l, k);
    
    e explique o que está acontecendo.

  4. Execute o programa abaixo e explique seu resultado.

    #include <stdio.h>
    
    int main (void) {
      int x = -1;
      unsigned int y = 2;
      printf("x=%d, y=%d\n", x, y);
      printf("x é menor do que y? %s\n", (x<y)?"sim":"nao");
      return 0;
    }
    

    E se em vez de int usarmos short, o que acontece? Você sabe explicar essa diferença?

  5. Para números sem sinal a operação de "shift right" (>>) corresponde a uma divisão por dois. Essa correspondência continua existindo para números no formato complemento a dois? (Dica: pense no valor que entra no bit mais significativo quando o shift é feito.)

    Faça um programa em C para verificar como ele faz o "shift right". O resultado de i >> 1 pode depender da variável i ser com ou sem sinal?

    Dica: experimente com valores com e sem sinal, mostre antes e depois do shift...

  6. Em C, o programador pode atribuir um signed char, que ocupa 8 bits, a um unsigned int, que ocupa 32 bits. Há duas formas possíveis do compilador fazer a expansão. (O caso duvidoso é aquele em que o caracter tem um valor negativo.) Quais são elas?

  7. Escreva um programa em C para descobrir como ele faz essa conversão.