C语言中类型捕获(typeof)的使用

 更新时间:2025年09月17日 09:36:45   作者:Lumiron  
C语言中typeof是一个编译器扩展,支持泛型宏开发,可避免表达式重复求值,提升代码可读性,本文就来详细的介绍一下C语言中类型捕获(typeof)的使用,感兴趣的可以来了解一下

它的作用是在编译时获取变量或表达式的类型。它非常强大,常用于编写类型通用的代码或简化复杂类型的声明,是 C 语言中一种“泛型编程”的实用技巧。

基本用法

typeof 的基本语法是 typeof(expression) 或 typeof(type)。

a) 获取变量类型

用于声明一个与另一个变量相同类型的新变量。

int a = 10;
// 声明一个与变量a类型相同(即int)的变量b
typeof(a) b = 20;

double foo;
// 声明一个与foo类型相同(即double)的数组
typeof(foo) array[10];

b) 获取表达式类型

你可以获取一个表达式的类型,即使这个表达式还没有被求值。

// 声明一个变量c,其类型是表达式 (a + b) 的结果类型
typeof(a + b) c;

// 一个更复杂的例子:声明一个指针,指向一个返回int、接受double参数的函数
int some_func(double d);
typeof(some_func) *func_ptr; // func_ptr 的类型是 int (*)(double)

c) 简化复杂声明

C 语言中复杂的指针和数组声明可能很难读懂,typeof 可以极大地提高代码的可读性。
没有 typeof 的复杂代码:

// 一个指向长度为5的int数组的指针
int (*array_ptr)[5];

// 一个函数指针,该函数接受一个int参数并返回一个指向char的指针
char *(*func_ptr)(int);

使用 typeof 简化:

// 先定义一个简单的数组类型
int array[5];
// 然后用typeof获取“指向这个数组类型的指针”
typeof(array) *array_ptr; // 等价于 int (*array_ptr)[5];

// 先定义一个函数(或使用已有的)
char *some_func(int);
// 然后用typeof获取“指向这个函数类型的指针”
typeof(some_func) *func_ptr; // 等价于 char *(*func_ptr)(int);

经典应用:编写“泛型”宏

typeof 最常见的用途是编写可以处理多种类型的宏,从而实现类似 C++ 模板的功能。Linux 内核源码中大量使用了这种技术。

示例1:一个简单的 Max 宏

一个简单的 MAX 宏如果只用 (a > b) ? a : b 实现,如果参数是有副作用的表达式(如 a++),可能会被求值两次,导致错误。
使用 typeof 可以创建一个安全版本的 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++只执行一次

    printf("result = %d, x = %d, y = %d\n", result, x, y);
    // 输出:result = 10, x = 6, y = 11
    return 0;
}

解释:({ … }) 是 GCC 的语句表达式扩展,它允许一个代码块产生一个值。宏内部创建了局部变量 _a 和 _b 来存储参数的值,避免了多次求值。

示例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 关键字:在头文件中,为了避免与用户定义的标识符冲突,GCC 建议使用 typeof,它与 typeof 的含义完全相同,但更“安全”。
4、C11 中的 _Generic:C11 标准引入了一个真正的泛型选择机制 _Generic,它可以在编译时根据表达式的类型选择不同的代码分支。虽然它的用法与 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"
}

到此这篇关于C语言中类型捕获(typeof)的使用的文章就介绍到这了,更多相关C语言 类型捕获内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

您可能感兴趣的文章:

相关文章

  • C++使用GDAL库实现Tiff文件的读取

    C++使用GDAL库实现Tiff文件的读取

    这篇文章主要为大家详细介绍了C++使用GDAL库实现Tiff文件的读取的相关知识,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下
    2023-03-03
  • C语言的常量和字符串

    C语言的常量和字符串

    这篇文章主要为大家介绍了C语言常量和字符串,具有一定的参考价值,感兴趣的小伙伴们可以参考一下,希望能够给你带来帮助
    2021-12-12
  • VisualStudio2022 cmake配置opencv开发环境

    VisualStudio2022 cmake配置opencv开发环境

    本文主要介绍了VisualStudio2022 cmake配置opencv开发环境,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2023-08-08
  • C++学习笔记之类与对象详解

    C++学习笔记之类与对象详解

    这篇文章主要为大家介绍了C++类与对象,具有一定的参考价值,感兴趣的小伙伴们可以参考一下,希望能够给你带来帮助
    2021-12-12
  • C++设计模式之外观模式

    C++设计模式之外观模式

    这篇文章主要介绍了C++设计模式之外观模式,本文详细讲解了C++中的Facade模式,并给出了实例代码,需要的朋友可以参考下
    2014-10-10
  • C++ pair方法与vector方法案例详解

    C++ pair方法与vector方法案例详解

    这篇文章主要介绍了C++ pair方法与vector方法案例详解,本篇文章通过简要的案例,讲解了该项技术的了解与使用,以下就是详细内容,需要的朋友可以参考下
    2021-09-09
  • 基于C语言实现学生成绩管理系统

    基于C语言实现学生成绩管理系统

    这篇文章主要介绍了基于C语言实现学生成绩管理系统,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2018-01-01
  • C语言线性代数算法实现矩阵示例代码

    C语言线性代数算法实现矩阵示例代码

    这篇文章主要为大家介绍了使用C语言线性代数的算法来实现矩阵示例代码,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步
    2021-10-10
  • C++ protobuf中对不同消息内容进行赋值的方式总结(set_、set_allocated_、mutable_、add_)

    C++ protobuf中对不同消息内容进行赋值的方式总结(set_、set_allocated_、mutable_、

    这篇文章主要给大家介绍了关于C++ protobuf中对不同消息内容进行赋值的方式总结,主要使用的是set_、set_allocated_、mutable_、add_,文中通过实例代码介绍的非常详细,需要的朋友可以参考下
    2023-03-03
  • C语言实现员工工资管理系统

    C语言实现员工工资管理系统

    这篇文章主要为大家详细介绍了C语言实现员工工资管理系统,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-02-02

最新评论