本章实验代码是为了解int、float以及指针类型的字节大小。并且通过对数值12345678与87654321的对比让大家能够了解到自己机器的大端小端存储方式。
/* show-bytes - prints byte representation of data */
/* $begin show-bytes */
#include
/* $end show-bytes */
#include
#include
/* $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;
double fval = 1;
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;
}
1.不带参数时运行结果如下(typedef unsigned char *byte_pointer时):
/*1.不带参数的运行结果
calling show_twocomp
0x7ffecafe81f4 0x39
0x7ffecafe81f5 0x30
0x7ffecafe81f6 0xc7
0x7ffecafe81f7 0xcf
Calling simple_show_a
0x7ffecafe81ec 0x21
0x7ffecafe81ec 0x21
0x7ffecafe81ed 0x43
0x7ffecafe81ec 0x21
0x7ffecafe81ed 0x43
0x7ffecafe81ee 0x65
Calling simple_show_b
0x7ffecafe81ec 0x78
0x7ffecafe81ec 0x78
0x7ffecafe81ed 0x56
0x7ffecafe81ec 0x78
0x7ffecafe81ed 0x56
0x7ffecafe81ee 0x34
Calling float_eg
For x = 3490593
0x7ffecafe81cc 0x21
0x7ffecafe81cd 0x43
0x7ffecafe81ce 0x35
0x7ffecafe81cf 0x00
0x7ffecafe81cc 0x84
0x7ffecafe81cd 0x0c
0x7ffecafe81ce 0x55
0x7ffecafe81cf 0x4a
For x = 3510593
0x7ffecafe81cc 0x41
0x7ffecafe81cd 0x91
0x7ffecafe81ce 0x35
0x7ffecafe81cf 0x00
0x7ffecafe81cc 0x04
0x7ffecafe81cd 0x45
0x7ffecafe81ce 0x56
0x7ffecafe81cf 0x4a
Calling string_ueg
0x55b808493d34 0x41
0x55b808493d35 0x42
0x55b808493d36 0x43
0x55b808493d37 0x44
0x55b808493d38 0x45
0x55b808493d39 0x46
Calling string_leg
0x55b808493d3b 0x61
0x55b808493d3c 0x62
0x55b808493d3d 0x63
0x55b808493d3e 0x64
0x55b808493d3f 0x65
0x55b808493d40 0x66
不带参数时会进行示例eg代码部分,此部分主要是对比float型及char指针型的数据进行字节测试;在show_a和show_b部分对机器内部存储方式进行了测试,据测试可知,本机为小端模式,如show_a中87654321则将低位字节21保存在低地址0x7ffecafe81ec中。
2.x=3000时,结果如下:
2.x=3000
calling test_show_bytes
Stack variable ival = 3000
(int)ival:
0x7fff3275689c 0xb8
0x7fff3275689d 0x0b
0x7fff3275689e 0x00
0x7fff3275689f 0x00
(float)ival:
0x7fff3275689c 0x00
0x7fff3275689d 0x80
0x7fff3275689e 0x3b
0x7fff3275689f 0x45
&ival:
0x7fff32756898 0xc4
0x7fff32756899 0x68
0x7fff3275689a 0x75
0x7fff3275689b 0x32
0x7fff3275689c 0xff
0x7fff3275689d 0x7f
0x7fff3275689e 0x00
0x7fff3275689f 0x00
此时代码测试内容为输入值3000的int、float以及指针型字节大小测试,由上可知int型占4个字节,float型4个字节,而指针类型占8个字节,注意,最后一段是指针所在地址而不是指针内容值!
3.x=-10000时,结果如下:
3.x=-10000
calling test_show_bytes
Stack variable ival = -10000
(int)ival:
0x7ffe23b829cc 0xf0
0x7ffe23b829cd 0xd8
0x7ffe23b829ce 0xff
0x7ffe23b829cf 0xff
(float)ival:
0x7ffe23b829cc 0x00
0x7ffe23b829cd 0x40
0x7ffe23b829ce 0x1c
0x7ffe23b829cf 0xc6
&ival:
0x7ffe23b829c8 0xf4
0x7ffe23b829c9 0x29
0x7ffe23b829ca 0xb8
0x7ffe23b829cb 0x23
0x7ffe23b829cc 0xfe
0x7ffe23b829cd 0x7f
0x7ffe23b829ce 0x00
0x7ffe23b829cf 0x00
该部分测试输入值为-10000,知负数与正数在字节大小上并无区别,。
4.x=3.14时,结果如下:
4.x=3.14
calling test_show_bytes
Stack variable ival = 3
(int)ival:
0x7ffe65fef77c 0x03
0x7ffe65fef77d 0x00
0x7ffe65fef77e 0x00
0x7ffe65fef77f 0x00
(float)ival:
0x7ffe65fef77c 0x00
0x7ffe65fef77d 0x00
0x7ffe65fef77e 0x40
0x7ffe65fef77f 0x40
&ival:
0x7ffe65fef778 0xa4
0x7ffe65fef779 0xf7
0x7ffe65fef77a 0xfe
0x7ffe65fef77b 0x65
0x7ffe65fef77c 0xfe
0x7ffe65fef77d 0x7f
0x7ffe65fef77e 0x00
0x7ffe65fef77f 0x00
当输入端为3.14时,因为最初的输入定义是int型,所以最开始在赋值时便将输入值舍为3,其余部分并无区别。
当我们将unsigned char型指针换成char型、int型指针时
typedef unsigned char *byte_pointer;
//typedef char *byte_pointer;
//typedef int *byte_pointer;
char型x=-10000时:
calling test_show_bytes
Stack variable ival = -10000
(int)ival:
0x7ffcb8dd92fc 0xfffffff0
0x7ffcb8dd92fd 0xffffffd8
0x7ffcb8dd92fe 0xffffffff
0x7ffcb8dd92ff 0xffffffff
(float)ival:
0x7ffcb8dd92fc 0x00
0x7ffcb8dd92fd 0x40
0x7ffcb8dd92fe 0x1c
0x7ffcb8dd92ff 0xffffffc6
&ival:
0x7ffcb8dd92f8 0x24
0x7ffcb8dd92f9 0xffffff93
0x7ffcb8dd92fa 0xffffffdd
0x7ffcb8dd92fb 0xffffffb8
0x7ffcb8dd92fc 0xfffffffc
0x7ffcb8dd92fd 0x7f
0x7ffcb8dd92fe 0x00
0x7ffcb8dd92ff 0x00
取负值时会自动向前扩充符号位,所以出现8位十六进制。下同。
int型x=-10000时:
calling test_show_bytes
Stack variable ival = -10000
(int)ival:
0x7ffd538ba42c 0xffffd8f0
0x7ffd538ba430 0x538ba470
0x7ffd538ba434 0x7ffd
0x7ffd538ba438 0xa843a90e
(float)ival:
0x7ffd538ba42c 0xc61c4000
0x7ffd538ba430 0x538ba470
0x7ffd538ba434 0x7ffd
0x7ffd538ba438 0xa843a924
&ival:
0x7ffd538ba428 0x538ba454
0x7ffd538ba42c 0x7ffd
0x7ffd538ba430 0x538ba470
0x7ffd538ba434 0x7ffd
0x7ffd538ba438 0xa843a93c
0x7ffd538ba43c 0x5606
0x7ffd538ba440 0xa843ad52
0x7ffd538ba444 0x5606