C语言 数据的位级表示及操作

#include <stdio.h>
#include <stdint.h>
#include <stdbool.h>

typedef unsigned char* byte_pointer;
/*表示:  高位->低位(和机器采用大端法和小端法有关) 本例机器采用小端法表示数据*/
void show_bytes(byte_pointer word,size_t len) {
    printf("0x");
    for (int i = len - 1; i >= 0; --i) {
        printf("%.2x",word[i]);
    }
    printf("\n");
}

void show_bits(byte_pointer word,size_t len) {
    for (int i = len - 1; i >= 0; --i) {
        unsigned int byte = word[i];
        unsigned int mask = 128;
        for (int j = 0; j < 8; ++j) {
            if (j % 8 == 0)
                printf("[");
            bool flag = byte & (mask >> j);
            if (flag)
                printf("1");
            else
                printf("0");
            if ((j + 1) % 8 == 0)
                printf("]   ");
        }
    }
    printf("\n");
}

int main() {
    int32_t a = 12345;
    printf("signed a 12345:\n");
    show_bytes((byte_pointer)&a,sizeof(int32_t));
    show_bits((byte_pointer)&a,sizeof(int32_t));

    uint32_t ua = 12345;
    printf("unsigned int a 12345:\n");
    show_bytes((byte_pointer)&ua,sizeof(uint32_t));
    show_bits((byte_pointer)&ua,sizeof(uint32_t));

    int32_t negative_a = -12345;
    printf("negative a -12345:\n");
    show_bytes((byte_pointer)&negative_a,sizeof(int32_t));
    show_bits((byte_pointer)&negative_a,sizeof(int32_t));

    /*          left                                */
    printf("a << 3 %d\n",a << 3);
    int32_t la = a << 3;
    show_bytes((byte_pointer)&la,sizeof(int32_t));
    show_bits((byte_pointer)&la,sizeof(int32_t));

    printf("ua << 3 %u\n",ua << 3);
    uint32_t lua = ua << 3;
    show_bytes((byte_pointer)&lua,sizeof(uint32_t));
    show_bits((byte_pointer)&lua,sizeof(uint32_t));

    printf("negative a << 3 %d\n",negative_a << 3);
    int32_t negative_la = negative_a << 3;
    show_bytes((byte_pointer)&negative_la,sizeof(int32_t));
    show_bits((byte_pointer)&negative_la,sizeof(int32_t));
    /*-----------------------------------------------------*/

    /*          right               */
    printf("a >> 3 %d\n",a >> 3);
    int32_t ra = a >> 3;
    show_bytes((byte_pointer)&ra,sizeof(int32_t));
    show_bits((byte_pointer)&ra,sizeof(int32_t));

    printf("ua >> 3 %u\n",ua >> 3);
    uint32_t rua = ua >> 3;
    show_bytes((byte_pointer)&rua,sizeof(uint32_t));
    show_bits((byte_pointer)&rua,sizeof(uint32_t));

    printf("negative a >> 3 %d\n",negative_a  >> 3);
    int32_t negative_ra = negative_a >> 3;
    show_bytes((byte_pointer)&negative_ra,sizeof(int32_t));
    show_bits((byte_pointer)&negative_ra,sizeof(int32_t));
    /*-----------------------------------------------------*/
    /*******************************************************
    为何数据右移分逻辑右移和算术右移而左移只有逻辑左移
    由下例可知c语言左右移是为了得到乘除的效果,而大部分逻辑右移并不能直接得到   正确结果,故出现算数右移能解决这一问题,逻辑左移其实能满足这一要求,而下例       出现的反常情况,其实是溢出导致的
    *******************************************************/
    int32_t c = 1 << 31;
    printf("c: %d\n",c);
    show_bytes((byte_pointer)&c,sizeof(int32_t));
    show_bits((byte_pointer)&c,sizeof(int32_t));
    printf("c << 1 %d\n",c << 1);
    c = c << 1;
    show_bytes((byte_pointer)&c,sizeof(int32_t));
    show_bits((byte_pointer)&c,sizeof(int32_t));    
}

运行:

这里写图片描述


版权声明:本文为RGBMarco原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。