缺少typedef关键字的结构体

8

我目前正在学习C语言中的struct数据结构以及如何在其前面加上typedef关键字。这将导致实际结构的变量名被放置在不同的命名空间中,如多个引用所解释的那样:

C++中"struct"和"typedef struct"之间的区别?

typedef struct与struct定义之间的区别

然而,对于我正在处理的示例,究竟发生了什么还不清楚:

#include <stdio.h>

struct demo
{
    short low_pass_vcf;
    short filter_coupler;
    short reverb;
    short sequential;
} synth;

int main() 
{    
    printf("Size of struct: %i\n", sizeof(struct demo));
    printf("Size of struct: %i\n", sizeof(synth));
    return 0;
}

在这个例子中,我可以通过变量名“synth”访问“struct”数据结构;然而,在我看到的例子中,为了能够做到这一点,“struct”需要以“typedef”为前缀。在这个例子中,没有使用“typedef”,但我仍然能够通过“synth”引用这个结构。我想知道C语言是如何允许我这样做的?任何解释都将不胜感激。谢谢。

你熟悉 typedef 的作用吗? - ameyCU
1
sizeof 返回一个 size_t 类型的结果。size_t 值的正确格式字符串是 %zu,而不是 %i(适用于 int)。 - Keith Thompson
感谢提供 size_t 信息。据我所知,typedef 所做的是在单独的命名空间中创建一个变量,使得可以在不需要使用 struct demo 的情况下引用该结构体。不确定是否还有其他操作在幕后进行。 - Adam Bak
5个回答

12
struct demo
{
    short low_pass_vcf;
    short filter_coupler;
    short reverb;
    short sequential;
} synth;

等同于:

// declare struct demo
struct demo
{
    short low_pass_vcf;
    short filter_coupler;
    short reverb;
    short sequential;
};

// define struct variable synth
struct demo synth;

现在您可以访问结构体成员,例如:
synth.sequential = 1;

sizeof(struct demo) 返回 struct demo 的大小。

sizeof(synth) 返回具体实例 synth 的大小。

在这种情况下,两者返回相同的大小。

更新:

使用 typedef,它可能看起来像这样:

// declare new type demo
typedef struct demo
{
    short low_pass_vcf;
    short filter_coupler;
    short reverb;
    short sequential;
} demo_t;

// define demo_t variable synth
demo_t synth;

更新2:

来自Linux内核编码风格

Chapter 5: Typedefs

Please don't use things like "vps_t". It's a mistake to use typedef for structures and pointers. When you see a

vps_t a;

in the source, what does it mean? In contrast, if it says

struct virtual_container *a;

you can actually tell what "a" is.


6
typedef关键字在C语言中的struct类型中是不必要的。它唯一的优点是可以为类型创建一个单词名称。
在您的示例中声明如下:
struct demo
{
    /* ... */
} synth;

实际上是两个声明,一个是类型为struct demo的声明,另一个是以该类型命名为synth的对象的声明。也许更明确地写成两个单独的声明:

struct demo
{
    /* ... */
};

struct demo synth;

第一个声明创建了一个新的结构类型,名为struct demo。第二个声明定义了该类型的一个对象,名为synth
在这些声明中,标识符demo本身是无意义的;它是一个结构标记,只有在前面加上struct关键字时才有意义。
另一方面,synth是一个对象(变量)的名称。它不需要并且实际上也不能在前面加上struct关键字。
如果你愿意,你可以添加一个typedef来为类型struct demo取一个别名。(typedef并不定义一个新类型;它仅为现有类型定义一个新名称,一个别名。)例如,一个常见的用法是:
typedef struct demo {
    /* ... */
} demo;

与您最初的声明一样,这实际上是两个声明:一个struct定义创建了类型struct demo,而typedef则为该类型创建了一个新名称demo。它可以写成:

struct demo {
    /* ... */
};
typedef struct demo demo;

如果您喜欢的话,可以跟着一个对象声明:
demo synth;

(请注意,结构体标签和typedef名称无需不同,并且在我看来,它们相同更为清晰。)
使用 typedef 来定义结构类型的选择基本上是风格问题。我的个人偏好是不为结构体使用 typedef ; struct demo 已经有一个非常好的名字。但是很多程序员更喜欢一个只有一个标识符的名称。

1
我能够通过变量名“synth”访问“struct数据结构”,但是在我看到的示例中,为了能够这样做,“struct”需要加上“typedef”的前缀。
不,不是你想的那样。并不是因为有了“typedef”,你才能通过“synth”访问结构成员。
在这个例子中,没有使用“typedef”,但我仍然可以通过“synth”引用这个结构。
这是因为“synth”本身就是一个“struct变量”,所以你可以访问结构的成员。
“typedef”是C语言中用于为现有类型分配替代名称的关键字,主要用于用户定义的数据类型。
例如:
typedef struct A{
     char B;
     int C;
 }D ;

在这里,D 可以用来声明结构体变量。

没有 typedef -

struct demo
{
   short low_pass_vcf;
   short filter_coupler;
   short reverb;
   short sequential;
}synth;

synth 是一个结构体变量,你可以访问结构体的成员。但是在没有 typedef 的情况下,如果你想声明结构体变量,你必须像这样声明 -

 struct demo t;

无论哪种情况,即使您删除了typedef,您仍然可以使用synth访问结构体,typedef在其中没有任何作用。

0

这与您声明的相同:

int i;

然后做了这个:

printf("Size of int: %i\n", sizeof(int));
printf("Size of int: %i\n", sizeof(i));

这两行代码将打印相同的值。
如果你有这个:
typedef struct demo
{
    short low_pass_vcf;
    short filter_coupler;
    short reverb;
    short sequential;
} mydemo;

mydemo synth;

你可以这样做:
printf("Size of struct: %i\n", sizeof(struct demo));
printf("Size of struct: %i\n", sizeof(mydemo));
printf("Size of struct: %i\n", sizeof(synth));

他们也会打印相同的东西。


0

typedef关键字: 定义结构体或创建的类型可以有更简单的方法,你可以“别名”它们。例如:

typedef struct
{
   char  title[50];
   char  author[50];
   char  subject[100];
   int   book_id;
}Books;

现在,您可以直接使用Books来定义Books类型的变量,而无需使用struct关键字。以下是示例:
Books Book1, Book2;

您可以像下面这样使用typedef关键字来定义非结构体:

typedef long int *pint32;

pint32 x, y, z;

x、y 和 z 都是指向长整型的指针


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