C / C ++ typedef / structs中的冗余命名

时间:2010-04-13 14:52:48

标签: c++ c

#include <stdio.h>
#include <string.h>

const int NAMELEN=30;

const int MAXCLASSSIZE=10;

typedef struct StudentRec {
    char lastname[NAMELEN];
    char firstname[NAMELEN];
    long int ID;
    int finalmark;
}Student;

我刚接触编码......我对为什么有学生有疑问;在括号之后..是我们必须遵循的格式。

5 个答案:

答案 0 :(得分:17)

你搞糊涂了两件事。在C中,您可以定义如下结构:

struct foo {
    int a, b;
};

然后使用你必须这样做:

struct foo myFoo;

这真的很罗嗦,因此他们有了使用typedef制作新类型的绝妙想法。我可以这样做:

typedef int myInt;

然后使用它:

myInt x;

所以你正在做的是声明有一个新类型Student,它相当于一个结构StudentRec。按照惯例,很多人对typedef使用与struct相同的名称 - 这是合法的:

typedef struct foo { int a, b; } foo;

答案 1 :(得分:13)

这是创建一个typename“Student”来表示结构。在C ++中不需要使用typedef来实现此目的。它可以这样定义:

struct Student {
    char lastname[NAMELEN];
    char firstname[NAMELEN];
    long int ID;
    int finalmark;
};

答案 2 :(得分:4)

在C中,结构名称和类型名称(例如int)有不同的名称空间{类型名称空间与变量和函数名称空间共享,所以要注意这一点}。定义新结构时,会自动将其名称添加到struct命名空间,但是当您声明该类型的变量时,必须在其名称前加上struct,以便编译器知道查看struct命名空间以查看究竟是什么让你想要这个变量。

使用typedef关键字可以将变量的名称添加到类型命名空间中,这样就不必在声明中使用struct关键字。

您提供的示例将typedef声明与struct定义结合使用,但在类型命名空间和struct命名空间中对结构使用了不同的名称。您可以这样做有两个原因。首先,使用typedef为与变量声明完全相同的语句添加前缀定义了typename而不是具有指定名称的变量。其次,您可以通过在结构声明和分号之后立即包含它们的名称来声明结构类型的变量。你的例子结合了这些。

在C中还有其他合法形式。例如:

/* This declares a variable foo whose type has no name but is a struct that contains one int named x */
struct {
    int x;
} foo;

/* This adds bar to the type namespace without adding an entry to the struct namespace. */
typedef struct {
    int y;
} bar;

/* This adds the name baz to the struct namespace and declares a variable named b of this type */
struct baz {
    int z;
} b;

/* This adds the name ralf to the type namespace which also refers to this type */
typedef struct baz ralf;

C ++有不同的命名空间结构,我确信你已经注意到它,因为它有namespace关键字。在这种情况下,尽管C ++比C更简单。定义结构(或类或联合或枚举)会自动将您使用的名称(如果有)添加到typedef为其添加名称的名称空间中。这在很大程度上简化了事情,但是有一些问题。这些主要与保留与C的向后兼容性有关。大多数情况下,这种兼容性与注意某人typedefs struct foo foo;并且不将其视为尝试使用已使用的名称命名的错误有关。

另一个问题是这类相当常见的C代码:

struct shoe {
    int size;
} shoe;

这在C中很常见,特别是当只需要存在一个结构时。在C中,这很容易,因为struct shoe和变量shoe的名称之间不会发生冲突。在C ++中,这仍然可以保持与C的向后兼容性。

答案 3 :(得分:1)

这些都不适用于C++。在C++首选:

struct Foo
{
   . . .
};

其余仅适用于C

从技术上讲,struct Foo {};足以满足大多数用途。但是,使用类型Foo时必须重复使用struct,这有点冗长。

struct Foo {}

void func( struct Foo* foo );

typedef使这更简单。

struct Foo { };
typedef struct Foo Foo;
void func( Foo* foo );

这可以通过以下方式进一步缩短:

typedef struct Foo { } Foo;
void func( Foo* foo );

当做一个班轮时,也可以使用这种语法:

typedef struct { } Foo;
void func( Foo* foo );

这是创建一个匿名struct,然后给它命名为Foo。您最常使用enum s。

typedef enum { } Bar;

有一个原因,通常有多余的Foo留在那里。它只是创建自引用结构的唯一方法,如链表。

typedef struct Node
{
   Node* next;
} Node;

如果ommited的初始Node将无法声明指向struct的指针。从技术上讲,这也是有效的,但现在你必须提出两个名字,而不只是一个。

typedef struct node_
{
   node_* next;
} Node;

为什么要使用:

typedef struct Foo { } Foo;

为了统一。这种声明风格涵盖了你的所有基础,因此在声明结构时你永远不必考虑它。

答案 4 :(得分:0)

Student是typedef创建的新类型的名称。 StudentRec是它定义的结构的名称。