【CSAPP第二章show_bytes函数的探究】花门楼前见秋草,岂能贫贱相看老。这篇文章主要讲述CSAPP第二章show_bytes函数的探究相关的知识,希望能为你提供帮助。
CSAPP第二章中给出了一个帮助我们观察数据的位模式的函数--show_bytes函数,具体实现如下:
#include<
stdio.h>
typedef unsigned char *byte_pointer;
void show_bytes(byte_pointer start, size_t len)
{
size_t i;
for (i = 0;
i <
len;
i++)
{
printf("
%.2x"
, start[i]);
}
printf("
"
);
}void show_int(int x)
{
show_bytes((byte_pointer)&
x, sizeof(int));
}void show_double(double x)
{
show_bytes((byte_pointer)&
x, sizeof(double));
}void show_float(float x)
{
show_bytes((byte_pointer)&
x, sizeof(float));
}
函数是不难懂的,只要有C语言基础的应该都能看懂,所以在看懂函数后,我第一时间想自己实现一下,实现代码如下:
#include<
stdio.h>
typedef char *byte_pointer;
void show_bytes(byte_pointer start, size_t len)
{
for (int i = 0;
i <
len;
i++)
{
printf("
%.2x"
, start[i]);
}
printf("
"
);
}void show_int(int x)
{
show_bytes((byte_pointer)&
x, sizeof(int));
}void show_double(double x)
{
show_bytes((byte_pointer)&
x, sizeof(double));
}void show_float(float x)
{
show_bytes((byte_pointer)&
x, sizeof(float));
}
写完后我立刻尝试跑了一下一个int类型的数字
int main(void)
{
int x=1;
show_int(x);
}
VS2017运行结果为:
文章图片
看上去是没什么问题的。于是我又试了一下浮点数的表示:
int main(void)
{
float x = 1.0f;
show_float(x);
}
VS2017运行结果为:
文章图片
输出了14个十六进制数字,多输出了6个十六进制数,即3个字节。
这三个字节是怎么来的呢?
通过对比发现我写的函数与书中的函数一个不同,书中的
byte_pointer
是unsigned char*
,而我的是char*
。这有什么问题呢,
char
与unsigned char
都是一个字节,八位二进制,两位十六进制,为什么会发生多输出三个字节的情况呢。通过查阅,我发现问题正出在
char
与unsigned char
中:c语言中 char* 和 unsigned char* 的区别浅析。具体原因是这样的:
C语言中虽然没有具体说明char有无符号,但是大多数机器上char都是有符号的,而printf中格式输出%.2x的过程为:先把char类型转换为int类型,然后再把int类型转换为二进制。这就涉及到了位的扩展,而有符号数的位扩展所遵循的是--‘符号扩展’具体见我的新博客~。
所以在扩展时,如果char类型的位模式中第一位是1的话,扩展为int类型,需要在前面加三个字节24位的1,printf时实际精度超过了.2x,自然就在这个字节的前面加了六个f。
推荐阅读
- spring中的ApplicationListener监听器
- Spring----事件(Application Event)
- mybatis配置约束config,mapper
- iPad2与iPad3的区别 选择哪一个好?
- 手机处理器:A8与A9架构CPU的差别在啥地方里?
- 笔记本光驱自动弹出处理办法大全
- 人人桌面 for Mac客户端怎样才能用上?
- 教你装磁盘阵列图文详细教程:组建RAID需要几块硬盘
- U盘坏了怎样办 要怎样修好U盘?