如何使用一个定义或函数来使用C打印任何变量类型?

时间:2014-04-28 05:36:13

标签: c printing types c-preprocessor sizeof

这开始是一个玩笑类型的Cython,我做了很多愚蠢的定义来使用C模拟python。然后我意识到它实际上很方便调试和快速黑客程序。

我有一个主要工作的定义,使用sizeof来区分类型,但是3或7个字符的char数组/字符串+ \0将被打印为double或int。有没有办法解决?我正在考虑使用try-exception来下标它以查看它是否是一个字符串,但我无法实现它。

#include <stdio.h>

#define print(n) if(sizeof(n)==8)      printf("%f\n",n); \
                 else if(sizeof(n)==4) printf("%i\n",n); \
                 else                  printf("%s\n",n); 

int main()
{
    print("Hello world!") // these all work perfectly
    print(8.93)
    print(4)

    print("abc") // these are interpreted as ints or doubles
    print("1234567")

    return 0;
}

4 个答案:

答案 0 :(得分:3)

gcc有一个方便的内置(也可用于clang),可以直接比较类型:

  

int __builtin_types_compatible_p(type1,type2)

     

如果类型为type1和type2的非限定版本,则此内置函数返回1   (它们是类型,而不是表达式)是兼容的,否则为0。这种内置的结果   function可以在整数常量表达式中使用。

http://gcc.gnu.org/onlinedocs/gcc/Other-Builtins.html

这个内置函数用于linux内核中特定于类型的调度和类型检查,仅举一例。

要从表达式中获取类型,您可以依赖typeof()语句来调整:

__builtin_types_compatible_p (typeof(n), int)

答案 1 :(得分:3)

可以使用_Generic构造选择基于参数类型的操作:

#define print(X) _Generic((0, X), int: print_int, \
                                  double: print_double, \
                                  char *: print_string)(X)

void print_int(int x) { printf("%d\n", x); }
// etc

所有_Generic做的是选择其列表中的一个表达式 - 这就是宏的参数出现两次的原因(一次根据其类型选择,一次实际应用它)选择哪个功能/值)。您还可以提供默认表达式。 Apparently逗号表达式((0, X))是轻松支持字符串文字所必需的:它将字符串衰减为char *

_Generic可用于支持C11的编译器(包括GCC和Clang)。 Jens Gustedt's P99中的某些C99编译器也有解决方法。

答案 2 :(得分:3)

Modern C,AKA C11,类型通用宏有_Generic。像

这样的东西
#define P(x) printf(_Generic(x, unsigned: "%u", signed: "%d", double: "%g"), x)

应该这样做。

答案 3 :(得分:0)

非C ++ 11版本或许只是重载一个函数......它显然不仅仅是一个宏:

void print_var(const char *s)
{
  printf("%s", s);
}

void print_var(unsigned int u)
{
  printf("%u", u);
}

void print_var(int d)
{
  printf("%d", d);
}

void print_var(double f)
{
  printf("%f", f);
}

#define print(v)    { print_var(v); \
                      printf("\n"); }


int main()
{
  print("abc")
  print(1234)
  print(-13)
  print(3.141592654)
  print("1234567")
  print("Hello world!")
  print(8.93)
  print(4)
  if(1)
    print("this too")
  if(2)
    print("and this")
}

产生输出:

abc
1234
-13
3.141593
1234567
Hello world!
8.930000
4
this too
and this