为什么这个C代码中的结构有两个名称?

时间:2015-01-10 00:24:50

标签: objective-c c

我从书中学到的一些示例代码" Learning Core Audio"像这样......

typedef struct MySineWavePlayer
{
  AudioUnit outputUnit;
  double startingFrameCount;
} MySineWavePlayer;

为什么" MySineWavePlayer"在这段代码中两次?

2 个答案:

答案 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;
}

source

答案 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;

首先简短回答MySineWavePlayerstruct的名称,而第二个是typedef d类型的名称。