I used to be confused about the use of the common Body Union when I was learning C language at school. After work to discover some of its magical, now for example:
1. To facilitate the understanding of the code.
For example, to write a 3 * 3 matrix, you can write this:
[Note: The following parts marked with red are added later, thanks to Yrqing718 's reminder.] ]
struct Matrix {union {struct {float _f11, _f12, _f13, _f21, _f22, _f23, _f31, _f3 2, _f33; }; float f[3][3]; }_matrix; }; struct Matrix m;
These two things use the same space, so there is no space to waste, when the need for the whole matrix can be used
M._MATRIX.F (for example, a parameter, or a whole assignment, etc.), you can use a few of these elements to avoid using m._matrix._f11 like m.f[0][0] (this is not intuitive, and error prone).
2. Use on coercion type conversion (easier to read than forced type conversions)
Here are a few examples:
(1). Judge whether the system is using big endian or little endian (its definition can be found on the Internet to check the relevant information, this slightly)
#define TRUE 1 #define FALSE 0 #define BOOL int
BOOL Isbigendian () {int i = 1; /* i = 0x00000001*/char c = * (char *) &i; /* Note cannot be written as char C = (char) i; */return (int) c!= i; If it is little endian byte order, that I = 1, the memory from small to large in turn is: 0x01 0x00 0x00 0x00, if, in accordance with the starting address of I into the char * Mode (1 bytes) access, that is C = 0x01;
Vice versa
Maybe it doesn't look very clear, so here's a look at this:
BOOL Isbigendian () {union {int i; char c; }test; test.c = 2; return test.i!= 2; }
There is a union to control the shared layout, and there is a knowledge that the members C and I in the Union are aligned from the low address. The same result can be achieved without conversion and clarity.
What, don't feel clear. Let's look at the following example:
(2). Replace the long type value under little endian with the value of the big endian type. It has been known that the system provides the following Api:long htonl (long LG), which replaces all byte sequences with big-endian byte sequences. The following approach is therefore drawn:
Long long  HTONLL (long long lg) { union { struct { long low; long high; }val_1; long long val_2; }val_arg, val_ret; if ( isbigendian () ) return lg; val_arg.val_2 = lg; val_ret.val_1.low = htonl ( val_arg.val_1.high ); val_ret.val_1.high = htonl ( val_arg.val_1.low ); Return val_ret.val_2; }
It is easier to understand the sketch of the memory structure as long as it is drawn.
(3). To understand the layout of C + + classes, look at one of the following examples. There are the following classes:
class test {public: float getfval () { return f;} private: &nbs P; int i; char c; float f; }; Test T;
The
Cannot add code in class test to assign a value of 7.0f to F in the object.
Class test_cpy { public: float getval () { return f;} & Nbsp; float setval (float f) { this->f = f;} private: int i; char c; float f; }; ... int main () { Test t; union { Test t1, Test_Cpy t2; }test; test.t2.setval (7.0f); t = test.t1; assert ( t.getval () == 7.0f ); return 0; }
Description: Because when you add a member function of a class, the layout of that class's objects is basically the same. So you can write a class test_cpy with the same structure as the test class, and you can assign a value to a private variable by having a member function Setval and then aligning with the Uinon structure. (This method may fail when there is virtual machine class and virtual function mechanism, so it is not portable) as far as detailed discussion is concerned, this example is not useful in practice, but is used to examine the use of this memory layout. The
Union is much more used in code at the bottom of the operating system because it is convenient and intuitive in the memory-sharing layout. So the network programming, the Protocol analysis, the kernel code some uses the union to compare understood, simplifies the design.