如何修改C语言中的dprint宏以适配所有数据类型?
改进K&R的dprint宏:自动适配类型的打印方案
你遇到的问题根源是printf格式符与参数类型不匹配:int类型参数被当成double解析,属于C语言的未定义行为,所以输出了异常的极小值。
用C11引入的_Generic类型选择器就能完美解决这个问题,它可以在编译时根据表达式的类型自动选择对应的格式字符串。修改后的宏如下:
#include <stdio.h> #define dprint(expr) \ printf(#expr " = " _Generic((expr), \ int: "%d\n", \ long: "%ld\n", \ double: "%g\n", \ float: "%g\n" \ ), (expr))
工作原理
_Generic((expr), ...)会根据expr的实际类型,匹配对应的格式字符串分支#expr保留了原宏的功能:把传入的表达式转换成字符串,方便打印时显示表达式本身- 针对float类型,由于C语言默认会把float参数提升为double,所以用
%g也能正确输出
使用示例
int main() { int num = 100; long big_num = 9876543210L; double pi = 3.1415926; float e = 2.71828f; dprint(num); // 输出:num = 100 dprint(big_num); // 输出:big_num = 9876543210 dprint(pi); // 输出:pi = 3.14159 dprint(e); // 输出:e = 2.71828 return 0; }
扩展支持更多类型
如果需要适配unsigned int、char等其他类型,只需在_Generic中添加对应分支即可:
#define dprint(expr) \ printf(#expr " = " _Generic((expr), \ int: "%d\n", \ unsigned int: "%u\n", \ long: "%ld\n", \ unsigned long: "%lu\n", \ char: "%c\n", \ double: "%g\n", \ float: "%g\n" \ ), (expr))
内容的提问来源于stack exchange,提问作者paralyzer
相关产品推荐
相关产品推荐

