为什么在C中使用typedef声明嵌套结构会导致错误?

dkqlctbz  于 2023-04-11  发布在  其他
关注(0)|答案(2)|浏览(232)

在我的一堂C语言课上,老师使用的是struct而不是typedefstruct,当我尝试时,显示了一个错误,而这堂课没有显示任何错误

#include <stdio.h>

typedef struct {
        char city[30];
        int hno;
        int pincode;
} address;

typedef struct {
        char name[30];
        int id;
        int salary;
        address a;
} employee;

int main(void) {
        employee e;
        scanf("%s %i %i %s %i %i", e.name, &e.id, &e.salary, e.a.city, &e.a.hno, &e.a.pincode);
        printf("%s %i %i %s %i %i\n", e.name, e.id, e.salary, e.a.city, e.a.hno, e.a.pincode);
        return 0;

}

而这个确实显示了一个错误,为什么呢?

#include <stdio.h>

typedef struct {
        char name[30];
        int id;
        int salary;
        typedef struct {
                char city[30];
                int hno;
                int pincode;
        } address;
        address a;
} employee;

int main(void) {
        employee e;
        scanf("%s %i %i %s %i %i", e.name, &e.id, &e.salary, e.a.city, &e.a.hno, &e.a.pincode);
        printf("%s %i %i %s %i %i", e.name, e.id, e.salary, e.a.city, e.a.hno, e.a.pincode);
        return 1;

}

我的逻辑是不是

typedef struct {
        // members of the structure
} name of the new variable;

声明了一个名为“新变量的名称”的新数据类型?

gwbalxhn

gwbalxhn1#

正如我在评论中指出的,简洁的答案是:
你不能有嵌套的typedef。从语法上讲,typedef是一个存储类,你不能把一个存储类放在一个结构定义中。
我认为最好参考C标准- §6.7声明作为一个整体,特别是§6.7.1存储类和§6.7.2.1结构和联合说明符。
根据§6.7.2.1,struct-or-union-specifier的语法是:

struct-or-union-specifier:
            struct-or-union identifier-opt { struct-declaration-list }
            struct-or-union identifier
    struct-or-union:
            struct
            union
    struct-declaration-list:
            struct-declaration
            struct-declaration-list struct-declaration
    struct-declaration:
            specifier-qualifier-list struct-declarator-list-opt ;
            static_assert-declaration
    specifier-qualifier-list:
            type-specifier specifier-qualifier-list-opt
            type-qualifier specifier-qualifier-list-opt
    struct-declarator-list:
            struct-declarator
            struct-declarator-list , struct-declarator
    struct-declarator:
            declarator
            declarator-opt : constant-expression

在我转录的-opt作为后缀的地方,标准中有opt作为下标,这意味着标记的元素是可选的。
此规则的关键组件是specifier-qualifier-list,它可以由一个或多个type-specifier项和一个或多个type-qualifier项组成。您需要查看§6.7的其他部分,以发现§6.7.2定义:

  • type-specifier-基本类型,如intchar,以及更特殊的类型,如struct-or-union-specifier

§6.7.3定义:

  • type-qualifier-constrestrictvolatile_Atomic之一。

请注意,typedef不是这些项目之一。(请注意:typedef-name出现在type-specifiers的列表中,但这是一个标识符,而不是关键字typedef
根据§6.7.1,项storage-class-specifier定义为:

storage-class-specifier:
            typedef
            extern
            static
            _Thread_local
            auto
            register

第5段说:
5 typedef说明符被称为“存储类说明符”只是为了语法上的方便;在6.7.8中进行了讨论。
因此,我在评论中使用了“语法上”这一限定词。
根据§6.7,声明的语法是:

declaration:
            declaration-specifiers init-declarator-list-opt ;
            static_assert-declaration
declaration-specifiers:
            storage-class-specifier declaration-specifiers-opt
            type-specifier declaration-specifiers-opt
            type-qualifier declaration-specifiers-opt
            function-specifier declaration-specifiers-opt
            alignment-specifier declaration-specifiers-opt
init-declarator-list:
            init-declarator
            init-declarator-list , init-declarator
init-declarator:
            declarator
            declarator = initializer

在一般的declaration中,可以有一个storage-class-specifier
2在声明中的声明说明符中最多只能给出一个存储类说明符,但_Thread_local可以与static或extern.120一起出现。
脚注参考§6.11.5,其内容为:
将存储类说明符放置在声明中声明说明符的开头以外的位置是一个过时的功能。
因此,typedef(或externstatic等)应该首先出现在声明中。
所有这些都表明,C语法不允许typedef出现在结构声明的中间,就像您在失败的示例中尝试做的那样。

xj3cbfub

xj3cbfub2#

作为一个建议,你可以使用struct代替,像这样

typedef struct {
        char name[30];
        int id;
        int salary;
        struct address {
                char city[30];
                int hno;
                int pincode;
        } add;
} employee;

相关问题