2

我知道这个问题有一个 C++ 版本,但是我使用的是标准类型定义而不是模板。

我编写了一个适用于 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 中的运行时条件类型定义是不可能的?

[开放式问题:]如果没有,你们将如何处理这样的事情?

4

5 回答 5

5

typedef是一个编译器特性,你不能在运行时应用它。

于 2012-07-18T12:25:12.623 回答
3

程序中的所有类型在编译时都必须是已知的。

在 C++ 中,您可以为模板编译代码shortint使用模板;在 C 中,您可以使用宏(特别是 X 宏)来执行此操作。

将您的计算代码放在一个名为 eg 的单独文件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)然后您可以在其他地方使用它们。

于 2012-07-18T12:29:41.027 回答
2

首先,typedef 不是一种新类型,它是一个别名或缩写形式,使事情更方便(尤其是在使用函数指针时)

C 是一种静态语言,不能在运行时创建类型,需要在编译/链接时解析类型。

好吧,如果可能的话,Windows API 会小得多:)

在 Windows 中,它们对于大多数每个 API 调用都有两个版本的函数和一个决定使用哪个版本的定义。

例如

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

但同样,类型是在编译时决定的

于 2012-07-18T12:28:47.860 回答
2

另一方面,您typedef只能在某些范围内使用。

int 
main(void) {
    if (1) {
        typedef short sample;
        sample n; // OK
    }
    sample u; // ERROR
    return 0;   
}
于 2012-07-18T13:22:59.683 回答
0

C(和 C++)中的类型在编译时是固定的;“运行时typedef”的概念在 C 中没有意义。

但是,您的问题可以小心解决。您将定义两组函数(和类型),一组处理 16 位.wav文件,一组处理 32 位.wav文件。这些将在编译时定义,类型的大小将在编译时固定,但是这两个代码都将在可执行文件中,您将能够根据运行选择要执行的函数集-时间信息(要求您处理或生成的文件类型)。

你的两组函数应该是对称的。您也许可以使用一些“类似模板”的机制,以便将同一个文件编译两次,一次用于 32 位代码,一次用于 16 位代码,以确保函数名称的更改一致。

于 2012-07-18T12:30:37.213 回答