在C语言(不是C++/C#)中,如何判断变量是否属于某种类型?

例如,类似这样的事情:

double doubleVar;
if( typeof(doubleVar) == double ) {
    printf("doubleVar is of type double!");
}

或者更一般地说:我如何比较两种类型,以便compare(double1,double2)将计算为真,compare(int,double)将计算为假.此外,我还想比较不同组成的 struct .

基本上,我有一个函数,它对类型为"struct a"和"struct b"的变量进行操作.我想用" struct a"变量做一件事,用" struct b"变量做另一件事.因为C不支持重载,而且void指针会丢失其类型信息,所以我需要判断类型.顺便说一句,如果你不能比较类型,使用typeof运算符有什么意义?


对我来说,sizeof方法似乎是一个实用的变通办法.谢谢你的帮助.我仍然觉得有点奇怪,因为类型在编译时是已知的,但是如果我想象一下机器中的进程,我可以看到,为什么信息不是按类型存储的,而是按字节大小存储的.除了地址,大小是唯一真正相关的东西.

推荐答案

到目前为止,在具有_Generic泛型 Select 的C11中可以获得变量的类型.它在编译时工作.

语法有点像switch.以下是一个样本(来自this answer):

    #define typename(x) _Generic((x),                                                 \
            _Bool: "_Bool",                  unsigned char: "unsigned char",          \
             char: "char",                     signed char: "signed char",            \
        short int: "short int",         unsigned short int: "unsigned short int",     \
              int: "int",                     unsigned int: "unsigned int",           \
         long int: "long int",           unsigned long int: "unsigned long int",      \
    long long int: "long long int", unsigned long long int: "unsigned long long int", \
            float: "float",                         double: "double",                 \
      long double: "long double",                   char *: "pointer to char",        \
           void *: "pointer to void",                int *: "pointer to int",         \
          default: "other")

要实际使用它进行编译时手动类型判断,您可以定义一个enum,其中包含您期望的所有类型,如下所示:

    enum t_typename {
        TYPENAME_BOOL,
        TYPENAME_UNSIGNED_CHAR,
        TYPENAME_CHAR,
        TYPENAME_SIGNED_CHAR,
        TYPENAME_SHORT_INT,
        TYPENAME_UNSIGNED_CHORT_INT,
        TYPENAME_INT,
        /* ... */
        TYPENAME_POINTER_TO_INT,
        TYPENAME_OTHER
    };

然后使用_Generic将类型与此enum匹配:

    #define typename(x) _Generic((x),                                                       \
            _Bool: TYPENAME_BOOL,           unsigned char: TYPENAME_UNSIGNED_CHAR,          \
             char: TYPENAME_CHAR,             signed char: TYPENAME_SIGNED_CHAR,            \
        short int: TYPENAME_SHORT_INT, unsigned short int: TYPENAME_UNSIGNED_SHORT_INT,     \
              int: TYPENAME_INT,                     \
        /* ... */                                    \
            int *: TYPENAME_POINTER_TO_INT,          \
          default: TYPENAME_OTHER)

C++相关问答推荐

当包含头文件时,gcc会发出隐式函数声明警告

C如何显示字符串数组中的第一个字母

C/SDL程序,渲染不使用我的渲染器

如何在C宏中确定 struct 中元素的类型?

无效指针值在函数调用之间莫名其妙地改变

为什么我一直收到分段错误?

在C23中使用_GENERIC实现带有右值的IS_POINTER(P)?

在C语言中,在数学运算过程中,为什么浮点数在变量中的行为不同

如何识别Linux中USB集线器(根)和连接到集线器(根设备)的设备(子设备)?

在句子中转换单词的问题

正数之和是负数

Printf()在C中打印终止字符之后的字符,我该如何解决这个问题?

C:如何将此代码转换为与数组一起使用?

C";中的ANN运行时判断失败#2-变量outputLayer;周围的堆栈已损坏.运行后出错

Realloc():中止的下一个大小无效(核心转储)

宏观;S C调深度

在C中打印指针本身

将char*数组深度复制到 struct 中?

GCC认为这是一个VLA是对的吗?

无法将字符串文字分配给 C 中的字符数组