代码功能
展示了数据在内存中的形式及其所在地址,可以看出大小端模式,强制类型转换发生的溢出。
代码分析
typedef unsigned char *byte_pointer;
void show_bytes(byte_pointer start, size_t len)
{
size_t i;
for (i = 0; i < len; i++)
printf("%p\t0x%.2x\n", &start[i], start[i]);
printf("\n");
}
size-t全称为size type,可以计算数据的大小,通常使用的sizeof()的结果就可以被定义为size-t。%p输出start[i]所在地址,0x%.2x输出start[i]的值,都是以十六进制输出。show_bytes函数输出数据的值和其所在地址,本篇代码中的其他函数都在调用show_bytes函数。 例如
void show_int(int x) {
show_bytes((byte_pointer) &x, sizeof(int));
}
//输出int型数据
void show_float(float x) {
show_bytes((byte_pointer) &x, sizeof(float));
}//输出float型数据
void test_show_bytes(int val) {
int ival = val;
//float fval = (float) ival;
double fval = (double) ival;
int *pval = &ival;
printf("Stack variable ival = %d\n", ival);
printf("(int)ival:\n");
show_int(ival);
printf("(float)ival:\n");
show_float(fval);
printf("&ival:\n");
show_pointer(pval);
}//定义int型val,强制类型转换为float和double,在相应类型下输出值和所在地址。
void show_twocomp()
{
/* $begin show-twocomp */
short x = 12345;
short mx = -x;
show_bytes((byte_pointer) &x, sizeof(short));
show_bytes((byte_pointer) &mx, sizeof(short));
/* $end show-twocomp */
}//输出取反后的值和地址
完整代码
/* show-bytes - prints byte representation of data */
/* $begin show-bytes */
#include <stdio.h>
/* $end show-bytes */
#include <stdlib.h>
#include <string.h>
/* $begin show-bytes */
typedef unsigned char *byte_pointer;
//typedef char *byte_pointer;
//typedef int *byte_pointer;
void show_bytes(byte_pointer start, size_t len) {
size_t i;
for (i = 0; i < len; i++)
printf("%p\t0x%.2x\n", &start[i], start[i]);
printf("\n");
}
void show_int(int x) {
show_bytes((byte_pointer) &x, sizeof(int));
}
void show_float(float x) {
show_bytes((byte_pointer) &x, sizeof(float));
}
void show_pointer(void *x) {
show_bytes((byte_pointer) &x, sizeof(void *));
}
/* $end show-bytes */
/* $begin test-show-bytes */
void test_show_bytes(int val) {
int ival = val;
//float fval = (float) ival;
double fval = (double) ival;
int *pval = &ival;
printf("Stack variable ival = %d\n", ival);
printf("(int)ival:\n");
show_int(ival);
printf("(float)ival:\n");
show_float(fval);
printf("&ival:\n");
show_pointer(pval);
}
/* $end test-show-bytes */
void simple_show_a() {
/* $begin simple-show-a */
int val = 0x87654321;
byte_pointer valp = (byte_pointer) &val;
show_bytes(valp, 1); /* A. */
show_bytes(valp, 2); /* B. */
show_bytes(valp, 3); /* C. */
/* $end simple-show-a */
}
void simple_show_b() {
/* $begin simple-show-b */
int val = 0x12345678;
byte_pointer valp = (byte_pointer) &val;
show_bytes(valp, 1); /* A. */
show_bytes(valp, 2); /* B. */
show_bytes(valp, 3); /* C. */
/* $end simple-show-b */
}
void float_eg() {
int x = 3490593;
float f = (float) x;
printf("For x = %d\n", x);
show_int(x);
show_float(f);
x = 3510593;
f = (float) x;
printf("For x = %d\n", x);
show_int(x);
show_float(f);
}
void string_ueg() {
/* $begin show-ustring */
const char *s = "ABCDEF";
show_bytes((byte_pointer) s, strlen(s));
/* $end show-ustring */
}
void string_leg() {
/* $begin show-lstring */
const char *s = "abcdef";
show_bytes((byte_pointer) s, strlen(s));
/* $end show-lstring */
}
void show_twocomp()
{
/* $begin show-twocomp */
short x = 12345;
short mx = -x;
show_bytes((byte_pointer) &x, sizeof(short));
show_bytes((byte_pointer) &mx, sizeof(short));
/* $end show-twocomp */
}
int main(int argc, char *argv[])
{
int val = 12345;
if (argc > 1) {
val = strtol(argv[1], NULL, 0);
printf("calling test_show_bytes\n");
test_show_bytes(val);
} else {
printf("calling show_twocomp\n");
show_twocomp();
printf("Calling simple_show_a\n");
simple_show_a();
printf("Calling simple_show_b\n");
simple_show_b();
printf("Calling float_eg\n");
float_eg();
printf("Calling string_ueg\n");
string_ueg();
printf("Calling string_leg\n");
string_leg();
}
return 0;
}
测试结果
typedef unsigned char *byte_pointer
不带参数
calling show_twocomp
0x7fff0d0bb784 0x39
0x7fff0d0bb785 0x30
0x7fff0d0bb786 0xc7
0x7fff0d0bb787 0xcf
Calling simple_show_a
0x7fff0d0bb77c 0x21
0x7fff0d0bb77c 0x21
0x7fff0d0bb77d 0x43
0x7fff0d0bb77c 0x21
0x7fff0d0bb77d 0x43
0x7fff0d0bb77e 0x65
Calling simple_show_b
0x7fff0d0bb77c 0x78
0x7fff0d0bb77c 0x78
0x7fff0d0bb77d 0x56
0x7fff0d0bb77c 0x78
0x7fff0d0bb77d 0x56
0x7fff0d0bb77e 0x34
Calling float_eg
For x = 3490593
0x7fff0d0bb75c 0x21
0x7fff0d0bb75d 0x43
0x7fff0d0bb75e 0x35
0x7fff0d0bb75f 0x00
0x7fff0d0bb75c 0x84
0x7fff0d0bb75d 0x0c
0x7fff0d0bb75e 0x55
0x7fff0d0bb75f 0x4a
For x = 3510593
0x7fff0d0bb75c 0x41
0x7fff0d0bb75d 0x91
0x7fff0d0bb75e 0x35
0x7fff0d0bb75f 0x00
0x7fff0d0bb75c 0x04
0x7fff0d0bb75d 0x45
0x7fff0d0bb75e 0x56
0x7fff0d0bb75f 0x4a
Calling string_ueg
0x5651499bdd34 0x41
0x5651499bdd35 0x42
0x5651499bdd36 0x43
0x5651499bdd37 0x44
0x5651499bdd38 0x45
0x5651499bdd39 0x46
Calling string_leg
0x5651499bdd3b 0x61
0x5651499bdd3c 0x62
0x5651499bdd3d 0x63
0x5651499bdd3e 0x64
0x5651499bdd3f 0x65
0x5651499bdd40 0x66
参数为1073741824的结果
calling test_show_bytes
Stack variable ival = 1073741824
(int)ival:
0x7ffd6c013afc 0x00
0x7ffd6c013afd 0x00
0x7ffd6c013afe 0x00
0x7ffd6c013aff 0x40
(float)ival:
0x7ffd6c013afc 0x00
0x7ffd6c013afd 0x00
0x7ffd6c013afe 0x80
0x7ffd6c013aff 0x4e
&ival:
0x7ffd6c013af8 0x24
0x7ffd6c013af9 0x3b
0x7ffd6c013afa 0x01
0x7ffd6c013afb 0x6c
0x7ffd6c013afc 0xfd
0x7ffd6c013afd 0x7f
0x7ffd6c013afe 0x00
0x7ffd6c013aff 0x00
typedef char *byte_pointer
参数1073741824
calling test_show_bytes
Stack variable ival = 1073741824
(int)ival:
0x7ffeedc4183c 0x00
0x7ffeedc4183d 0x00
0x7ffeedc4183e 0x00
0x7ffeedc4183f 0x40
(float)ival:
0x7ffeedc4183c 0x00
0x7ffeedc4183d 0x00
0x7ffeedc4183e 0xffffff80
0x7ffeedc4183f 0x4e
&ival:
0x7ffeedc41838 0x64
0x7ffeedc41839 0x18
0x7ffeedc4183a 0xffffffc4
0x7ffeedc4183b 0xffffffed
0x7ffeedc4183c 0xfffffffe
0x7ffeedc4183d 0x7f
0x7ffeedc4183e 0x00
0x7ffeedc4183f 0x00
typedef int *byte_pointer
参数为1073741824的结果
calling test_show_bytes
Stack variable ival = 1073741824
(int)ival:
0x7fff6e211c3c 0x40000000
0x7fff6e211c40 0x6e211c80
0x7fff6e211c44 0x7fff
0x7fff6e211c48 0xaab2090e
(float)ival:
0x7fff6e211c3c 0x4e800000
0x7fff6e211c40 0x6e211c80
0x7fff6e211c44 0x7fff
0x7fff6e211c48 0xaab20924
&ival:
0x7fff6e211c38 0x6e211c64
0x7fff6e211c3c 0x7fff
0x7fff6e211c40 0x6e211c80
0x7fff6e211c44 0x7fff
0x7fff6e211c48 0xaab2093c
0x7fff6e211c4c 0x55ec
0x7fff6e211c50 0xaab20d52
0x7fff6e211c54 0x55ec
测试结果解释
typedef unsigned char *byte_pointer,被定义为char型,每次读取一个字节
Stack variable ival = 1073741824
(int)ival:
0x7ffeedc4183c 0x00
0x7ffeedc4183d 0x00
0x7ffeedc4183e 0x00
0x7ffeedc4183f 0x40
//00<127,40<127,都在范围内
0x7ffeedc4183c 0x00
0x7ffeedc4183d 0x00
0x7ffeedc4183e 0xffffff80
0x7ffeedc4183f 0x4e
//而80转换为十进制大于127,超出了char的范围,会出现补充符号位的现象,符号位为1。
typedef int *byte_pointer,被定义为int ,每次读取四个字节
0x7fff6e211c3c 0x40000000
//00<2147483647,40<2147483647,输出正常
0x7fff6e211c3c 0x4e800000
//00<2147483647,80<2147483647,4e<2147483647,正常输出
运行结果显示为小端模式。