show-bytes.c代码解释

    xiaoxiao2025-04-03  20

    代码功能

    展示了数据在内存中的形式及其所在地址,可以看出大小端模式,强制类型转换发生的溢出。

    代码分析

    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,正常输出 运行结果显示为小端模式。
    最新回复(0)