A rotina abaixo faz um "dump" de uma região de memória:
#include <stdio.h> void dump (void *p, int n) { unsigned char *p1 = p; while (n--) { printf("%p - %02x\n", p1, *p1); p1++; } }O dump mostra uma sequência de posições da memória, mostrando para cada posição seu endereço e seu conteúdo (em hexa-decimal). O parâmetro
p
é o endereço inicial a ser mostrado,
e n
é o número de bytes.
Um exemplo de uso é o programa abaixo, que mostra como um inteiro é armazenado na memória:
int main (void) { int i = 10000; dump(&i, sizeof(i)); return 0; }
Explique detalhadamente o resultado do programa acima (se necessário,
rode o programa com outros valores para i
).
Aplique a mesma técnica para ver como um char
é armazenado.
Aplique a mesma técnica para ver como um short
é armazenado.
A mesma técnica pode ser usada para vermos como uma string é armazenada:
int main (void) { char p[] = "7509"; dump(p, sizeof(p)); return 0; }Modifique o exemplo acima para descobrir os códigos ASCII dos caracteres
'a'
,
' '
,
'\0'
,
e '$'
.
Aplique a mesma técnica para ver como um array de inteiros é armazenado.
Como você acha que o array abaixo é armazenado?
short a[3][2];(inicialize seu array com um loop como:
for (i=0;i<3;i++) for (j=0;j<2;j++) a[i][j] = 1+i-j;e veja o que a dump mostra)
Use a função dump
para ver como a estrutura abaixo é armazenada:
struct X { int a; int b; short s; int i; } x;(Sim, existe um "buraco". Você sabe explicá-lo?)
Considere a função abaixo, para multiplicar dos números inteiros:
int mul (int a, int b) { int p = 0; while (b) { if (b%2 == 1) p += a; a *= 2; b /= 2; } return p; }Na forma apresentada acima, a função
mul
não faz
muito sentido,
pois usamos várias multiplicações e divisões para simular uma
única multiplicação.
Entretanto, como essas operações são todas com 2,
podemos substituí-las por operadores bit-a-bit,
que são bem mais eficientes.
Reescreva a função mul
de modo que ela não use nenhuma
operação "complicada"
(*
, /
ou %
).