Kev*_*lar 12 c typedef objective-c
我很好奇当typedefing一个枚举或结构时,这里的区别是什么.这两个块之间在语义上有什么区别吗?
这个:
typedef enum { first, second, third } SomeEnum;
Run Code Online (Sandbox Code Playgroud)
还有这个:
enum SomeEnum { first, second, third };
typedef enum SomeEnum SomeEnum;
Run Code Online (Sandbox Code Playgroud)
结构相同的交易.我已经看到两者都在使用,他们似乎都在C或Objective-C中做同样的事情.是否存在真正的差异,或者只是偏好您可以使用哪种风格?
AnT*_*AnT 15
不同之处在于第二种方法声明了一个名为的类型,enum SomeEnum并且还声明了一个typedef-name SomeEnum- 该类型的别名.它实际上可以组合成等效的单行程
typedef enum SomeEnum { first, second, third } SomeEnum;
Run Code Online (Sandbox Code Playgroud)
这很明显,两种方法之间的唯一区别在于enum关键字后面是否有名称.使用第二种方法,您可以使用SomeEnum e或者enum SomeEnum e,无论您喜欢哪种方式声明该枚举类型的对象.
第一种方法仅为SomeEnum最初的匿名枚举类型声明typedef-name ,这意味着您仅限于SomeEnum e声明.
因此,只要您SomeEnum在声明中仅使用typedef-name ,两者之间就没有区别.但是,在某些情况下,您可能必须使用该类型的完整原始名称enum SomeEnum.在第一种方法中,该名称不可用,因此您将失去运气.
例如,如果在上述声明之后,您还声明了SomeEnum在某个嵌套范围中命名的变量
int SomeEnum;
Run Code Online (Sandbox Code Playgroud)
变量的名称将隐藏枚举的typedef-name,从而使此声明非法
SomeEnum e; /* ERROR: `SomeEnum` is not a type */
Run Code Online (Sandbox Code Playgroud)
但是,如果在声明枚举时使用第二种方法,则可以使用完整类型名称解决此问题
enum SomeEnum e; /* OK */
Run Code Online (Sandbox Code Playgroud)
如果在声明枚举类型时使用第一种方法,则无法实现这一点.
当与结构一起使用时,struct当你需要一个自引用类型(一个包含指向同一类型的指针的类型)时,必须使用该名称,例如
typedef struct SomeStruct {
struct SomeStruct *next;
} SomeStruct;
Run Code Online (Sandbox Code Playgroud)
最后,在第二种方法中,typedef名称是完全可选的.你可以简单地宣布
enum SomeEnum { first, second, third };
Run Code Online (Sandbox Code Playgroud)
并且只需在enum SomeEnum每次需要引用此类型时使用.
是的,存在语义差异.第二个片段声明了标记标识符,但第一个标识符没有.两者都声明一个普通的标识符.
这意味着,对于第一个,此代码无效,但对于第二个,它是:
enum SomeEnum foo;
Run Code Online (Sandbox Code Playgroud)
据我所知,代码中它们之间没有其他语义差异.对于结构和联合,递归类型需要第二种形式,可能与一个声明中的typedef结合使用
typedef struct node {
struct node *parent; // refer to the tag identifier
} node;
Run Code Online (Sandbox Code Playgroud)
普通标识符在struct的说明符中尚不可见,因此您需要通过已声明的标记标识符来引用该结构.标签标识符通过在"struct","union"或"enum"之前加上它们来引用,而普通标识符在没有前缀的情况下引用(因此名称为"普通").
除了将引用结构,联合和枚举的标识符与引用值的标识符分开时,标记标识符对于创建前向声明也很有用:
/* forward declaration */
struct foo;
/* for pointers, forward declarations are entirely sufficient */
struct foo *pfoo = ...;
/* ... and then later define its contents */
struct foo {
/* ... */
};
Run Code Online (Sandbox Code Playgroud)
Typedef名称不能在同一范围内重复声明(与C++相反),并且它们需要引用现有类型,因此它们不能用于创建前向声明.
| 归档时间: |
|
| 查看次数: |
4517 次 |
| 最近记录: |