[英]Effect of type casting on printf function
這是我書中的一個問題,
其實我也不知道對printf function會有什么影響,所以我試了一下原系統C lang中的語句。 這是我的代碼:
#include <stdio.h>
void main() {
int x = 4;
printf("%hi\n", x);
printf("%hu\n", x);
printf("%i\n", x);
printf("%u\n", x);
printf("%li\n", x);
printf("%lu\n", x);
}
所以,output 非常簡單。 但是,這真的是解決上述問題的方法嗎?
這個問題存在許多問題,使其不適合教授 C。
首先,要解決這個問題,我們必須假設使用了非標准的 C 實現。 在標准C中, %x
是完整的轉換規范,所以%xu
和%xd
不能; 轉換規范在u
或d
之前已經結束。 並且在轉換規范中使用z
會干擾其對size_t
的標准使用。
盡管如此,讓我們假設這個 C 變體沒有那些標准轉換規范,而是使用表中顯示的那些,但是這個 C 變體在其他方面符合 Z0D61F8370CAD1D412F80B84D143E125 標准。
我們的下一個問題是,在Y num = 42;
,我們有一個普通的Y
,而不是表中顯示的有signed Y
或unsigned Y
讓我們假設有signed Y
是有意的。
那么num
是一個有符號的四位 integer。 它可以表示的最大值是 0111 2 = 7 10 。 所以它不能代表 42。嘗試用 42 初始化它會導致 C 2018 6.3.1.3 指定的轉換,其中部分表示:
否則,新類型是有符號的,值不能在其中表示; 結果是實現定義的,或者引發了實現定義的信號。
結果是我們不知道num
中的值是什么,甚至不知道程序是否繼續執行; 它可能會陷入困境並終止。
好吧,讓我們假設這個實現只取值的低位。 42是1010102,所以它的低四位是1010。所以如果num
中的位是1010,就是負數。 C 標准允許負數的幾種表示方法,但我們將假設最常見的一種方法,即二進制補碼,因此num
中的位 1010 表示 -6。
現在,我們來printf
語句。 除了問題文本顯示Printf
,C 標准沒有定義。 (你確定這個問題與 C 代碼有關嗎?)假設它的意思是printf
。
在printf("%xu",num);
, 如果轉換規范應該像標准 C 中的那樣工作,那么對應的參數應該是一個unsigned X
值,該值已被提升為int
以用於 function 調用。 作為兩位無符號 integer, unsigned X
可以表示 0、1、2 或 3。傳遞它 -6 未定義。 所以我們不知道程序會打印什么。 它可能只需要低兩位,10,並打印“2”。 或者它可能會使用所有位並打印“-6”。 這兩者都與printf
的行為與unsigned X
可表示范圍內的值的規定一致。
在printf("%xd",num);
和printf("%yu",num);
,同樣的問題存在。
在printf("%yd",num);
,我們正確地為帶signed Y
轉換規范傳遞了帶signed Y
值,因此打印了“-6”。
然后printf("%zu",num);
與類型不匹配的值有相同的問題。
最后,在printf("%zd",num);
,該值再次在正確的范圍內,並打印“-6”。
從我們必須做出的所有假設以及行為未定義的所有點中,您可以看到這是一個糟糕的練習。 你應該質疑它所在的書和任何使用它的學校的質量。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.