1. 程式人生 > >C語言——printf列印字串(關於資料在記憶體中儲存格式的體現)

C語言——printf列印字串(關於資料在記憶體中儲存格式的體現)

PS:本篇文章,是筆者在C語言學習過程中的所產生疑惑的地方,經過查閱相關資料得出的結論,如有錯誤的地方,還望指出改正。

int 佔4個位元組, 這裡輸入的8位16進位制數每相鄰兩位數代表一個位元組。如:44,43,42,41

int b = 0x41424344;
printf("string: %s\n", &b);

注意:%s列印字串的時候,必須要求printf所傳引數必須是一個記憶體的地址,且一定有一個0(代表字串結尾標誌‘\0’)做為截至條件。而這裡並沒有以0結尾所以,這兩行程式碼除了輸出各個位元組的ASCII碼對應的字元以外還會輸出這片儲存區域後面的的記憶體所儲存的資料(是不可預見的)知道遇到0為止。
我的電腦是小端儲存系統,所以輸出結果為:
這裡寫圖片描述

下面來看看這些程式碼:

    int b = 0x41424344;
    int b1 = 0x41424300;
    int b2 = 0x00414243;
    int b3 = 0x41004243;

    printf("string: %s\n", &b);
    printf("string: %s\n", &b1);
    printf("string: %s\n", &b2);
    printf("string: %s\n", &b3);

要記住,%s輸出字串的時候遇到0或‘\0’,就會被截斷,只輸出0或‘\0’前面的字元,所以,這裡b1的最低位為0,則b1沒有字元可以輸出。b2, b3同理。
如圖:這裡寫圖片描述

同樣的道理,如下程式碼:

char arr[4] = {0x41, 'X', '0', 'C'};
        printf("string: %s\n", arr);

由於arr[4]陣列只有4個元素,由於賦值的時候就給四個元素都賦了值,陣列中就沒有元素再來儲存結束符‘\0’,所以,同樣輸出完陣列後會有亂碼產生。
如圖:
這裡寫圖片描述

最有意思的是這兩行程式碼:

int arr[] = {0x41, 'm', 'X', '0', 'C', '\0'};
        printf("string: %s\n", arr);

看上去,在陣列的末位手動添加了字串結尾標誌符,以為正常輸出:AmX0C
其實不然。
這裡寫圖片描述


這裡我給出了,前兩個資料在記憶體中儲存的格式,由於int佔4個位元組,所以0x41只是佔用了第一個元素4個位元組的第一個位元組,所以後面的三個位元組由系統自動補0,所以編譯器在編譯的時候,任然是碰到0就截止。就導致,最終程式只能輸出,0x41所對應的字元 ‘A’.
如圖:
這裡寫圖片描述

下面提供兩種可以正確輸出的方式:

    char arr[5] = {0x41, 'm', 'X', '0'};
    char arr2[] = "AX0C";
    printf("string: %s\n", arr);
    printf("string: %s\n", arr2);

這裡寫圖片描述