C ++ from scratch (9) -- What is Structure

Source: Internet
Author: User

C ++ starts from scratch (9) -- what is the original structure? Source: Network

When the previous article describes programming, the first thing to do after obtaining the algorithm isResourcesIt is mapped to a number, and previously said, "type is the protocol for interpreting the binary numbers in the memory." That is to say, a number corresponds to a piece of memory (which may be 4 bytes, it may also be 20 bytes), and the number type is additional information to tell the compiler when an operation statement (that is, an operator) is found for that block of memory, how to Write machine commands to implement that operation. For example, if two char-type numbers are used for addition operators, the machine commands compiled by the compiler are different from those for two long-type numbers, that is, the so-called "how to interpret the binary number protocol in memory ". Due to different interpretation protocols, each type must have a unique identifier to indicate a difference, which provides strong semantics.

Typedef

Providing semantics means to reflect the meaning of this sentence or this piece of code in the human world as much as possible in the Code. For example, the previous article defines a cross-river scheme, which is represented by a char type, then, an array of char sln [5] is defined to reflect the solution from the variable name. But obviously, people looking at the Code may not be able to see that sln is the abbreviation of solution and then understand the significance of this variable. But more importantly, it seems like this is a red apple, and you know it is an apple, but it may also be a toy, CD, or something else, that is, the semantics to be embodied should be embodied by the type, rather than the variable name. That is, char cannot reflect the required semantics.
In this regard, C ++ provides a very meaningful statement-Type Definition Statement. The format is typedef & lt; source type name & gt; & lt; identifier & gt ;;. & Lt; source type name & gt; indicates an existing type name, such as char and unsigned long. & Lt; identifier & gt; Is a programmer's casual name that complies with the identifier rules and is used to express semantics. The preceding cross-river scheme can be as follows:
Typedef char Solution; Solution sln [5];
The above is actually an alias Solution for the type char, and then the Solution is used to define the sln to better reflect the semantics to increase the readability of the Code. In the previous article, the number of people on both sides of the Strait is mapped to char [4]. To enhance the semantics, you can:
Typedef char PersonLayout [4]; PersonLayout oldLayout [2, 200];
Note that the above is typedef char PersonLayout [4]; instead of typedef char [4] PersonLayout; because the array modifier "[]" is next to the defined or declared identifier, the pointer modifier "*" is connected to the front, so typedef char * ABC [4]; but not typedef char [4] ABC *;, because the type modifier has a fixed position in the definition or declaration statement.
The preceding figure shows a better semantic representation than char oldLayout [200] [4]. But does it reduce programming speed due to increasing the type name or variable name to reflect the semantics? If the coding process is too long, you will find that the programming time is not spent on coding, but debugging. Therefore, do not avoid writing long variable names or type names. For example, in the Win32 Security SDK, the following function name is provided:
BOOL ConvertSecurityDescriptorToStringSecurityDescriptor (...);
Obviously, this function is used to convert the Security Descriptor type into text form to facilitate people to view the information in the security descriptor.
Note that typedef not only creates an alias for the type, but also creates an original type. When writing char * a, B;, the type of a is char *, and B is char, rather than the expected char *. Because "*" is a type modifier here, it is independent of the declared or defined identifier, otherwise for char a [4], B ;, is B char [4]? That seriously does not conform to people's habits. The preceding char is called the original type. To make char * The original type, you can: typedef char * PCHAR; PCHAR a, B, * c [4];. Both a and B are char *, while c is char ** [4], so there is no problem: char ** pA = & ;.


Structure

Again, consider why the previous article maps the number of people layout into char [4], because the number of people can be expressed by a char, and the number of people layout has four people, so char [4] is used. That is to say, if char [4] is used to define only one variable, it represents a person's number distribution, and the compiler allocates four bytes of space on the stack at a time, and each byte represents a person's number. Therefore, to show the number of merchants on the left side of the riverbank, you must enter a [0], and the number of servants on the left must be a [1]. The disadvantage is obvious. From a [0], it cannot be seen that it represents the number of merchants on the Left Bank, that is, the ing meaning (the Merchant number on the Left Bank is mapped to the content of the first byte in the memory block, which is interpreted in the complement code format) cannot be reflected in the Code, reducing the readability of the Code.
The above is actually the need for memory layout, that is, how to explain the binary numbers of each byte in the memory block. For this reason, C ++ proposes the type definition character "{}". It is a pair of braces dedicated to defining a type in a definition or declaration statement, called a custom type. That is, the memory layout can be customized when the type originally provided by C ++ cannot meet the requirements. The format is: & lt; Type keyword & gt; & lt; Name & gt ;{& lt; declaration statement & gt ;...}. & Lt; Type keyword & gt; there are only three types: struct, class, and union. The so-called structure is the original type defined by the Type definer when the & lt; Type keyword & gt; Is struct. Its type name is & lt; Name & gt ;, it represents multiple declaration statements written in the braces below. The Defined variables are in a serial relationship (as described later), as follows:
Struct ABC {long a, * B; double c [2], d;} a, * B = &;
The above is a variable definition statement. For a, the compiler is required to allocate a 4 + 4 + 8*2 + 8 = 32-byte continuous memory block on the stack, then, bind the first address to a, and its type is structured custom type (Structure for short) ABC. For B, the compiler is required to allocate a 4-byte memory block, bind the first address to B, and its type is a pointer of the structure ABC.
When variables a and B are defined above, the structure ABC is defined by writing the type definition character "{}" in the definition statement. Then, you can use the type name ABC to define the variable as follows, you don't need to do that every time, that is:
ABC & c = a, d [2];
Now let's take a look at the above. First, the preceding statement defines six ing elements, with a and B mapped to two memory addresses respectively. The four variable declarations in braces also generate four variables named ABC: a, ABC: B, ABC: c, and ABC: d; the ing values are 0, 4, 8, and 24. Their types are long ABC:, long * ABC:, double (ABC: :) [2], and double ABC: :, indicating the offset. ABC: indicates a hierarchy, indicating "ABC", that is, ABC: a indicates the variable a defined in structure ABC. It should be noted that because C ++ is a strong type language, it also defines ABC: as a Type modifier, resulting in long * ABC: type, it indicates that the identifier it modifies is a member of the custom type ABC, called the offset type, and this type of number cannot be used separately (as described later ). Because the type shown here is not a function, the ing is not a memory address, but an offset value (as described in the next article ). Unlike before, numbers of the Offset type (that is, the above Type) cannot be calculated because the offset is a relative concept and no reference is given, that is, it cannot: ABC: a; ABC: c [1];. The latter is a serious error, because the array operator "[]" requires that the first is an array or pointer type, and here the ABC :: c is the offset of the double array structure ABC, not the array type.
Note that the offset 0, 4, 8, and 24 above is exactly the same as the offset formed by a, B, c, and d placement in the memory sequentially. This is also the modifier of the struct keyword, that is to say, the variables defined previously are in a serial relationship.
Why do we need to map the offset? That is, Why map a to zero-byte offset, and B to four-byte offset? Because semantics can be added to the offset. In the previous section, "The Merchant number on the Left Bank maps the content of the first byte in the memory block to be interpreted in the complement format" is actually the first address offset of the given memory block to 0 bytes. Now, if an identifier is bound to it, you can name it LeftTrader to express its semantics.
Since all the variables defined above are of the Offset type, there is no allocation of memory to map with them, and they normally cannot be of the reference type, that is, struct AB {long a, & B ;}; it will be wrong. Note that the double (ABC: :) [2] type modifier "ABC:" is enclosed in parentheses, because the type operator rules are interpreted from left to right, "ABC:" is actually interpreted, but it must be placed on the left of the identifier, it is the same as the pointer modifier "*", so it must be enclosed in parentheses to indicate that it is last modified. Therefore, double (* ABCD: :) [2] and double (** ABCD: :) [2] are defined as follows:
Struct ABCD {double (* pD) [2]; double (** ppD) [2];};
However, it should be noted that "ABCD:" cannot be used directly, that is, double (* ABCD: pD) [2]; is incorrect. to define a variable of the Offset type, you must use the "{}" type definition to customize the type. Note that C ++ also allows such a type double (* ABCD: *) [2], which is called a member pointer, that is, the type is double (* ABCD ::) the pointer of [2] can be as follows:
Double (** ABCD: * pPPD) [2] = & ABC: ppD, (** ABCD: ** ppPPD) [2] = & pPPD;
It is very strange to recall what the pointer type is. Only a number of the address type can have a pointer type, indicating that its binary representation, that is, the address, is directly returned without calculating the number of that address type. For a variable, the address is the number mapped to it, and the pointer directly returns the number mapped to it. Therefore, the number returned by & ABCD: ppD is actually an offset value, that is, 4.
To apply the preceding offset type, C ++ provides a pair of operators-member operators "." and "-& gt ;". The former is connected to numbers on both sides, the left is the address type Number of the custom type, and the right is the offset type Number of the corresponding custom type, returns the number of the address type given in the offset type, for example,. ABC: d ;. The type of a on the left is ABC, and the type of ABC: d on the right is double ABC:, then. ABC: d returns a number of the double address type. Therefore,. ABC: d = 10.0 ;. Assume that the address of a is 3000, then. ABC: d returns the address 3000 + 24 = 3024 and the type is double. That is why ABC: d is called the offset type. Because the structure type on the left side of "." should be the same as the structure type on the right side, the above ABC: can be omitted, that is, a. d = 10.0 ;. "-& Gt;" is the same as ".", except that the number on the left is pointer type, that is, B-& gt; c [1] = 10.0 ;. Note that B-& gt; c [1] is actually (B-& gt; c) [1] instead of B-& gt; (c [1]), because the latter uses "[]" for the offset type, it is wrong.
Pay attention to the following because of the Offset type on the right side:
Double (ABC: * pA) [2] = & ABC: c, (ABC: ** ppA) [2] = & pA;
(B-& gt; ** ppA) [1] = 10.0; (a. * pA) [0] = 1.0;
The above brackets are added because the array operator "[]" has a higher priority than "*", but why?

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.