INF1018 - Software Básico

Aulas de Laboratório

Representação de Dados na Memória (continuação)

Inteiros com e sem sinal

  1. 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;
    }
    
  2. 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?
    
  3. A linguagem C não especifica se o tipo char tem formato com ou sem sinal. Escreva um programa em C para descobrir como ele interpreta um char. A idéia básica é fazer algo que dê um determinado resultado se o char for interpretado como um número com sinal, e dê um resultado diferente se ele for interpretado sem sinal.

    Para conferir seu programa, teste-o com os tipos signed char e unsigned char e verifique se os resultados são efetivamente diferentes.

  4. Existem pelo menos duas maneiras "razoáveis" para a máquina converter um número do formato signed char para o formato unsigned int. Quais são elas?

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

  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?

  6. Escreva uma função que receba um número inteiro (int) e o imprima em binário, sempre com 32 bits. (Use os operadores bit-a-bit de C!) Experimente sua função com números negativos. Para cada número negativo que você testar, some-o com o seu complemento e veja o resultado.

Representação de structs

  1. Como os tipos abaixo são organizados na memória? Use a função dump (da aula passada) para conferir suas respostas. (A função dump deve ser usada apenas para conferência! Antes de usá-la escreva sua reposta.)
    1. struct X1 {
        char c1;
        int i;
        char c2;
      };
      
    2. struct X2 {
        int i;
        char c;
      };
      
    3. struct X3 {
        int i;
        char c1;
        char c2;
      };
      
    4. struct X4 {
        struct X2 x;
        char c;
      };
      
    5. struct X4_ {
        struct {
          int i;
          char c1;
        } x;
        char c;
      };
      
    6. struct X5 {
        char c1;
        char c2;
        char c3;
      };
      
    7. struct X6 {
        short s1;
        int i;
        char c[3];
        short s2;
        double d;
      };
      
    8. struct X6 {
        short s1;
        int i;
        char c[3];
        short s2;
      };
      
    9. union U1 {
        int i;
        char c[5];
      };
      
    10. union U2 {
        short s;
        char c[5];
      };