2012-07-18 52 views
2

我知道這個問題有一個C++版本,但是我使用標準的typedefs而不是模板。C運行時條件typedef

我寫了一個程序,可以使用16位的wav文件。它通過將每個樣本加載到一個短文中來完成。程序然後對短路進行算術運算。

我現在正在修改程序,以便它可以同時使用16位和32位wav。我希望做一個條件typedef,即使用16位的short和32位的int。但後來我意識到,如果編譯器事先不知道變量的類型,編譯器可能不會編譯代碼。

於是,我就考出了下面的代碼:

#include <stdio.h> 

int 
main() 
{ 
    int i; 
    scanf("%i", &i); 

    typedef short test; 

    if(i == 1) 
    typedef short sample; 
    else 
    typedef int sample; 

    return 0; 
} 

,並得到了以下編譯器錯誤:

dt.c: In function ‘main’: 
dt.c:12:5: error: expected expression before ‘typedef’ 
dt.c:14:5: error: expected expression before ‘typedef’ 

這是否意味着用C是運行條件的typedef是不可能的?

[開放式問題:]如果不是,你們將如何處理這樣的事情?

+3

是的,運行時typedefs是不可能的。編譯器需要爲'sample s;'分配存儲空間,因爲它必須知道大小。 – 2012-07-18 12:25:52

+0

考慮使用''(和/或'')和'uint16_t'和'int32_t'等等。當然這是來自C99,但即使是逆行編譯器通常也提供工具(或者可以提供頭文件)。 – 2012-07-18 13:11:23

回答

2

程序中的所有類型必須在編譯時是已知的。

在C++中,您可以使用模板編譯shortint的代碼;在C中,您可以使用宏(特別是X宏)來執行此操作。

將您的計算代碼放在一個單獨的文件中,例如, dt.tmpl.c,然後在dt.c寫:

#define sample int 
#include "dt.tmpl.c" 

#define sample short 
#include "dt.tmpl.c" 

dt.tmpl.c代碼,然後可以使用sample作爲預處理記號來命名類型並粘貼到函數的名稱,例如:

#define PASTE(name, type) name ## _ ## type 
#define FUNCTION_NAME(name, type) PASTE(name, type) 

sample FUNCTION_NAME(my_calculation, sample)(sample i) { 
    return i * 2; 
} 

這將導致兩個功能int my_calculation_int(int i)short my_calculation_short(short i),然後您可以在其他地方使用。

+0

你只能粘貼一個宏,所以你必須把函數名變成參數化的宏調用,比如'FUNCTION_NAME(my_calculation,SAMPLESIZE)',其中'SAMPLESIZE'可能是'wav16'或'wav32',並且'FUNCTION_NAME'宏調用另一個宏將參數粘貼到一個名稱中。 – 2012-07-18 12:33:35

+0

@JonathanLeffler謝謝,糾正。 – ecatmur 2012-07-18 12:43:06

+1

更接近。有關詳細說明,請參見[C預處理器和串聯](http://stackoverflow.com/questions/1489932/c-preprocessor-and-concatenation/1489985#1489985)。我在前面的評論中提到,你需要讓函數名稱宏調用另一個來進行粘貼。即使你的修改後的代碼會生成'my_calculation_sample',而不管'sample'被定義爲什麼。 – 2012-07-18 12:49:25

5

typedef是一個編譯器功能,你不能在運行時應用它。

1

首先,一個typedef是不是一個新的類型,它是一個別名或短格式(使用函數指針工作時,特別是)使事情變得更加方便

C是一種靜態語言,你不能創建類型在運行期間需要在編譯/鏈接時解析。

以及如果有可能在Windows API將是幾乎每個API調用SOOO小得多:)

在Windows它們的功能,兩個版本和定義決定使用哪一種。

例如

#ifndef UNICODE 
#define myfunction _myfunctionA(TCHAR* p); 
#else 
#define myfunction _myfunctionW(TCHAR* p); 
#endif 

但同樣類型在決定編譯時間

0

C(和C++)中的類型在編譯時是固定的; '運行時typedef'的概念在C中沒有意義。

但是,您的問題可以小心解決。您將定義兩組函數(和類型),一個用於處理16位.wav文件,另一個用於處理32位.wav文件。這些將在編譯時定義,並且類型的大小將在編譯時被固定,但是這兩個代碼都將在可執行文件中,並且您可以根據運行時選擇執行哪組函數,時間信息(您要求處理或生成的文件類型)。

你的兩套函數應該是對稱的。您可能可以使用某種類似「模板」的機制,這樣您可以編譯兩次相同的文件,一次編譯32位代碼,一次編譯16位代碼,確保函數名稱一致地更改。

2

另一方面,您只能在某個範圍內使用typedef

int 
main(void) { 
    if (1) { 
     typedef short sample; 
     sample n; // OK 
    } 
    sample u; // ERROR 
    return 0; 
}