C語言訪問資料物件在記憶體中真實位模式的一個方法

發表於2023-05-19

在判定機器採用大端還是小端儲存時,可以按位元組輸出某資料物件的機器表示的位模式。機器表示的位模式即某資料物件在記憶體中的二進位制串。下面是一個訪問資料物件位模式的方法:

//傳入一個資料物件,從低地址到高地址按位元組輸出這個物件的每位元組的十六進位制表示
void printByte(unsigned char* a,int n)
{
    for( int i=0; i<n; i++ ) {
        printf("%x ",a[i]);
    }
    printf("\n");
}

上面的printByte函式的功能是:以引數*a傳入一個資料物件的地址,以及你想列印的以這個地址為起始地址的連續的位元組數量n,printByte列印出這連續的n個位元組記憶體的位模式的十六進位制表示。我們使用了一個unsigned char* 型別的指標變數,它以一位元組大小解讀所指向的資料,並以"%x"格式輸出這個一位元組大小的資料。

我們定義一個int變數並列印它的位模式:

int x = 128;
printByte((unsigned char*)&x,sizeof(int))

可以看到輸出為:

上面的輸出也表示,這裡實驗的機器使用小端儲存,即資料物件的低位部分儲存在低地址部分。

在printByte函式中,需要注意:char* 型的指標指向的同樣是一位元組大小的資料,但此處一定要用unsigned char* 型別,而不能用char* 型別。因為"%x"是以十六進位制形式輸出int型的變數,所以,如果printByte的引數設定為char* 型別,在使用%x輸出時,會將char型別隱式轉換為int型別。此時,在上面的例子中,x值為128,其低8位的位模式為:1000 0000,即0x80,對於char型變數,其真值為-128。轉換成int型變數後,位模式為:1111 1111 1111 1111 1111 1111 1000 0000 (補碼編碼),即0xffffff80:

void printByte(char* a,int n)
{
    for( int i=0; i<n; i++ ) {
        printf("%x ",a[i]);
    }
    printf("\n");
}

int main()
{
    int x = 128;
    printByte((char*)&x,sizeof(int));
    return 0;
}

輸出結果為:

 所以,在這個方法列印記憶體的位模式時,引數指標一定是unsigned char* 型別,而不能是char*型別。

 

相關文章