printf未知精确类型的整数

时间:2015-12-31 10:49:40

标签: c

我已经输入了我的代码

typedef int myinteger ;

如果我将typedef更改为另一个整数类型,我希望我的所有代码都能继续有效。

现在我想打印一个myinteger类型的变量。这是一种正确的方法吗?我刚刚发现了以下“黑客”:

printf("%lld", myvariable) ;

希望任何整数类型都适合long long并且编译器将进行正确的转换。它似乎适用于gcc(虽然我有一个警告)。 printf是一个问题,但它们也可能是其他问题(比如找到最大的“myinteger”)。

更普遍的是,有可能/希望尝试我尝试实现的目标,编写代码假设只有myinteger引用某种整数类型?

6 个答案:

答案 0 :(得分:4)

没有通用格式说明符可以在printf()中用于打印任何整数类型。一种方法是投射到C99&#39} intmax_tuintmax_t并打印出来:

#include <stdint.h>

printf("%jd\n", (intmax_t)myvariable);
printf("%ju\n", (uintmax_t)myvariable);

这适用于所有整数类型,因为intmax_t / uintmax_t是最大宽度整数类型。

一般来说,任意改变typedef表明这是设计中的一个根本缺陷。

答案 1 :(得分:4)

我建议:

typedef int my_type_t;
#define FMT_MY_TYPE "%d"

然后:

my_type_t my_var = 0;
printf("Here is my_var: " FMT_MY_TYPE "\n", my_var);

这甚至适用于结构。这是一个概括:

typedef struct { int a; int b; } my_struct_t;
#define FMT_MY_STRUCT "{a: %d, b: %d}"
#define FMT_MY_STRUCT_ARG(x) (x).a, (x).b

然后:

my_struct_t my_var = {0, 1};
printf("Here is my_var: " FMT_MY_STRUCT "\n", FMT_MY_STRUCT_ARG(my_var));

答案 2 :(得分:1)

你必须在long long的调用中转换为printf(),因为它是最长的整数类型:

printf("%lld", (long long)myvariable);

答案 3 :(得分:1)

  

它似乎适用于gcc(虽然我有警告)。

需要添加演员。

printf("%lld", (long long) myvariable);
  

更普遍的是,有可能/希望尝试我尝试实现的目标,编写代码假设只有“myinteger”引用某种整数类型?

“通用”printf调用是一种糟糕的设计气味。此外,如果myvariable的类型为unsigned long long且其值大于LLONG_MAX,该怎么办?

答案 4 :(得分:1)

根据值是否为负数并转换为intmax_tuintmax_t类型,考虑分支;我无法保证long long intunsigned long long int是最大的整数类型,但这些max类型可以保证最大。

例如:

#include <inttypes.h>
/* ... */
if (my_variable < 0) printf("%jd", (intmax_t)  my_variable);
else                 printf("%ju", (uintmax_t) my_variable);

答案 5 :(得分:0)

如果所有代码都需要打印整数,并使用C99或C11,请使用_Generic选择匹配的打印说明符。

#include <stdio.h>
#include <stddef.h>
#include <stdint.h>

#define IntegerFormat3(X) _Generic((X), \
  size_t: "%zu", \
  ptrdiff_t: "%td", \
  default: 0 \
 )

#define IntegerFormat2(X) _Generic((X), \
  intmax_t: "%jd", \
  uintmax_t: "%ju", \
  default: IntegerFormat3(X) \
 )

#define IntegerFormat(X) _Generic(X, \
  _Bool: "%d", \
  char: "%c", \
  signed char: "%hhd", \
  unsigned char: "%hhu", \
  short: "%hd", \
  unsigned short: "%hu", \
  int: "%d", \
  unsigned: "%u", \
  long: "%ld", \
  unsigned long: "%lu", \
  long long: "%lld", \
  unsigned long long: "%llu", \
  default: IntegerFormat2(X) \
  )

int main(void) {
  int i = 12;
  unsigned long long u = 34;
  size_t sz = 56;
  printf(IntegerFormat(i), i);
  printf(IntegerFormat(u), u);
  printf(IntegerFormat(sz), sz);
  return 0;
}

不幸的是printf(IntegerFormat(i) "\n", i);不起作用。

另一种使用任何编码类型相关的说明符Formatted print without the need to specify type matching specifiers using _Generic进行格式化打印的方法。

尽管如此,投射到最宽的匹配符号类型很简单,其他人也会回答。