2016-03-05 126 views
1

是否可以創建一個宏函數,其返回值是預定義的c變量數據類型之一?例如:C宏返回類型的變量

#include <stdio.h> 
#define IND_I_ 0 
#define IND_F_ 1 
#define INT_FORMAT_ "%i" 
#define FLOAT_FORMAT_ "%f" 
// (Of course the following macros do not make the desired jobs) 
// FORMAT_ macro would be used for the variable format: 
#define FORMAT_(ind_)((ind_) == IND_I_ ? FOR_INT_ : FOR_FLOAT_) 
// VAR_TYPE_ macro would be used for 
// defining variable types and for the casting of variables: 
#define VAR_TYPE_(ind_) ((ind_) == IND_I_ ? int : float) 

int main(void) 
{ 
    VAR_TYPE_(IND_I_) first_var = 123; //here I want: int first_var = 123; 
    VAR_TYPE_(IND_F_) second_var = 345.789; 
    //Instead of: 
    //printf("int variable = " "%i" "\n", first_var); 
    //I would use: 
    printf("int variable = " FORMAT_(IND_I_) "\n", first_var); 
    printf("float variable = " FORMAT_(IND_F_) "\n", second_var); 
    printf("truncated real variable = " INT_FORMAT_ "\n", (VAR_TYPE_(IND_I_))second_var); 
    return 0; 
} 

回答

3

對不起,這在C系列中是不可能的。 (它可能在語言中使用更強大的宏系統,如Common Lisp和Rust。)

宏只能做文本替換。所以,你的

#define VAR_TYPE_(ind_) ((ind_) == IND_I_ ? int : float) 
#define IND_I_ 0 
VAR_TYPE_(IND_I_) first_var = 123; 

擴展到

((0) == 0) ? int : float) first_var = 123; 

這是一個語法錯誤。沒有辦法使它評估?:表達式。

有你可以做的事情,將使其工作時的參數VAR_TYPE_擴大到字面零,一,等:

#define VAR_TYPE_(ind_) VAR_TYPE__(ind_) 
#define VAR_TYPE__(ind_) VAR_TYPE__##ind_ 
typedef int VAR_TYPE__0; 
typedef float VAR_TYPE__1; 
// etc 

...但如果你在做這所有,你可能想允許ind_是一個任意的整數常量表達式,並且不起作用。你會得到像

VAR_TYPE_sizeof(int)==4?0:2 

在擴展,你會回到語法錯誤。

(噓:你把空間上的括號內每一次,神殺死一隻小貓。)

+0

@zwol,你認爲通過使用#if,#else,#elif指令可以解決我的問題嗎? – jruiz

+0

@Olaf這是一個示範,確切地說明了「這可以完成」和「這不能完成」之間的界限。它不打算用於生產代碼。 – zwol

+1

C11的那個邪惡'_Generic'結構可以做到。雖然格式字符串連接不起作用,但至少不是以任何直接的方式。 – doynax

0

簡短的回答是:沒有。

你想實現什麼?
爲什麼你需要在C中靈活鍵入?也許你應該轉向Java或Python。

在你的例子中,你已經有了類型信息,所以用宏代替特定於類型的字符串文字是矯枉過正的。

如果你想控制的類型從外面看,這我強烈反對的變量,可以設置宏替代品,並注入他們通過頁眉或直接指定他們的編譯器的命令行上。

舉例示範(請不要在家裏做這個)​​:

#include <stdio.h> 
#include <stdlib.h> 
/* // eg. 
#define TEH_TYPE double 
#define TEH_TYPE_FMT "%f" 
#define TEH_TYPE_ATO atof 
*/ 
// Either, or see command line below. 
/* 
#define TEH_TYPE int 
#define TEH_TYPE_FMT "%d" 
#define TEH_TYPE_ATO atoi 
*/ 

int main(int argc, char **argv) { 
    TEH_TYPE v; 
    if(argc > 1) 
    { 
     v = TEH_TYPE_ATO(argv[1]); 
     printf("So your thingie is " TEH_TYPE_FMT "\n", v); 
    } 
    return 0; 
} 

然後,您可以編譯爲gcc -DTEH_TYPE=int -DTEH_TYPE_FMT='"%d"' -DTEH_TYPE_ATO=atoi main.c -o main

但是,請不要。我很慚愧地寫下這些。

+0

非常感謝您的簡短回答。我在這裏寫的代碼當然是我想要做的代表性部分。我想知道我在我的問題中解釋的效果是否可以實現。 – jruiz

1

宏只是文字替換,所以你不能這樣做。 使用C++ 11/14,自動類型和outstream句柄將適合。

+0

「使用C++」不是專門針對C問的問題的答案,是嗎? –

+0

@Meehm是的,事實並非如此。 – hxpax