2015-12-31 46 views
2

的整數我已經把我的代碼printf的未知精確型

typedef int myinteger ; 

我想然而,所有我的代碼繼續有效,如果我改變的typedef另一個整數類型。

現在我想打印一個myinteger類型的變量。這是一種正確的做法嗎?我剛找到下面的「黑客」:

printf("%lld", myvariable) ; 

希望任何整數類型將適合在一個long long和編譯器會做適當的轉換。它似乎與gcc一起工作(雖然我有一個警告)。 printf是一個問題,但他們也可能是其他問題(如找到最大的「myinteger」)。

更一般地說,可能/需要嘗試我試圖實現的目標,編寫代碼只假設myinteger引用某種整數類型?

+0

我會帶葉出C99的書,他們定義了幾個宏的對格式,如'uint64_t'(對於該格式是'PRIu64'宏)。只需要添加一個'#define MYINT_F「%d」'來與'typedef'一起使用,並根據類型 –

回答

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)); 
1

你不得不轉換爲long long在調用printf(),因爲它是最長整數類型:

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

「它是最長的整數類型」更改格式字符串?由於C99,'intmax_t'和'uintmax_t'是「最大寬度整數類型」C11dr 7.20.1.5 – chux

1

這似乎可與海灣合作委員會(雖然我有一個警告)。

需要添加一個演員。

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

更普遍的是有可能/希望盡我儘量做到,編寫代碼假設僅僅是「myinteger」指的是某個整數類型?

「通用」printf調用是一種糟糕的設計氣味。此外,如果myvariable的類型爲unsigned long long,並且其值大於LLONG_MAX

+0

當然,它不會爲無符號...工作,但我擔心你說的是正確的通用printf是壞的。有沒有更好的方法來做我想要的? – olivier

+0

@Oivivier一個解決方案就是避免'typedef'。就我個人而言,我不喜歡'typedef',並發現大多數時候這是一種混淆代碼的方式。 – ouah

+1

@Olivier:「*更好的方法*」被稱爲C++ - 'std :: cout << myvariable' - 這不是您可能正在尋找的答案。 – Clifford

4

沒有通用格式說明符可用於printf()來打印任何整數類型。一種方法是強制轉換爲C99的intmax_tuintmax_t和打印:

#include <stdint.h> 

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

這將爲所有的整數類型上班intmax_t/uintmax_t的類型是最大寬度整數。

一般而言,任意改變typedef表明設計中存在根本缺陷。

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); 
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);不起作用。

另一種C格式化打印方法任意編碼類型相關說明符Formatted print without the need to specify type matching specifiers using _Generic

儘管如此,鑄造最廣泛匹配標誌岬型被別人當作回答很簡單。