#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 = 150; short s = -3; int i = -151; 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; }
#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; }>
Imagine que, para economizar espaço de armazenamento, utilizemos uma estrutura de dados que "empacota" quatro valores inteiros com sinal, de 1 byte cada, em um inteiro unsigned de 32 bits. Os bytes dentro desse inteiro são numerados, da direita para a esquerda, de 0 (byte menos significativo) a 3 (byte mais significativo), conforme mostrado a seguir:
BITS: | 31-24 | 23-16 | 15-8 | 7-0 |
---|---|---|---|---|
byte 3 | byte 2 | byte 1 | byte 0 |
Sua tarefa é implementar uma função com o protótipo abaixo:
typedef unsigned packed_t;
/* extrai byte indicado e retorna valor inteiro correspondente (32 bits) com sinal */
int xbyte (packed_t word, int bytenum);
Use seus conhecimentos de aritmética de complemento a 2 e
operações de manipulação de bits para
implementar essa função.
Teste-a com o programa abaixo (leia o enunciado até o final
antes de começar a tarefa!)
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
typedef unsigned packed_t;
int string2num (char *s, int base) {
int a = 0;
for (; *s; s++) {
if(isdigit(*s))
a = a*base + (*s - '0');
else if((*s >= 'A') && (*s < (base-10+'A')))
a = a*base + ((*s - 'A') + 10);
else if((*s >= 'a') && (*s < (base-10+'a')))
a = a*base + ((*s - 'a') + 10);
else {
printf("pane: numero invalido! \n");
exit(1);
}
}
return a;
}
int xbyte (packed_t word, int bytenum) {
/* implementar!!! */
return 1;
}
int main (int argc, char **argv) {
int x;
if (argc != 3) {
printf ("uso: %s <word (em hexadecimal)> <bytenum>\n", argv[0]);
exit(1);
}
x = xbyte(string2num(argv[1], 16), atoi(argv[2]));
printf ("%08x %d\n", x, x);
return 0;
}
Para entender como deve funcionar o programa depois que você implementar
a função xbyte, veja os exemplos abaixo:
ana@sol:~/sb$ ./xbyte 01abcd02 0
00000002 2
ana@sol:~/sb$ ./xbyte 11a032b5 0
ffffffb5 -75
ana@sol:~/sb$ ./xbyte 11a032b5 1
00000032 50
ana@sol:~/sb$ ./xbyte 11a032b5 2
ffffffa0 -96
ana@sol:~/sb$ ./xbyte 11a032b5 3
00000011 17
ana@sol:~/sb$ ./xbyte abcd 3
00000000 0
ana@sol:~/sb$ ./xbyte abcd 1
ffffffab -85
ana@sol:~/sb$ ./xbyte zzzz 1
pane: numero invalido!
Execute os programas abaixo (separadamente!) e explique os resultados (pense na representação interna
dos valores de x e y e na declaração de seus tipos).
/* programa 1*/
#include <stdio.h>
int main (void) {
int x = 0xffffffff;
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;
}
/* programa 2*/
#include <stdio.h>
int main (void) {
unsigned int x = 0xffffffff;
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;
}
dica: Experimente trocar o "%d" por "%u" na string passada para printf e veja o que
os programas imprimem.
Agora execute o programa como abaixo e explique o resultados
comparando com os casos anteriores
/* programa 3*/
#include <stdio.h>
int main (void) {
int x = 0xffffffff;
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;
}
Em C, o programador pode atribuir um signed char
,
que ocupa 8 bits,
a um unsigned int
, que ocupa 32 bits:
signed char sc = -1;
unsigned int ui = sc;
Ao atribuir um valor a ui
, o que o código gerado tem que
fazer?
Observe que há duas mudanças, de tamanho e de tipo (o tipo, nesse
caso, é importante para saber como fazer a mudança de tamanho).
Faça a conversão na mão e diga como ficará a representação
interna de ui
.
Em seguida, escreva um programa em C para conferir sua resposta.
(Escreva as linhas acima e depois chame dump para ui).