How to access a struct member inside a union in C?

2020-06-14 04:39发布

I have the following union:

union employee
{
    char key;

    struct manager
    {
        short int age;
        float shares;
        short int level;
    };

    struct worker
    {
        short int age;
        short int skill;
        short int department;
    };

} company[10];

How can I access a member of a structure which is inside the union employee? I tried to access the age member of the manager structure this way:

company[i].manager.age

But I get error C2039: 'manager' : is not a member of 'employee'.

4条回答
来,给爷笑一个
2楼-- · 2020-06-14 05:05

Add something after the tag declaration. Perhaps:

struct manager
{
    short int age;
    float shares;
    short int level;
} manager;

Side note: you're not using the union right. The key, i.e. the field that tells you whether you are dealing with a manager or with a mere worker should be in an enclosing object, outside the union. Perhaps:

struct employee {
    char key;

    union {
        struct manager ...;
        struct worker ...;
    } u;
};

As dasblinkenlight notes, you could declare your manager / worker tags outside the union.

查看更多
看我几分像从前
3楼-- · 2020-06-14 05:10

this error is because you are trying to access the structure elements by the name of the structure itself, which is not valid. In order to access the elements of a structure, one should first create an object to it.

in the following code manage and work are the objects of the structure manager and worker respectively.

union employee { char key;

struct manager
{
    short int age;
    float shares;
    short int level;
}manage;

struct worker
{
    short int age;
    short int skill;
    short int department;
}work;

} company[10];

now to access the member u can use "company[i].manage.age"

查看更多
▲ chillily
4楼-- · 2020-06-14 05:11

You can access the members, the way you are trying( but the structures which are inside the union should have unique members) but you should make sure that while compiling the code gcc should know that you are trying like that,

command : gcc -fms-extensions file_name.c which supports from c11.

like :

union employee
{
char key;

struct manager
{
    short int age;
    float shares;
    short int level;
};

struct worker
{
    short int age;
    short int skill;
    short int department;
};
} company[10];

This basically gives compilation error because it finds ambiguity between the members of manager and worker.

So if you change your code to:

union employee
{
char key;

struct manager
{
    short int age;
    float shares;
    short int level;
};

struct worker
{
    short int age1;
    short int skill;
    short int department;
};

} company[10];

or else you can keep directly under union.

unless you don't specify -fms-extensions while compiling it will give compile time errors.

查看更多
小情绪 Triste *
5楼-- · 2020-06-14 05:14

Anonymous structs/unions is not part of the C standard, but rather a not very widespread GNU extension.

In your particular example some compilers (mainly GCC) will allow you to access manager and worker unique variables via e.g. company[i].shares or company[i].department, but company[i].age is ambiguous and the compiler will not know which one is meant. Your approach is similar to trying to define

 union {
      int num;
      float num;
 } union_number;

which is not even valid C.

there are two ways to solve this.

a) moving the shared attributes outside the struct (the evil GNU way, please don't do that, I know for a fact that icc does not even compile this)

union employee
{
    char key;

    struct person {
        short int age;

        union {
            struct manager
            {
                float shares;
                short int level;
            };

            struct worker
            {
                short int skill;
                short int department;
            };
        }
    };

} company[10];

b) or the more clean standardized way to name your structs:

union employee
{
    char key;

    struct manager
    {
        short int age;
        float shares;
        short int level;
    } manager;

    struct worker
    {
        short int age;
        short int skill;
        short int department;
    } worker;

} company[10];

in this case you will be able to access the struct elements via company[i].manager.age, company[i].worker.skill and so on.

Please pay attention that at runtime there is no way to test whether your union contains a key, a manager or a worker. That must be known in advance.

Another thing: I am not sure if this is intended, but in your declaration you cannot save a key together with a manager or a worker. Your union contains only one of key, manager or worker

查看更多
登录 后发表回答