C语言中type of怎么用?

99ANYc3cd6
预计阅读时长 22 分钟
位置: 首页 C语言 正文

Of course! In C, there isn't a direct, built-in keyword like typeof that you can use in the same way you might in C++ or other languages. However, there are several ways to achieve similar functionality, ranging from compiler-specific extensions to modern standard C features.

c语言 type of
(图片来源网络,侵删)

Let's break down the methods, from the most common to the most modern.


The Most Common Method: sizeof(type)

While sizeof doesn't give you the type as a name, it's the most common way to get information about a type's size at compile time. You can use it in preprocessor #if directives to perform conditional compilation based on a type's size.

Example:

#include <stdio.h>
int main() {
    // This is NOT getting the type name, but it's a common way
    // to work with types in a generic way.
    int my_int = 10;
    double my_double = 20.5;
    printf("Size of int: %zu bytes\n", sizeof(my_int));      // Output: 4 bytes
    printf("Size of double: %zu bytes\n", sizeof(my_double)); // Output: 8 bytes
    // Conditional compilation based on type size
    #if sizeof(int) == 4
        printf("This compiler uses 4-byte integers.\n");
    #endif
    return 0;
}

Limitation: This only tells you the size, not the type itself.

c语言 type of
(图片来源网络,侵删)

Compiler-Specific typeof (GCC and Clang)

GCC (and its derivative Clang) support a powerful extension called typeof. This is the closest you'll get to a true typeof operator in standard C. It's very useful for writing generic macros.

Syntax:

  • typeof(expression): Gets the type of the result of an expression.
  • typeof(type): Gets the type directly.

Example (GCC/Clang only):

#include <stdio.h>
// A generic macro to swap two values of any type
#define SWAP(a, b) do { \
    typeof(a) temp = a; \
    a = b; \
    b = temp; \
} while(0)
int main() {
    int x = 5, y = 10;
    printf("Before swap: x = %d, y = %d\n", x, y);
    SWAP(x, y);
    printf("After swap: x = %d, y = %d\n", x, y);
    double d1 = 3.14, d2 = 6.28;
    printf("\nBefore swap: d1 = %f, d2 = %f\n", d1, d2);
    SWAP(d1, d2);
    printf("After swap: d1 = %f, d2 = %f\n", d1, d2);
    return 0;
}

Output:

c语言 type of
(图片来源网络,侵删)
Before swap: x = 5, y = 10
After swap: x = 10, y = 5
Before swap: d1 = 3.140000, d2 = 6.280000
After swap: d1 = 6.280000, d2 = 3.140000

Limitation: This is not standard C. Code using typeof will not compile on compilers that don't support it (like MSVC by default).


The Modern Standard C Solution: _Generic (C11)

Since C11, the standard includes _Generic, which is a powerful feature for generic programming. It allows you to select an expression based on the type of an expression. It's the standard way to create type-safe generic macros and functions.

How it works: _Generic takes a controlling expression and a series of type-name: association pairs. It evaluates the association that matches the type of the controlling expression.

Example: Let's create a macro that safely prints any type.

#include <stdio.h>
// A generic "print" macro
#define PRINT(x) _Generic((x), \
    int: print_int, \
    double: print_double, \
    const char*: print_string \
)(x)
// Helper functions for each type
void print_int(int i) {
    printf("Integer: %d\n", i);
}
void print_double(double d) {
    printf("Double: %f\n", d);
}
void print_string(const char* s) {
    printf("String: %s\n", s);
}
int main() {
    int a = 100;
    double b = 3.14159;
    const char* c = "Hello, C11!";
    PRINT(a);
    PRINT(b);
    PRINT(c);
    return 0;
}

Output:

Integer: 100
Double: 3.141590
String: Hello, C11!

Limitation: _Generic doesn't give you the type as a string or a variable of type type. It's a compile-time dispatch mechanism. You have to list all the types you want to handle explicitly.


Advanced: Getting the Type as a String (Non-Standard)

If your goal is to get the name of the type as a string (e.g., "int", "double"), this is not possible in standard C. The C preprocessor and compiler do not have a way to generate a string literal from a type name.

However, some compilers offer non-standard extensions for this. For example, GCC has __typeof__ and a way to stringify type names using and __VA_ARGS__ tricks, but it's complex and not portable.

Example (GCC-specific, advanced macro):

// This is a GCC-specific trick and not recommended for portable code
#define TYPESTR(x) _Generic((x), \
    int: "int", \
    double: "double", \
    default: "unknown type" \
)
int main() {
    int my_var = 42;
    printf("The type of my_var is: %s\n", TYPESTR(my_var)); // Output: The type of my_var is: int
    return 0;
}

This uses _Generic to select a string literal, effectively creating a "type-to-string" mapping. It's still limited to the types you explicitly list.


Summary Table

Method Standard C? Use Case Portability
sizeof(type) Yes Getting the size of a type; conditional compilation. Excellent (All C compilers)
typeof (GCC/Clang) No Creating generic macros that work with any type. Poor (GCC, Clang, ICC only)
_Generic (C11) Yes Writing type-safe generic functions and macros. Good (Modern C11 compilers)
Stringify Type Name No Getting a type's name as a string (e.g., "int"). Very Poor (Compiler-specific hacks)

Conclusion

  • For portable, standard C code, use _Generic (C11 and later) for generic programming and sizeof for size-based conditional logic.
  • If you are targeting GCC or Clang and need a simple typeof for macros, typeof is an excellent and powerful choice.
  • Getting a type's name as a string is not possible in standard C and should be avoided for portable code.
-- 展开阅读全文 --
头像
织梦模板安装步骤是什么?
« 上一篇 04-07
c语言format函数
下一篇 » 04-07

相关文章

取消
微信二维码
支付宝二维码

目录[+]