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("\n");
}

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语言基础的应该都能看懂,因此在看懂函数后,我第一时间想本身实现一下,实现代码以下:.net

#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("\n");
}

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类型的数字code

int main(void)
{
    int x=1;
    show_int(x);
}

VS2017运行结果为:
TIM截图20191119161542.png
看上去是没什么问题的。因而我又试了一下浮点数的表示:blog

int main(void)
{
    float x = 1.0f;
    show_float(x);
}

VS2017运行结果为:
TIM截图20191119162023.png
输出了14个十六进制数字,多输出了6个十六进制数,即3个字节。
这三个字节是怎么来的呢?
经过对比发现我写的函数与书中的函数一个不一样,书中的byte_pointerunsigned char*,而个人是char*
这有什么问题呢,charunsigned char都是一个字节,八位二进制,两位十六进制,为何会发生多输出三个字节的状况呢。
经过查阅,我发现问题正出在charunsigned char中:c语言中 char* 和 unsigned char* 的区别浅析
具体缘由是这样的:
C语言中虽然没有具体说明char有无符号,可是大多数机器上char都是有符号的,而printf中格式输出%.2x的过程为:先把char类型转换为int类型,而后再把int类型转换为二进制。这就涉及到了位的扩展,而有符号数的位扩展所遵循的是--‘符号扩展’具体见个人新博客~。
因此在扩展时,若是char类型的位模式中第一位是1的话,扩展为int类型,须要在前面加三个字节24位的1,printf时实际精度超过了.2x,天然就在这个字节的前面加了六个f。get

相关文章
相关标签/搜索