C語言中類型捕獲(typeof)的使用
它的作用是在編譯時獲取變量或表達式的類型。它非常強大,常用于編寫類型通用的代碼或簡化復雜類型的聲明,是 C 語言中一種“泛型編程”的實用技巧。
基本用法
typeof 的基本語法是 typeof(expression) 或 typeof(type)。
a) 獲取變量類型
用于聲明一個與另一個變量相同類型的新變量。
int a = 10; // 聲明一個與變量a類型相同(即int)的變量b typeof(a) b = 20; double foo; // 聲明一個與foo類型相同(即double)的數(shù)組 typeof(foo) array[10];
b) 獲取表達式類型
你可以獲取一個表達式的類型,即使這個表達式還沒有被求值。
// 聲明一個變量c,其類型是表達式 (a + b) 的結(jié)果類型 typeof(a + b) c; // 一個更復雜的例子:聲明一個指針,指向一個返回int、接受double參數(shù)的函數(shù) int some_func(double d); typeof(some_func) *func_ptr; // func_ptr 的類型是 int (*)(double)
c) 簡化復雜聲明
C 語言中復雜的指針和數(shù)組聲明可能很難讀懂,typeof 可以極大地提高代碼的可讀性。
沒有 typeof 的復雜代碼:
// 一個指向長度為5的int數(shù)組的指針 int (*array_ptr)[5]; // 一個函數(shù)指針,該函數(shù)接受一個int參數(shù)并返回一個指向char的指針 char *(*func_ptr)(int);
使用 typeof 簡化:
// 先定義一個簡單的數(shù)組類型 int array[5]; // 然后用typeof獲取“指向這個數(shù)組類型的指針” typeof(array) *array_ptr; // 等價于 int (*array_ptr)[5]; // 先定義一個函數(shù)(或使用已有的) char *some_func(int); // 然后用typeof獲取“指向這個函數(shù)類型的指針” typeof(some_func) *func_ptr; // 等價于 char *(*func_ptr)(int);
經(jīng)典應用:編寫“泛型”宏
typeof 最常見的用途是編寫可以處理多種類型的宏,從而實現(xiàn)類似 C++ 模板的功能。Linux 內(nèi)核源碼中大量使用了這種技術(shù)。
示例1:一個簡單的 Max 宏
一個簡單的 MAX 宏如果只用 (a > b) ? a : b 實現(xiàn),如果參數(shù)是有副作用的表達式(如 a++),可能會被求值兩次,導致錯誤。
使用 typeof 可以創(chuàng)建一個安全版本的 MAX 宏:
#define MAX(a, b) ({ \
typeof(a) _a = (a); \
typeof(b) _b = (b); \
_a > _b ? _a : _b; \
})
int main() {
int x = 5, y = 10;
int result = MAX(x++, y++); // 安全,x++和y++只執(zhí)行一次
printf("result = %d, x = %d, y = %d\n", result, x, y);
// 輸出:result = 10, x = 6, y = 11
return 0;
}
解釋:({ … }) 是 GCC 的語句表達式擴展,它允許一個代碼塊產(chǎn)生一個值。宏內(nèi)部創(chuàng)建了局部變量 _a 和 _b 來存儲參數(shù)的值,避免了多次求值。
示例2:交換兩個變量的值
一個通用的 SWAP 宏:
#define SWAP(a, b) do { \
typeof(a) _temp = a; \
a = b; \
b = _temp; \
} while (0)
int main() {
int i = 1, j = 2;
SWAP(i, j);
double x = 3.14, y = 2.71;
SWAP(x, y);
return 0;
}
這個宏可以交換任何相同類型的變量(int, double, struct 等)。
注意事項和限制
1、非標準:最重要的一點,typeof 不是標準 C。如果你寫的代碼需要極高的可移植性,并且必須能用 MSVC 等不支持此擴展的編譯器編譯,就應該避免使用它。
2、編譯器支持:主要被 GCC 和 Clang 支持。
3、typeof 關(guān)鍵字:在頭文件中,為了避免與用戶定義的標識符沖突,GCC 建議使用 typeof,它與 typeof 的含義完全相同,但更“安全”。
4、C11 中的 _Generic:C11 標準引入了一個真正的泛型選擇機制 _Generic,它可以在編譯時根據(jù)表達式的類型選擇不同的代碼分支。雖然它的用法與 typeof 不同,但它是標準委員會提供的解決類似“泛型”需求的方案。
_Generic 示例:
#define get_type_name(x) _Generic((x), \
int: "int", \
double: "double", \
default: "unknown type" \
)
int main() {
int i;
printf("%s\n", get_type_name(i)); // 輸出 "int"
}
到此這篇關(guān)于C語言中類型捕獲(typeof)的使用的文章就介紹到這了,更多相關(guān)C語言 類型捕獲內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Qt5中QML自定義環(huán)形菜單/環(huán)形選擇框的實現(xiàn)
本文主要介紹了Qt5中QML自定義環(huán)形菜單/環(huán)形選擇框的實現(xiàn),文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下2022-03-03
C++利用棧實現(xiàn)中綴表達式轉(zhuǎn)后綴表達式
這篇文章主要為大家詳細介紹了C++利用棧實現(xiàn)中綴表達式轉(zhuǎn)后綴表達式,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下2020-04-04

