C样式结构声明

时间:2011-07-25 05:21:21

标签: c struct

我有一个关于C风格结构的快速问题。我正在挖掘一些示例代码并找到以下列方式声明的结构:

typedef struct _STRUCTNAME
{
   // struct contents
} STRUCTNAME;

请注意STRUCTNAME第二次显示缺少下划线。我的理解是,这将声明一个名为STRUCTNAME的_STRUCTNAME,并且不能再实例化此结构的对象。

然而,情况似乎并非如此。除了在一个地方之外,这种类型的结构从未在代码中实际实例化:在随机位置使用的此类对象的全局数组中:

const struct STRUCTNAME ARRAYNAME[] = 
{
   // various STRUCTNAMEs declared here
};

请注意再次缺少下划线(我认为是实例化对象的名称?)

我的理解完全消失了吗?

有人可以解释一下吗?

5 个答案:

答案 0 :(得分:7)

typedef struct _STRUCTNAME
{
   // struct contents
} STRUCTNAME;

这段代码做了两件事:

  1. 定义名为struct _STRUCTNAME
  2. 的结构
  3. 创建名为typedef的结构的STRUCTNAME
  4. 这样做的原因是,在适当的C代码中,您以其他方式声明struct(如上所述)的方式如下:

    struct _STRUCTNAME structInstance;
    

    但是,在typedef到位的情况下,您只需使用以下内容:

    STRUCTNAME structInstance;
    

    enum声明也是如此。

答案 1 :(得分:4)

STRUCTNAME是typedef名称。

_STRUCTNAME是结构的'标签',它位于不同的名称空间中。

在ANSI标准化之前,结构标记命名空间在许多编译器中并不是独立的,因此为了防止名称与typedef名称冲突,它必须是不同的。但是,由于标准化,标签名称不需要不同。

你看到这个习惯用法经常在Windows代码中使用,毫无疑问,因为在SDK的许多例子中都是这样。雷蒙德陈写了一篇关于它的博客文章:

此外,我确信会有一些关于如何为实现保留_STRUCTNAME标识符的评论,因此在任何情况下使用该表单都不是一个好主意。

答案 2 :(得分:2)

Michael Burr说:

  

此外,我确信会有一些关于如何为实现保留_STRUCTNAME标识符的评论,因此在任何情况下使用该表单都不是一个好主意。

好的,我是游戏(但我想要一些格式化,所以你得到一个答案):

语言标准是编译器 - 编写者和编译器 - 用户之间的契约,每个人都承诺这样做而不做某些事情。

_开头的大多数标识符都是为实现保留的 - 包括以_开头的所有标识符,后跟大写字母。这意味着允许编译器编写者将它们用于任何目的,因为编译器用户已承诺不使用它们。

违反承诺的编译用户会得到奇怪的结果。

相反,[适用]标准不为实现保留的所有标识符都保证可供编译器用户使用,因为编译器 - 编写者已承诺不使用它们。

当有效代码获得奇怪的结果时,违反承诺的编译人员会获得退款要求。

我的偏好是在标记名称上添加一个尾随_,包括警卫等,以确保我不在实现的空间内;因此:

typedef struct STRUCTNAME_
{
   // struct contents
} STRUCTNAME;

(有些纯粹主义者在typedef上皱眉只是语法糖,但C在这里和那里需要一点糖,否则它看起来很平淡。)

答案 3 :(得分:0)

我相信你的困惑是为什么 struct定义末尾的标识符列表没有实例化实例。原因是您已添加typedef关键字。

考虑typedef的syantax:

typedef type-definition identifier;

您所做的是struct作为类型定义。您正在定义类型,而不是创建实例。将此约束为实例化结构只是定义内联类型的实例:

struct STRUCTNAME
{
   // struct contents
} myStruct, *ptr, alsoMyStruct;

如果不包含typedef关键字,标识符将照常指定实例。

答案 4 :(得分:0)

const struct STRUCTNAME ARRAYNAME[] = 
{
   // various STRUCTNAMEs declared here
};

上面的代码不会为数组的不完整类型编译。我认为它应该是错误的

const struct _STRUCTNAME ARRAYNAME[] = ...

或者,您可以在不指定struct keyword

的情况下使用typedef
const STRUCTNAME ARRAYNAME[] =