簡單的說,我們用va_arg(ap,type)取出乙個引數的時候,
type
絕對不能為以下型別:
——char、signed
char、unsigned
char
——short、unsigned
short
——signed
short、shortint、signed
shortint、unsigned
shortint
——float
乙個簡單的理由是:
——呼叫者絕對不會向my_printf傳遞以上型別的實際引數。
在c語言中,呼叫乙個不帶原型宣告的函式時:
呼叫者會對每個引數執行「預設實際引數提公升(default argumentpromotions)」。
同時,對可變長引數列表超出最後乙個有型別宣告的形式引數之後的每乙個實際引數,也將執行上述提公升工作。
提公升工作如下:
——float型別的實際引數將提公升到double
——char、short和相應的signed、unsigned型別的實際引數提公升到int
——如果int不能儲存原值,則提公升到unsigned int
然後,呼叫者將提公升後的引數傳遞給被呼叫者。
附錄:在《c語言程式設計》對可變長引數列表的相關章節中,並沒有提到這個陷阱。
但是有提到預設實際引數提公升的規則:
在沒有函式原型的情況下,char與short型別都將被轉換為int型別,float型別將被轉換為double型別。
——《c語言程式設計》第2版 2.7 型別轉換 p36
在其他一些書籍中,也有提到這個規則:
事情很清楚,如果乙個引數沒有宣告,編譯器就沒有資訊去對它執行標準的型別檢查和轉換。
在這種情況下,乙個char或short將作為int傳遞,float將作為double傳遞。
這些做未必是程式設計師所期望的。
腳注:這些都是由c語言繼承來的標準提公升。
對於由省略號表示的引數,其實際引數在傳遞之前總執行這些提公升(如果它們屬於需要提公升的型別),將提公升後的值傳遞給有關的函式。——譯者注
——《c++程式語言》第3版-特別版 7.6 p138
…… float型別的引數會自動轉換為double型別,short或char型別的引數會自動轉換為int型別 ……
——《c陷阱與缺陷》 4.4 形參、實參與返回值 p73
這裡有乙個陷阱需要避免:
va_arg巨集的第2個引數不能被指定為char、short或者float型別。
因為char和short型別的引數會被轉換為int型別,而float型別的引數會被轉換為double型別 ……
例如,這樣寫肯定是不對的:
c = va_arg(ap,char);
因為我們無法傳遞乙個char型別引數,如果傳遞了,它將會被自動轉化為int型別。上面的式子應該寫成:
c = va_arg(ap,int);
——《c陷阱與缺陷》p164
關於isinstance和type的區別
分析 type和isinstance都是python中用來判斷資料型別的,type相對與isinstance更加粗糙,建議使用具體的type,我們還可以使用c語言中的ctypes。isinstace的兩個引數,第一引數是乙個類的例項,在這個例子中的例項是子類b的例項 z,第二個引數是指定的類,或者其...
oracle中type的使用
create or replace type mytype is table of varchar2 20 declare type1 mytype mytype 1 2 3 4 i number 1 var str varchar 20 liaomin begin type1.extend typ...
sysobjects中type的定義
sysobjects中type的定義如下 sysobjects是mssql資料庫的系統表,在web許可權下可以正常訪問。msysobjects是access資料庫的系統表,在web許可權下沒有許可權訪問,會提示 沒有許可權訪問 我們在mssql的儲存過程中經常要處理一些特殊的物件,這些物件都存放在資...