为什么我们会在花括号中省略一些结构体变量?

41

我正在尝试理解C语言中的struct。我无法理解下面这个定义的意思。为什么我们要把aCarddeck[ ]*cardPtr排除在外呢?将它们包含进去和排除在外有什么区别?

 struct card {
    char *face;
    char *suit;
 } aCard, deck[52], *cardPtr;

15
这只是声明风格比较随意,同时使用了“Linux 风格”的结构体,而不是更常用的typedef struct { } card_t;... card_t card; - Lundin
8
代码难以阅读,不直观,虽然功能正确但不如@MichaWiedenmann改写后易读。易读的代码更为重要。 - Trevor Boyd Smith
2
@Lundin 或者甚至只是 struct card { ... } ... struct card drawn;(这是我更喜欢的方式,但这更多是样式问题) - anon
2
@Lundin:有不使用typedef结构体的好理由。这并不是“懒散”的表现;Linux之所以这样做是有原因的 - wchargin
1
@wchargin:再读一遍他们的评论。Lundin说它是松散的和没有typedef,而不是因为它没有typedef就松散。在我看来,这里松散的是结构布局和变量声明的组合。 - Eric
显示剩余6条评论
6个回答

74
你把事情搞混了。一个 struct card 有成员 facesuit。但是有三个变量使用了 struct card 类型,分别为 aCard, deck, cardPtr
或者也可以这样写:
typedef struct {
    char *face;
    char *suit;
} Card;

Card aCard, deck[52], *cardPtr;
// or even
Card aCard;
Card deck[52];
Card *cardPtr;

关于 typedef,可以看一下:为什么在C语言中我们经常使用typedef定义结构体?(它涉及到了typedef struct { ... } Foo;struct Foo {...}的辩论)。


是的,关于是否使用typedef的争论仍在继续。但为什么要引入原问题中不存在的东西呢?这只会让答案更加复杂。很抱歉,出于这个原因,我会给你的回答点个踩,并且会支持Jabberwocky的回答 - Jonathon Reinhart

28

你的代码可以写成这样,更清晰易懂:

struct card {          // define the struct card
    char *face;
    char *suit;
 };

struct card aCard;     // declare a variable "aCard" of type "struct card "
struct card deck[52]   // declare an array of 52 variables of type "struct card"
struct card *cardPtr;  // declare a variable "cardPtr" of type "pointer to struct card"

20
尽管这个问题已经被回答了,但我发布我的答案是因为我认为提问者对结构声明和结构类型变量的定义存在疑惑。
如果您不知道C语言中什么是结构体,请参阅下面的1)
关键字struct引入了一个结构体声明,它是一系列用大括号括起来的声明。可以在struct后跟一个可选的名称,称为结构标记。因此,这是一个结构声明:
struct card {
    char *face;
    char *suit;
 };

这里的facesuit成员变量。请注意,结构声明不会保留任何存储空间;它只是描述了一个结构的模板。

结构声明定义了一种类型。终止成员列表的右括号后面可以跟一个变量列表。所以,在你的情况下:

....
} aCard, deck[52], *cardPtr;

aCarddeck[52]*cardPtrstruct card 类型的变量。

由于结构体声明被标记为 card,因此在定义结构体实例时可以在后面使用该标记。例如,给定上面的结构体声明:

struct card someCard;

定义了一个变量someCard,它是struct card类型的结构体。

或者,您可以使用typedef声明并将其用于定义其类型的变量。


1)

根据定义 - 结构体是一组一个或多个变量的集合,可能是不同类型的,在单个名称下分组在一起。

根据C标准#6.2.5 [Types]:

结构类型描述了一组按顺序分配的非空成员对象(在某些情况下为不完整数组),每个对象都具有可选指定的名称和可能不同的类型。

.....
.....
算术类型和指针类型统称为标量类型。数组和结构类型统称为聚合类型。46)


1
简而言之,OP代码中的整个“struct foo {...}”与“int i, j, k;”或“float x, y, z;”中的int或float是一样的。 - jamesqf

6

A

struct card {
    char *face;
    char *suit;
 }

它就像 int 一样,但它是用户自定义的,并且

aCard, deck[52], *cardPtr;

变量名是指变量的名称,例如:

int aCard, deck[41], *cardPtr;

3
“struct card”和“int”确实都是类型,但它们并不等同。我想要澄清这一点,因为我认为这个答案可能会被一些初学者或英语不流利的人误解。 - Robin Goupil

1
你声明了三个变量。 aCard 是类型为 struct card 的,deck 是类型为 struct card[52] 的,而 cardPtr 是类型为 struct card * 的。

0

aCard和你提到的其余变量都是struct card类型的变量,每个变量都包含char *facechar *suit。那么如何让某个变量包含自身,即aCard在结构体节点中。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接