我从书中学到的一些示例代码" Learning Core Audio"像这样......
typedef struct MySineWavePlayer
{
AudioUnit outputUnit;
double startingFrameCount;
} MySineWavePlayer;
为什么" MySineWavePlayer"在这段代码中两次?
答案 0 :(得分:11)
这是一个常见问题,通过解释在定义结构时使用typedef与不使用typedef之间的区别来解答。
常见习语是同时使用:typedef struct X { int x; } X;
它们的定义不同。为了使讨论更清楚,我将分开句子:
struct S { int x; };
typedef struct S S;
在第一行中,您将在结构名称空间中定义标识符S
(不是在C ++意义上)。您可以使用它并通过将参数类型定义为struct S
来定义新定义类型的变量或函数参数:
void f( struct S argument ); // struct is required here
第二行在全局名称空间中添加了一个类型别名S
,因此您只需编写:
void f( S argument ); // struct keyword no longer needed
请注意,由于两个标识符名称空间不同,因此在结构和全局空间中定义S
不是错误,因为它不是重新定义相同的标识符,而是在不同的位置创建不同的标识符
使差异更明显:
typedef struct S { int x; } T;
void S() {} // correct
//void T() {} // error: symbol T already defined as an alias to 'struct S'
您可以定义一个具有相同结构名称的函数,因为标识符保存在不同的空格中,但是您无法定义与typedef同名的函数,因为这些标识符会发生碰撞。
在C ++中,它略有不同,因为定位符号的规则已经巧妙地改变了。 C ++仍保留两个不同的标识符空间,但与C不同,当您只在类标识符空间中定义符号时,不需要提供struct / class关键字:
// C++
struct S { int x; }; // S defined as a class
void f( S a ); // correct: struct is optional
搜索规则有哪些更改,而不是定义标识符的位置。编译器将搜索全局标识符表,但在找不到S
后,它将在类标识符中搜索S
。
之前呈现的代码行为方式相同:
typedef struct S { int x; } T;
void S() {} // correct [*]
//void T() {} // error: symbol T already defined as an alias to 'struct S'
在第二行中定义S
函数之后,编译器无法自动解析结构S,并且要创建对象或定义该类型的参数,您必须回退到包含结构关键字:
// previous code here...
int main() {
S();
struct S s;
}
答案 1 :(得分:3)
在这种情况下实际上不需要第一个,如果你写这个,第二个是typedef
struct MySineWavePlayer
{
AudioUnit outputUnit;
double startingFrameCount;
};
然后你需要做这样的事情来声明struct
的一个实例struct MySineWavePlayer mySineWavePlayer;
然后你可以这样做
typedef struct MySineWavePlayer MySineWavePlayer;
然后宣言将成为
MySineWavePlayer mySineWavePlayer;
所以原来的那个
typedef struct MySineWavePlayer
{
AudioUnit outputUnit;
double startingFrameCount;
} MySineWavePlayer;
是这些的组合。
你甚至可以为{匿名结构
做typedef
typedef struct
{
AudioUnit outputUnit;
double startingFrameCount;
} MySineWavePlayer;
首先简短回答MySineWavePlayer
是struct
的名称,而第二个是typedef
d类型的名称。