Overview:
Structure and array are mainly two points, the first structure can be declared in a structure of different data types, followed by the same structure of the structural body face can be assigned to each other.
Both the common Body (union) and the struct are composed of several different data type members, but at any one point, the shared body value holds a selected member . And all members of the struct are present.
The C + + enumeration (enum) tool provides another way to create symbolic constants instead of const, which is a collection of enumerated constants.
3.1 struct struct
struct type variables are defined in the general form:
struct struct type name { Type 1 member name 1; Type 2 member name 2; ... Type N member name n; };
Defines the type of struct body. Only describes the composition of the type, and does not allocate memory space. The system allocates space to a variable of the struct type only if it is defined.
Here are a few things to note:
1) recursive definition of the struct itself is not allowed in the struct type definition. But you can use pointers to point to this type, the following definitions are most commonly used:
struct person{ Type 1 member name 1; Type 2 member name 2; ... Type N member name N; struct // pointer to this type };
2) The structure can be nested, that is, the structure definition can contain another structure.
3) struct variables can be redefined when the assignment is initialized (according to the order of declarations, the numerical and character types are not assigned the initial value, the system automatically assigns 0):
struct person{ char name[]; Char = {"zhangsan"'M'};
Bit fields in a struct
While some information is stored, it is not necessary to occupy a full byte, but only a few or a bits. To conserve storage space, C provides a data structure called bit field or bit segment .
C and C + + allow the development of struct members that occupy a specific number of bits. The type of the field is an integer or an enumeration, followed by a colon, followed by a number, which specifies the number of bits used, and a field without a name can be used to provide spacing. Each member is made a bit field.
the assignment cannot exceed the allowable range of the bit field, and when it exceeds, only the right side of the equal sign is worth the low value assigned to the bit field .
3.2 Common body
The defined form is:
Union common body Name { data type member name; Data type member name; ... Data type member name; } Variable name;
One of the uses of a common body is to save space when data items are used in two or more formats, but are not used at the same time.
Note: The structure may occupy more memory than the sum of the members ' memory, and the pooled memory will occupy the maximum of the members.
The order in which the pooled union is stored is that all members are stored from the low address (also the struct), which is often examined along with the small-end storage format and the big-endian storage format.
large -End storage Format (Big-endian): High bytes of data are stored in low addresses, while low bytes are stored in high addresses;
Small -End storage Format (Little-endian): Low bytes of data are stored in low addresses, while high bytes are stored in high addresses.
For example: The number of 32bit 0x12345678 assumed to be stored starting from address 0x4000
Little-endian:
Memory address |
0x4000 |
0x4000 |
0x4001 |
0x4002 |
Store content |
0x78 |
0x56 |
0x34 |
0x12 |
Big-endian:
Memory address |
0x4000 |
0x4000 |
0x4001 |
0x4002 |
Store content |
0x12 |
0x34 |
0x56 |
0x78 |
The difference is that the order in which the bytes in the word is stored is different, and the order in which the characters are stored is the same.
We often use the X86 structured small-end mode, while Sun's SPARC uses the big-endian model.
As the following example (small end system):
Union Student { int i; Char ch[2];}; int Main () { Student Student; 0x1420 ; printf ("%d %d", student.ch[0], student.ch[1 ]); return 0 ;}
The result of the output is: 32 20.
In a small terminal system, Hex 20 is stored at the low address, and hex 14 is stored at the high address. Because the union member is stored from a low address, the content in ch[0] is hexadecimal 20, that is, the content in decimal 32;ch[1] is hexadecimal 14, which is the decimal 20.
In the next example, assuming that in a 32-bit environment, the CPU is in Little-edian mode and all parameters are passed with the stack, the following output is:
int Main () { longlong123; printf ("%d %d %d\n", A, b, c); return 0 ;}
Answer: 1 0 2. First, a long long is 8 bytes, int is 4 bytes, the last element of the printf function is first in the stack, that is, C first, then B, a, the case of this stack is:
0x01000000 |
0x00000000 |
0x02000000 |
0x00000000 |
0x03000000 |
0x00000000 |
The left side is the top of the stack, the right side is the bottom, because it is litte-edian, so the low byte is the word address. Output, first output stack top, at this time the output format is%d, output only 4 bytes, that is, 1, 0, 2.
3.3 Enumeration
The basic format for the definition is:
enum enum-type name {enum-constant 1[=-shaped constant], enumeration constant 2[=-shaped constant], ...} [List of variable names]
Note: If you do not assign an initial value, the compiler assigns a different integer value for each enumerated constant (when a constant in the enumeration table is assigned a value, the subsequent member determines its value once in order plus 1).
enum Color {red, orange, yellow, Green, blue};
In the example above, the Red~blue are 0~4 respectively.
3.4 sizeof operator
The usual test in the written examination.
sizeof is a single-mesh operator, not a function. The storage size of its operands is given in bytes .
It should be kept in mind that sizeof's calculations occur at compile time, so it can be used as a constant expression, ignoring the various operations within its parentheses, such as sizeof (a++), where "+ +" does not execute.
How to use 3.4.1 sizeof
1) for variables
2) for data type
In fact, the size of the sizeof object is also converted to the calculation of the object type, that is to say, the sizeof value of different objects of the same type is the same.
Where C99 specifies that a function, an expression of an indeterminate type, and a bit-field member cannot be computed by the sizeof value:
1)intFoo () {return 1;} sizeof(foo);//error, function name cannot be computed2)voidFoo2 () {}sizeof(Foo2 ());//error, the return type is void, the type cannot be determined3)intFoo3 () {return 1;} sizeof(Foo3 ());//the size of sizeof (int) is returned correctly, but the function is not called4)structs{unsignedintF1:1; unsignedintF2:5; }; sizeof(S.F1);//error, bit domain member cannot calculate sizeof value
Results of 3.4.2 sizeof
Typically in a 32 or 64-bit compilation environment:
sizeof (char): 1
sizeof (short): 2
sizeof (int): 4
sizeof (LONG): 4
sizeof (float): 4
sizeof (double): 8
sizeof (*P): 4 (64 bit is 8)
Spatial computation of 3.4.3 struct
The spatial computation of a struct is more complex and generally follows two principles:
1) The overall space is an integral multiple of the number of bytes occupied by the largest member (the type of the space) (LINUX+GCC environment exception, when the maximum type is more than 4, also need to be a multiple of 4).
2) Data Alignment principle----the memory is arranged in the order of the struct members, and when the member variable is queued, the size of the space before it must be an integer multiple of the size of the member type, if not enough. Backwards and forwards in turn (Linux is still the exception).
The first example is as follows (WIN32 environment):
structS1 {CharA; Doubleb; intC; CharD;};structS2 {CharA; Charb;; intC; DoubleD;}; cout<<sizeof(S1) <<endl//Statement 1cout<<sizeof(S2) <<endl//Statement 2
Statement 1 output 24, statement 2 output 16. Because statement 1 is aligned at the time of the second double, it takes three double lengths, and statement 2 needs to be aligned in the 4th double, requiring only two double lengths.
1. Spatial calculation of structures with structural bodies
struct S3 { char C; int i;}; struct S4 { char C1; S3 S; Char C2;}; cout<<sizeof// statement 1cout<<sizeof// Statement 2
Statement 1 output 8, statement 2 output 16.
When a struct contains a struct, such as in this example, the S3 is a sub-structure, S4 is the parent structure, the above two principles should be changed to:
1) The overall space is an integer multiple of the number of bytes (the type of the child) that occupies the largest space in the parent structure (the special case in Linux).
2) Data Alignment principle----The parent structure is in the order of the members of the structure, and when the member of the sub-structure, the size of the space in front of it must be an integer multiple of the maximum type size of the member of the substructure, if not enough then aligned, followed by the analogy (Linux under special case).
2. Spatial calculation of structures with arrays
In structs, arrays are placed in a single variable, rather than as a whole.
struct S1 { char a[8]; int b;};
sizeof (S1) results in 12, the number of elements in a single placement, if the order of A and B is reversed, the result is still 12.
3. Spatial computation of structure with bit domain
The primary role of the bit domain is to press the wrong storage, so different compilations have different compression methods to save space.
Because bit-domain members cannot take the sizeof value individually, it is possible to discuss sizeof with a struct with a bit field, with the following rules.
1) If the adjacent bit field field is of the same type and its bit width is less than the size of the type sizeof, the subsequent field will be stored next to the previous field until the position cannot be accommodated.
2) If the adjacent bit field field is of the same type, but its bit width is greater than the size of sizeof of type, then the subsequent field will start from the new storage unit, with an offset of an integer multiple of its type size.
3) If the adjacent bit domain field type is different, the specific implementation of the compiler differs, VC6 take the non-compression method, dev-c++ and GCC to take the compression method.
4) If the bit field fields are interspersed with non-bit field fields, no compression is done.
5) The total size of the entire struct is an integer multiple of the size of the widest base type member.
Take a look at the following examples to understand more profoundly:
struct a { int3; Char b; Char c;};
A The answer is: 4 F1 only occupies 3 bits, less than one byte, the back can continue to place.
struct B { char3; Char 4 ; Char 5 ;};
b The answer is: the 2-bit domain type is char, the first byte can only tolerate F1 and F2 (8 bits is a byte), so F2 is compressed into the first byte. F3 can only start with the next byte.
struct C { char3; Short 4 ; Char 5 ;};
C The answer is: 6 or 2 adjacent bit field type is different, the result of rule 3,vc6 is 6,DEV-C++/GCC compression, the result is 2.
struct d { char3; Char F2; Char 5 ;};
The D answer is: 3 because non-bit field fields are in it, rule 4 is not compressed.
4. Calculation of structure space when using "#pragma pack"
In general, you can change the default alignment criteria by using the following method:
Using the pseudo-directive #pragma pack (n), the compiler will align N bytes;
Use pseudo-Directives #pragma pack () to cancel custom byte alignment.
The usual usage:
#pragma pack (n), n is a byte-aligned number, the value 1, 2, 4, 8, 16, and so on, the default is 8, if this value is smaller than the sizeof value of the struct member, then the member's offset should be based on this value, that is, the structure member's offset should take the minimum value , The size of the struct should also be an integer multiple of the maximum value in all offsets.
#pragma pack (push) // Save the current pack by setting the stack to #pragma Pack (2) // must be used before struct definition struct S1 { char C; int i;}; struct S2 { char C2; S1 s; char C3;}; #pragma Pack (pop) // Restore the previous pack settings
In the above example, when sizeof (S1) is calculated, C takes one byte and then min (2, sizeof (i)) has a value of 2, so the offset of I is 2, plus sizeof (i) is 6, can be divisible by 2, so sizeof (S1) is 6.
For sizeof (S2), S has an offset of 2,c3 of 1,C2 for one byte, then a byte is left blank, and sizeof (C3) equals 9, cannot be divisible by 2, and a byte padding is added, so sizeof (S2) is 10.
5. Size of the empty structure
The size of "empty struct" (excluding data members) is not 0, but 1!!!
Spatial computation of 3.4.4 Union
Structs are sequential in the memory organization, the unions are overlapping, and each member shares a memory, so sizeof, the entire consortium, is the maximum value of each member sizeof.
struct S1 { double b;}; Union u { int i; Char C; s1 s;};
In the above example, sizeof (U) is 8 (the Union also needs to consider the alignment, the alignment principle is the same as the struct).
3.4.5 Enumeration of spatial computations
An enum simply defines a set of constants with no "elements", and the enumeration type is stored as an int type, so the sizeof value of the enumeration type is 4.
enum Number{one, three, four} num;
Then sizeof (number) and sizeof (NUM) are all 4.
To this, about the written test of sizeof related knowledge points are said almost, the difficult part is mainly Big-endian and Little-endian storage, multi-painting can be written out, the most important thing is to distinguish between categories, a little calculation, I hope you can have some gains *. *
Back to the directory-C + + basic Knowledge overview
[Basic C + +] 3. Struct, common body, enumeration