色婷婷狠狠18禁久久YY,CHINESE性内射高清国产,国产女人18毛片水真多1,国产AV在线观看

C語言如何支持C

謝彥文2年前24瀏覽0評論

C語言如何支持C?

這個問題描述其實有點問題,因為C++重載有兩種場景:

函數重載運算符重載

問題本身沒有指明到底是哪種場景。現在就兩個場景分別給出答案。

如何用C語言實現C++函數重載?

根據筆者的經驗,共有3種方法可以實現:

用C語言實現一個C++編譯器的對應子集, 后者自然可以支持重載;用函數指針加上void指針類型參數強制類型轉換,可以實現函數重載;用宏加上可變參數,可以實現函數重載如何用C語言實現C++運算符重載?

運算符在C語言中是保留字, 無法通過普通變通方法實現重載。只能用C語言實現一個C++編譯器的對應子集, 后者自然可以支持重載。

用函數指針加上void指針類型參數強制類型轉換,實現函數重載

用一個例子來說明:

typedef void (*funcOverride)(void *param);

void runFuncOverride(funcOverride f, void *param) {

f(param);

}

void func_with_int_param(void *iParam) {

int i = *(int *)iParam;

printf("int_param function is called, param is %d\n", i);

}

void func_with_char_param(void *cParam) {

char c = *(char *)cParam;

printf("char_param function is called, param is %c\n", c);

}

int i = 1;

char c='2';

runFuncOverride(func_with_int_param, &i);

runFuncOverride(func_with_char_param, &c);

輸出結果為:

bint_param function is called, param is 1

char_param function is called, param is 2

這種方法有一個明顯的劣勢:

需要調用方事先指定函數指針掛接的實際調用的函數實體,即便是用變通的方式——將類型信息通過枚舉類型或者字符串類型作為參數傳遞,也無法完美消除這個劣勢。

根因是:運行時類型判斷并未收納于C語言標準規范中。

當然,一些C語言編譯器可能會提供內置函數來實現該特性,但畢竟不是標準,無法滿足跨平臺的需求。比方說gcc就提供了__builtin_types_compatible_p和typeof這兩個內置函數來做運行時類型判斷。

用宏加上可變參數,實現函數重載

C語言支持可變參數,比方說prinf函數的原型如下:

int printf(const char *format, ...);

省略號表示參數為可變參數,而且C語言規定:省略號只能出現在函數形參的末尾,而且左邊必須有普通的形參。

需要注意的是:對于宏沒有上述限制。

C語言定義了一系列宏來完成可變參數函數參數的讀取和使用:宏va_start、va_arg和va_end。

在ANSI C標準下,這些宏定義在stdarg.h中:

void va_start(va_list ap, last);//取第一個可變參數;

type va_arg(va_list ap, type);//獲取當前位置參數值

void va_end(va_list ap);//將ap置為NULL

除此之外,還提供了一個非常有用的宏:__VA_ARGS__

這個宏直接引用可變參數列表。

有了上述前置知識,下面用一個例子來說明如何實現函數重載:

#define OneArgument(a) printf("One Argument func is called!\n")

#define TwoArguments(a, b) printf("Two Arguments func is called!\n")

#define MacroKernel(_1, _2, FUNC, ...) FUNC

#define Macro(...) MacroKernel(__VA_ARGS__, TwoArguments, OneArgument, ...)(__VA_ARGS__)

Macro(1);

Macro(2,3);

輸出結果為:

One Argument func is called!

Two Arguments func is called!

上述代碼估計有些小伙伴看了有點暈,現在做要點說明:

Macro宏定義展開其實是:調用MacroKernel宏展開的函數實體,調用參數為可變參數,由Macro宏括號中的內容定義。__VA_ARGS__其實引用的就是Macro宏定義括號中的可變參數列表。MacroKernel宏定義中的_1,_2都是占位符,沒有實際含義,作用是:保證在傳給Macro不同數目參數時,使得FUNC指向對應的函數實體:Macro參數數目為1時,FUNC指向OneArgument函數;參數數目為2時,FUNC指向TwoArguments函數。

下面來看看實際的展開效果:

Macro(1)

=>MacroKernel(1, TwoArguments, OneArgument, ...)(1)

=>OneArgument(1)

Macro(2, 3)

=>MacroKernel(2, 3, TwoArguments, OneArgument, ...)(2, 3)

=>TwoArguments(2, 3)

java 操作符重載,C語言如何支持C