char unsigned char %d %u

前幾天遇到了這麼個問題 ,在學習 unsigned char和char 和signed char的區別時 ,說char的類型到底是signed 還是unsigned 取決於編譯器 。

當時寫了一串代碼 如下:

char a=-1;
    printf("%d\n",sizeof(a));
    printf("%d\n",a);
    printf("%u\n",a);

wKiom1Q9MVPwoAU0AAAg9woIWUE769.jpg

先說%d 是將數據以int型的 十進制 格式輸出;

    %u 是將數據以unsigned int 的十進制格式輸出;

那麼爲何會輸出 4294967295呢? 再怎麼理解 char 類型也只是佔用了 一個字節  ,而這個結果分明是4個字節的最大整數啊!

爲此當時還特意查看了 內存狀況  如下:

wKioL1Q9Mr6z1YtWAABSyekhf2U060.jpg


wKiom1Q9MonQ1276AACigK7RXg8822.jpg

查詢了一下 cc在內存中表示的是 隨機數 。

這就讓我更難理解了:爲何會輸出一個 四個字節的最大int整數?


當時我百度的是 %d和%u的區別 ,,後來我知道 我的方向錯了,,導致這個結果的原因是

printf 函數對於 unsigned 和signed char的區別。


1、printf中採用%d的格式輸出  就是講元素的內存塊 以有符號的形式讀出來,如char a=-1;

內存中就是 0xff ,這個數字用有符號的讀出來 顯示的就是 -1(原碼,反碼,補碼的關係有講)


而printf用%u的格式時 ,若被讀的數是unsigned 類型,則不會有 “字符擴張”,若是signed 類型的(char short int long)都會有字符的擴展,而這個擴展在內存中是查看不到的,擴展成四個字節的數據, 具體如下:

    若要讀的數據 小於0,在內存中 符號位是1,擴展的時候,不足32位的都要在前面擴展出來的位補1(因爲最前面是1,類似於<< >>左移右移時的方法),這個擴展出來的數 再以無符號int型十進制讀。例如本例的-1 ,內存中是0xff ,擴展之後的就是0xff ff ff ff  這樣再讀就是4294967295了。

而如果是 1的話 內存中是0x01 (最前面是0) 所以擴展出來的也是0,即0x00 00 00 01,再讀出來也是1.

#include<stdio.h>
int main()
{
    
    char c1=1,c2=-1;
    printf("%d\n",c1);
    printf("%d\n",c2);
    printf("%u\n",c1);
    printf("%u\n",c2);
    printf("#####################\n");
    long l1=1,l2=-1;
    printf("%d\n",l1);
    printf("%d\n",l2);
    printf("%u\n",l1);
    printf("%u\n",l2);
    printf("#####################\n");
    unsigned char c3=1,c4=-1;
    printf("%d\n",c3);
    printf("%d\n",c4);
    printf("%u\n",c3);
    printf("%u\n",c4);
    printf("#####################\n");
    unsigned long l3=1,l4=-1;
    printf("%d\n",sizeof(l4));
    printf("%d\n",l3);
    printf("%d\n",l4);
    printf("%u\n",l3);
    printf("%u\n",l4);
    return 0;
}

運行結果:

wKiom1Q9OiOQ-TSWAACc6Ig0n9s972.jpg

注:最後的unsigned long l4=-1;在以%u輸出的時候,結果也是4294967295,但是卻並不是字符擴展的結果,因爲它本來就佔了4個字節,在內存中爲0xFF FF FF FF,所以輸出像是也進行了字符擴展一樣。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章