C语言中的嵌套结构

14

我需要建立一个嵌套结构来存储一些有关个人的基本信息(姓名,年龄,地址)。因此,我创建了一个名为“info”的结构,并创建了另一个名为“address”的嵌套结构以保存地址信息。但是每当我使用for循环提示存储值时,就会出现错误。问题在哪里?我该如何解决?

[错误]“struct Info”没有名为“address”的成员
[警告]声明未声明任何内容[默认情况下启用]

#include <stdio.h>

int main(){

    struct Info{
        char name[30];
        int age;
        struct address{
            char area_name[39];
            int house_no;
            char district[39];
        };
    };

    struct Info Person[10];

    int i;
    for(i=0;i<10;i++){

        printf("enter info of person no %d\n",i);
        printf("enter name\n");
        scanf("%s",&Person[i].name);
        printf("enter age\n");
        scanf("%d",&Person[i].age);
        printf("enter address :\n");
        printf("enter area name :\n");
        scanf("%s",&Person[i].address.area_name);
        printf("enter house no : \n");
        scanf("%d",&Person[i].address.house_no);
        printf("enter district : \n");
        scanf("%s",&Person[i].address.district);
    }
}

请注意在调用 scanf() 时不要使用 & 前缀字符串成员。如果包括 &,则传递的类型是 char (*)[30] 而不是 char *,但 %s 格式期望一个 char *。如果编译器设定足够严格(-Wall 应该足够),它会告诉您有类型不匹配,并应该注意。 (是的,在大多数实际机器上实际操作中,它可以正常工作 - 但这在某种程度上是巧合的; 存在类型不匹配,您应避免这些问题。) - Jonathan Leffler
5个回答

20

在结构体 Info 中声明了类型为 struct address 的结构体,但没有该类型的成员变量。

例如,您可以编写以下代码:

struct Info{
    char name[30];
    int age;
    struct address{
        char area_name[39];
        int house_no;
        char district[39];
    } address;
      ^^^^^^^^
};

10

你现在拥有的只是一个名为address的结构体的声明,但你需要在struct Info中创建一个叫做address变量,以便使用Person[i].address语法。

你需要稍微移动一下address这个词:

struct Info{
    char name[30];
    int age;
    struct {
        char area_name[39];
        int house_no;
        char district[39];
    } address; // <<< here it is now
};

另一个选择是使用以下内容:

struct Info{
    char name[30];
    int age;
    struct addr{ // as noted by @JonathanLeffler,
                 // it's not necessary to change the 
                 // name of a struct
        char area_name[39];
        int house_no;
        char district[39];
    };
    struct addr address; // <<< a variable of type struct addr
};

2
为什么要改名?结构标签与结构元素位于不同的命名空间中,因此 struct address { … } address; 是完全有效的 C 代码。 - Jonathan Leffler
@JonathanLeffler,当时我不太确定。但是,在阅读以下内容时,它可能有助于避免混淆:struct address address; - ForceBru

4

结构体 Info 有一个嵌套的 结构,名为 address,但没有名为 address 的成员变量。

您应该这样做:

struct Info
{
    ...
    struct
    {
        ...
    } address;
};

1
外部“结构体”中有一个名为“address”的结构。但它只是一个没有名称的匿名结构成员。这是自C99以来合法的语法。 - too honest for this site
1
@Olaf:标准规定(ISO/IEC 9899:2011 §6.7.2.1 ¶13):“类型说明符为结构体且没有标记的未命名成员称为匿名结构体;类型说明符为联合体且没有标记的未命名成员称为匿名联合体。匿名结构体或联合体的成员被视为包含结构体或联合体的成员。如果包含结构体或联合体也是匿名的,则递归应用此规则。”在问题中的原始声明中,struct address有一个标记,因此它不是匿名结构体成员。 - Jonathan Leffler
@JonathanLeffler:你能详细说明一下吗?我已经很久没有使用C89了。另一方面,它对于OOP来说太有用了,不能不使用它(尽管你必须显式启用它)- 当然,如果你有很好的文档记录。请参见此处 - too honest for this site
@Olaf:对此进行全面的阐述将很难适应评论。编译器警告(“声明未声明任何内容”)是准确的;它声明了一种类型,但该类型并没有立即使用。在C中,您可以在结构struct Info之后(外部、分开)创建一个类型为struct address的结构,但C++具有嵌套作用域。这是一种定义struct address;的古怪方式,但在语法上是合法的。通常,您会在struct Info的定义内部使用struct address { … } address;,这不会引起警告。_ […继续…]_ - Jonathan Leffler
你可以在struct Info中编写struct address { … }; struct address address;,这可能会引发警告。这些都是C89/90中有效的。在撰写我的初始评论之前,我不确定匿名结构和联合类型的规则是什么措辞。我可以看到可能有用于替代方案,但事实仍然是它改变了语法上有效(虽然不正统)的现有程序的含义,而标准委员会通常会尝试避免这种情况。 - Jonathan Leffler
显示剩余3条评论

1

0

这里是使用匿名结构体更新的代码。我启用了C11来编译它。

#include <stdio.h>

int main(){

    struct Info{
        char name[30];
        int age;
        struct {
            char area_name[39];
            int house_no;
            char district[39];
        };
    };

    struct Info Person[10];

    int i;
    for(i=0;i<10;i++){

        printf("enter info of person no %d\n",i);
        printf("enter name\n");
        scanf(" %s",Person[i].name);
        printf("enter age\n");
        scanf("%d",&Person[i].age);
        printf("enter address :\n");
        printf("enter area name :\n");
        scanf(" %s",Person[i].area_name);
        printf("enter house no : \n");
        scanf("%d",&Person[i].house_no);
        printf("enter district : \n");
        scanf(" %s",Person[i].district);
    }
}

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