20. Custom types: enumerations and unions

1 Enumeration type

1.1 Declaration of enumeration types

example:

enum Day//week
{<!-- -->
 Mon,
 Tues,
 Wed,
 Thur,
 Fri,
 Sat,
 Sun
};
enum Sex//gender
{<!-- -->
 MALE,
 FEMALE,
 SECRET
};
enum Color//Color?
{<!-- -->
 RED,
 GREEN,
 BLUE
};

The enum Day, enum Sex, and enum Color defined above are all enumeration types. The contents in {} are possible values of the enumeration type, also called enumeration constants. These possible values are all valid, starting from 0 by default and increasing by 1 in sequence. Of course, you can also assign an initial value when declaring an enumeration type, for example:

#include <stdio.h>
enum Color//Color?
{<!-- -->
    RED=2,
    GREEN=4,
    BLUE=8
};
int main()
{<!-- -->
    printf("%d\
", RED);
    printf("%d\
", GREEN);
    printf("%d\
", BLUE);
return 0;
}

Output result:

The external link image transfer failed. The source site may have an anti-leeching mechanism. It is recommended to save the image and upload it directly.

1.2 Advantages of enumeration types

Originally we could use #define to define constants, why do we have to use enumerations?

Enumerations have the following advantages:

  1. Increase code readability and maintainability.
  2. The identifier defined by #define has no type, while the enumeration has type checking, which is more rigorous.
  3. The preprocessing phase will delete symbols defined by #define, but enumeration types will not, which makes debugging easier.
  4. Easy to use, multiple constants can be defined at one time.
  5. Enumeration constants follow scoping rules. Enumerations are declared within a function and can only be used within the function.

1.3 Use of enumeration types

enum Color//Color?
{<!-- -->
RED=1,
 GREEN=2,
BLUE=4
};
enum Color clr = GREEN;//Use enumeration constants to assign values to enumeration variables

Note: In C language, you can assign integers to enumeration variables, but not in C++. C++’s type checking is stricter.

2 Union type

2.1 Declaration of union type

//Declaration of union type
union Un
{<!-- -->
char c;
int i;
};

2.2 Characteristics of union types

Like a structure, a union is also composed of one or more members. These members can be of different types, but the characteristic of a union is that all members share the same memory space, and the compiler >Only allocate enough memory space for the largest member, so the union is also called: union.

example 1:

#include <stdio.h>
union Un
{<!-- -->
char c;
int i;
};
int main()
{<!-- -->
union Un un = {<!-- --> 0 };//Definition of union variables
printf("%d\
", sizeof(un));
printf("%p\
", & amp;un);
printf("%p\
", & amp;(un.c));
printf("%p\
", & amp;(un.i));
return 0;
}

Output result:

The external link image transfer failed. The source site may have an anti-leeching mechanism. It is recommended to save the image and upload it directly.

Example 2:

#include <stdio.h>
union Un
{<!-- -->
char c;
int i;
};
int main()
{<!-- -->
union Un un = {<!-- --> 0 };
un.i = 0x11223344;
un.c = 0x55;
printf("%x\
", un.i);
return 0;
}

Output result:

The external link image transfer failed. The source site may have an anti-leeching mechanism. It is recommended to save the image and upload it directly.

From the output of Example 1, we can see that the variable c and the variable i occupy the same memory space, and the member i occupies the largest memory, so the size of the entire union is 4 bytes.

In Example 2, since the members of the union share the same memory space, if you assign a value to one member of the union, the values of other members will also change accordingly. We can pass the following unMemory layout diagram to deepen understanding:

The external link image transfer failed. The source site may have an anti-leeching mechanism. It is recommended to save the image and upload it directly.

2.3 Calculation of consortium size

? The size of the union is at least the size of the largest member.

? When the size of the largest member is not an integer multiple of the maximum alignment number, it must be aligned to an integer multiple of the maximum alignment number.

example:

//What is the result output below?
#include <stdio.h>
union Un1
{<!-- -->
char c[5];
int i;
};
union Un2
{<!-- -->
short c[7];
int i;
};
int main()
{<!-- -->
printf("%d\
", sizeof(union Un1));
printf("%d\
", sizeof(union Un2));
return 0;
}

Output result:

The external link image transfer failed. The source site may have an anti-leeching mechanism. It is recommended to save the image and upload it directly.

Analysis:

#include <stdio.h>
union Un1
{<!-- -->
char c[5];
int i;
};
//The size of the largest member is 5, which is not an integer multiple of the maximum alignment number (4), so it is aligned to 8.
union Un2
{<!-- -->
short c[7];
int i;
};
//The size of the largest member is 7, which is not an integer multiple of the maximum alignment number (4), so it is aligned to 16.
int main()
{<!-- -->
printf("%d\
", sizeof(union Un1));
printf("%d\
", sizeof(union Un2));
return 0;
}

2.4 Application of union type

For example, for an event, a gift exchange order needs to be launched online. There are three types of products in the gift exchange order: books, cups, and shirts.

Each product has: inventory, price, product type and other information related to the product type.

Book: title, author, number of pages;

cup: design;

Shirts: Designs, Available Colors, Available Sizes.

If we use a structure to implement:

struct gift_list
{<!-- -->
 //Public properties
 int stock_number;//inventory quantity
 double price; //pricing
 int item_type;//item type
 
 //Special properties
 char title[20];//book title
 char author[20];//Author
 int num_pages;//Number of pages
 char design[30];//Design
 int colors;//Color
 int sizes;//size
};

Although the above design is very simple and easy to use, the structure design contains various attributes of all gifts, which makes the memory occupied by the structure relatively large and wasteful. Because for the products in the gift redemption order, only some attribute information is commonly used. For example, if the product is a book, there is no need for design, colors, and sizes, so we can write the public attributes separately, and the remaining attributes belonging to the various products themselves are stored in a union, which can reduce the required memory space.

struct gift_list
{<!-- -->
int stock_number;//inventory quantity
double price; //pricing
int item_type;//item type
union {<!-- -->
struct
{<!-- -->
char title[20];//book title
char author[20];//Author
int num_pages;//Number of pages
}book;
struct
{<!-- -->
char design[30];//Design
}mug;
struct
{<!-- -->
char design[30];//Design
int colors;//Color?
int sizes;//size
}shirt;
}item;
};

2.5 Exercise

Baidu written test question: Design a small program to determine the byte order of the current machine.

//Use union to determine the byte order of the system
#include <stdio.h>
int check_sys()
{<!-- -->
union//Because we only use un once, we can use anonymous form here.
{<!-- -->
char c;
int i;
}un = {<!-- --> .i = 1 };
return un.c;
}

int main()
{<!-- -->
int ret = check_sys();
if (ret == 1)
printf("Little endian storage\
");
else
printf("Big endian storage\
");
return 0;
}

Output result:

The external link image transfer failed. The source site may have an anti-leeching mechanism. It is recommended to save the image and upload it directly.