数据在计算机都是由基本的0、1二进制数表示的. 通过强制转换可以改变数字的类型,使得编译器对待同一地址处的数字会以不同的方式去存储和解释.了解一些底层的细节有助于发现和查找bug.
通过typedef 将unsigned char *类型定义为byte_pointer类型, 从而在后续的函数调用中, 通过强制类型转换, 使得编译器在面对int, float, void * 类型的数据时, 将它们统一视为unsigned char * 类型的数据. 从而可以通过遍历数据的每一个字节, 并且通过%.2x 将其以16进制数的形式展现出来.
不同的操作系统平台(linux , windows...)下show_int( ) 函数可能会得到不同的结果, 这是因为"大端", "小端"的区别导致的. 并且同样的平台下, 每次执行该段代码, show_pointer( )结果也不相同, 这是因为操作系统每次分配的内存地址不相同. 由于我是在64位linux机上测试的, 因此show_pointer( )返回的结果是16位的16进制数, 正好对应64位机器的寻址特点 .
通过sizeof函数可以更好实现跨平台, 这是因为同一类型的数据在不同的平台下占据的字节数是不同的.
#include <stdio.h>
typedef unsigned char *byte_pointer;
void show_bytes(byte_pointer start, int len){
int i;
for (i = 0; i < len; i++)
printf(" %.2x", 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 *));
}
void test_show_bytes(int val){
int ival = val;
float fval = (float) ival;
int *pval = &ival;
show_int(ival);
show_float(fval);
show_pointer(pval);
}
void main()
{
test_show_bytes(12345);
}
输出结果如下: 39 30 00 00 00 e4 40 46 e0 a6 43 6d ff 7f 00 00 |