C語言 資料的位級表示及操作

RGBMarco發表於2018-01-13
#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));    
}

執行:

這裡寫圖片描述

相關文章