C言語 型の意味

型付きプログラム言語における変数の型の機能検証コード。型はメモリ上で変数がしめるサイズと属性を表す。CPUは属性によって同じビットイメージでもその解釈を変える。

/* 0x86 32bit系CPU向けコード */
/* intが32bit, 1バイト8bit LittleEndianが前提 */

#include <stdio.h>
#include <limits.h>

#define INTSIZE_BY_4BIT (sizeof(int) * CHAR_BIT / 4)
#define HORIZONE printf("------------------------------\n")
#define GET_ARRAY_NUM(array) ((sizeof(array)) / (sizeof(array[0])))


/* pArgからsize分のデータをfpにダンプする */
void dumpBuffer(void *pArg, unsigned size)
{
    char *p = pArg;
    int i;
    int lCnt;

    lCnt = 0;
    for (i = 0; i < size; i++) {
        printf(" %2x", 0xff & *p);
        p++;
        lCnt++;
        if (lCnt >= 16) {
            printf("\n");
            lCnt = 0;
        }
    }
    putchar('\n');

    return;
}

/* int変数のビットイメージを表示 */
/* bitイメージとともに4bit毎に16進数表記 */
void dumpIntBit(int x)
{
    int i;
    int tmp;

    /* Bitイメージ表示 */
    for (i = sizeof(x) * CHAR_BIT - 1; 0 <= i; i--) {
        tmp = x >> i;
        printf("%d", tmp & 0x1);
        /* 4ビットごとに区切り */
        if ((i & 0x3) == 0) {
            putchar(' ');
        }
    }
    putchar('\n');
    
    /* 4bit単位で16進表記。Little Endianなので逆から表示 */
    tmp = x;
    for (i = INTSIZE_BY_4BIT - 1; 0 <= i; i--) {
        printf("%4x ", (0xf0000000 & tmp) >> 28);
        tmp <<= 4;
    }
    putchar('\n');
    
    return;
}

/* intと同サイズのchar配列、short配列メンバをもつ共用体 */
typedef union {
    char ch[sizeof(int)];
    short sh[sizeof(int) / sizeof(short)];
    int i;
} U_Hoge;

/* 符号有10進表記, 符号無10進表記,16進表記用マクロ */
#define PRINT_BYTE(BYTE) printf(" %d(%02u:%#02x)", \
    (BYTE), (0xff & (BYTE)), (0xff & (BYTE)))

#define PRINT_SHORT(SHORT) printf(" %d(%04u:%#04x)", \
    (SHORT), (0xffff & (SHORT)), (0xffff & SHORT))

#define PRINT_INT(INT) printf(" %d(%08u:%#08x)", \
    (INT), (INT), (INT))

void dispUnion(U_Hoge *p)
{
    int i;

    /* char配列表示 */
    printf("Display as char:\n");
    for (i = 0; i < GET_ARRAY_NUM(p->ch); i++) {
        PRINT_BYTE(p->ch[i]);
    }
    putchar('\n');

    /* short配列表示 */
    printf("Display as short:\n");
    for (i = 0; i < GET_ARRAY_NUM(p->sh); i++) {
        PRINT_SHORT(p->sh[i]);
    }
    putchar('\n');

    /* int 表示 */
    printf("Display as int:\n");
    PRINT_INT(p->i);
    putchar('\n');

    return;
}

int main(void)
{
    U_Hoge hoge;

    hoge.i = 0xdeadbeef;
    dumpIntBit(hoge.i);
    dispUnion(&hoge);
    HORIZONE;

    hoge.sh[0] = -1;
    hoge.sh[1] = 1;
    dumpIntBit(hoge.i);
    dispUnion(&hoge);
    HORIZONE;

    return 0;
}