Pointer and its semantics and use

xiaoxiao2021-03-06  59

Pointer and its semantics and use

This article is an attachment of "C from the beginning" series. Because the friend repeatedly considered "C from the scratch" series to the pointer to the pointer too much, the concepts of each concept were mixed, and there were fewer use of the important concepts in this C in the pointer, The key points illustrate the number, address, pointer and other basic concepts proposed in the "C zero" series, and give the semantics of the pointer, the relationship between the pointers and arrays, explain the multi-level pointer, multi-dimensional array, function pointer, array pointer The semantics of members' pointers and their respective use.

Numbers, operators, types, type modifiers

In "C from zero (3)", it has been explained, in fact, the CPU continuous binary number does not know, it can only handle the state, and the state it can handle exactly use the binary number, so that the CPU only knows the binary number. It should be noted that since the CPU knows the binary number is to understand the state represented by it, it is not a binary number in the sense of mathematical sense, and therefore the CPU does not know the decimal number 20. However, after 20% of the math rules to the binary number 10100, the designer of the luck of the CPU will add the addition instruction to the state 10100 and the state 10100 to obtain state 101000, and this binary number is converted to a decimal number according to the mathematical rules. Is 40, that is, the CPU connection and subtraction and division will not change the state in different ways, and the CPU design personnel defines the modifications of those states into mathematics, which makes the CPU as if Will be adjusted and removed. So, in order to let the CPU execute an instruction, the things involved in the instruction can only be a binary number, and there must be a rule to convert the number of mathematics in the mathematical sense to a binary number. As the rules of the decimal turnover, the original code, complement, IEEE REAL * 4, which mentioned in "C from zero (2)". To write C code, be sure to reflect the above conversion rules in the code, and to be able to reflect the number of mathematics in the code to be converted, so the compiler can determine the CPU to operate according to our writing code. Bi - one representation of something. In this regard, the C is used in the previous type, with a digital manifestation, use the operator to represent the CPU instruction, which is the transformation of the CPU state. Therefore, in order to make the CPU perform an addition instruction, the code is written on both sides of the operation - " ", " " on both sides of " ", " ", and the number of numbers determine how the mathematics representing the number Number conversion to binary number. Note that the numbers are the concept of the compilation level, not the concept of the code level, that is, the number cannot be expressed on the code, but only the number of calculations of the operator can be obtained. Because any operator returns a number (not returned to the number of operators can also be represented by returning the number of VOID to meet this method), and the most common americ operator is usually referred to as a constant. Things, such as 6.3, 5.2F, 0772, etc. I am in "C from scratch (2)", it is called a digital confusion, in this special clear. Note that as long as it is something that returns a number is the operator, so the previous constant is an operator. For variables, members variables, and functions, they have repeatedly emphasized them in the "C from the zero" series, they are all mapping elements, directly writing variable names, member variable names, and function names will return the numbers of each mapping, namely variable name functions. Wait is also an operator. The numbers are type, C provides custom type struct, Class, etc. from defining complex types, but not only, C also provides a more worthything - type modifier. In "C from zero (5)", the type modifier is used by the modified type, that is, the digital conversion rules characterized by the modified type (called original type) according to some rules. Such as pigs, blood sheep blood and pork lamb, "blood" and "meat" are type modifiers, changing their own original types - "pig" and "sheep". The above feels more like the latter to modify the former, such as "blood" in pig blood, "pig" is attributive. That is, the type modifier is actually a digital conversion rule that is characterized by the original type of information. This is called "blood", "meat" is a thing, but also a type is a pointer type, reference type, array type, function type, and so on.

The following types of modifiers are made in "C from the zero" series - reference "&", pointer "*", array "[]", function ", function call rule" __stdcall ", offset" :: ", constant" const "and address type modifiers. The address type modifier is the most confusing. In "C from zero (3)", the address has been described in the 32-bit operating system, which is often represented in a 32-bit long binary number to uniquely identify a particular memory unit. And a number of numbers is when the address type (because there is a address type modifier, it seems that a number is an array type), indicating a number of binary binary in mathematics represented by this number to identify a memory unit. Then, according to the original type of rules, the content of the memory unit and its subsequent units (the length of the type may be more than one byte, and the address type is a type modifier, so there is a original type). Since the number of variable mappings is actually address, the number mapped in variables is the address type. Such as long a;, assuming that A map is 3006, when writing A = 3;, since A is a variable name, returns a number 3006 mapped in A. The type is the address type of the long type. Since it is the address type, "=" operator syntax inspection success (this is another type of type of type - syntax check, it is like a nameless adjective), executes the calculation of "=" operators. Note that C does not propose the concept of address type modifiers, just for the completeness of the grammatical, otherwise more unnecessary concepts and rules, such as * (p 1) = 20; a [2] = 3; The interpretation will be complicated, so the concept of the address type in the "C from the zero" series is intended to explain as much as possible in the same way as possible. The most common type of modifier - pointers and arrays

The pointer is only one type modifier in "C from zero (5)". A number is a pointer type, and the number of mathematics represented by this number is represented and returned. The use of the number that has been said to convert the number of binary numbers, and its type only shows how to transform, and the rules represented by the pointer type are the number of binary numbers, regardless of its original type. Since the type of pointer is always fixed due to the influence of the original type (not necessarily the member pointer), it is four bytes on the 32-bit operating system. Such as long a; long * p = & a ;. Suppose A map is 3006, and P is mapped 3010. For * p = 3;, P This operator returns the number 3010 of the address type of the type of LONG type, that is, the type of this number is modified twice by two type modifiers. Since it is finally modified by the address, 3010 is The number of the address type, and its original type is the pointer type of the LONG. Therefore, * p returns the number 3006 of the type of address type for the type long, and then executes the calculation of the "=" operator. Here you should pay attention to the two operators - take the content operator "*" and the address operator "&". It also emphasized in "C from scratch (5)", and their real name is not true, and should be called the type conversion operator. That is, the front, the number of the pointer type, the number returned, and the type is turned to the address type; the number of the rear of the address type, the number returned, the number is not moving, and only its type becomes a pointer type. This is a little smart feel, but please pay attention to: long * p1 = 0; long * p2 = & * p1; if "*" is to take content, then & * P1 will first take the address of the memory unit of 0 0, This will cause memory access violation, but it doesn't actually, because "*" is only converted to the type and is not taken (the content is implemented by the calculation of the number of address types). As previously explained, when the number of the pointer type returns a binary number, the original type of participation is not required, that is, the number of binary numbers returned by the number of LONG *, the number of binary numbers returned by the number 3006 of CHAR *, is 3006 correspondence. Binary number. So why do you want the pointer to a type modifier to bring an unused original type? According to the previous, the original type of the pointer type is to give the content operator "*". But it is also useful, because the addition of array type modifiers makes pointers a so-called computing function, first look at the array type. The modification function of the array is described in detail in "C from zero (5)" is to repeat multiple elements of the original type to create a new type. Such as long a [10];, a type is long [10], the length is 10 * sizeof (long) = 40 bytes, while the length of the CHAR [7] type is 7 * sizeof (char) = 7 One byte. A number of numbers is an array type, because the length of this number can be one byte, can be 10,000 bytes, so the number must be stored in a block memory, and the number of binary numbers returned by the array type is its The first address of the memory stored. So the constant mentioned earlier cannot return an array type number because it does not give a number of memory to store the number of array types. It is a bit confusing here, paying that the numbers are not necessarily stored by memory.

For long a [3] = {45, 45, 45};, it is assumed that the number A map is 3000, indicating the number recorded by the memory unit 3000 in line [3], the length of this number is 3 * Sizeof (long) = 12 bytes, its value is determined by the array type as the length variable and determines that it represents it, the number of 3 values ​​is 45. So, a; first return the number 3000 of the LONG [3] type address type, then calculate the number of this address type and return the number of the original type, because the original type is long [3], and this number is stored in 3000 identity The memory is, so the last two binary numbers corresponding to 3000 are returned. It is easy to find that the pointer returns an address. The array is also an address. When their original type is the same, the latter can be implicitly converted to the former, but it can't, because the array has the number of elements, that is, long [2] The original type of long [3] is the same, but the type is different. So there are: long a [3]; long * p = a; There is no problem here, assuming that A map is 3000, then the value of P is 3000. Therefore, * p = 3; is in the 0th element of the array type of the 3000 stored in 3000. In order to put it in the first and second elements, C provides a so-called pointer calculation function, as follows: * (p 1) = 4; * (p 2) = 5 ;. The 4 is placed in the first element, 5 is placed in the second element. For * (p 1) = 4;, p returns a number 3000 of a long *, while P 1 returns the number 3004 of the long * and then proceeds. Similarly, the P 2 returns the number of types of long * 3000 2 * SizeOf (long) = 3008. That is, the pointer can only be reduced, such as: char * p1 = 0; p1 ; p1 = p1 5 * 8 - 1; short * p2 = 0; p2 = 11; P2 - The value of the upper P1 is 40 The value of P2 is also 40, because the original type of P1 is char and P2 is Short. Therefore, in order to obtain the value of the second element of the array, * (p 2) is required; this is obviously inconvenient to read, for this, C provides a subscript operator "[]", its front admir type The numbers, the square brackets put a total number, replace the numbers of the pointer type to the address type, and then return the value to the pointer arithmetic rule to return. Such as long a [4]; long * p = a; Then a [2] = 1; equivalent to * (p 2) = 1;, a [2] front connection is the number 3000 of the long * type (implicit type conversion, from long [4] to long * ), Plus 2 * sizeof (long), return 3008, and the type simply turns into a LONG type address type. Because "[]" is just a simplified version of the pointer operation, it can also be A [-1] = 3; and it is equivalent to * (p - 1) = 3; Due to "[]" front pointer, it can also be p [-1] = 3;, equivalent to A [-1] = 3; Repeative modification of type modifiers - multi-level pointers and multi-dimensional arrays

In the previously mentioned modifier, only three type modifiers of pointers, arrays, and offsets can be continuously repeated. Offset repeat modification to indicate the type nested, the pointer repeats the modification is referred to as multi-stage pointers, and the array repetition is called a multi-dimensional array. This looks like it is more complicated. It doesn't have it, just remember: Type modifier, a new type of formation, is considered to be the type of original type. Long ** P ;. The number of p mapping is a number of address types of a long **, then P; the number of numbers returned is long **. For * p; the type of the numbers returned to the P returned as the pointer type, the original type of long *, so the type of the number returned by * P is the number of the address type of long *, while ** P; Then return the number of the LONG address type. For long a [2] [3]; also. Since its original type is long [3], long (* p) [3] = a;, then A [1] is returned to the number of address types of long [3], and A [1] [2] The returned is the number of the address type of the LONG. Note Why is A's original type is not long [2] but long [3]. In "C from zero (5)", it has been explained that when multiple type modifiers are simultaneously modified, the modified order is from left to right, and the same continuous modifier is modified from right to left to conform to human habits. And "()" reduces the modification priority. Such as long * [2] [3] is the array of long pointer type [3] type [2] type, that is, it is an array type, there are two elements, the original type is long * [3]. That is, "[2]" finally modified, the lowest priority (from the type of number thereof, it can also be considered to be the highest). And Long * [3] * [2] [3] is a wrong type, although there is no problem with the left to right, but when C specifies the variable definition, the pointer type modifier must be in the variable On the left side of the name, the array type modifier must be in the right side to conform to human reading habits, and therefore "()" will appear in the type "()" to reduce the modification priority. So long * [3] * [2] [3] should be written as long * (* [2] [3]) [3], want to define variables long * (* p [2] [3]) [3]; The last modified "[2]" (not "[3]" is from right to left and right from left to right due to the same continuous modifier. Therefore, P is an array with two elements. The original type is long * (* [3]) [3], and long * (* (* pp) [2] [3]) [3] = & p; no Question, because finally modified "*", and the original type is long * (* [2] [3]) [3]. In addition to this, you should pay attention to one thing - no matter what multi-level pointer, its length is 4 bytes (this is for 32-bit operating system, but the member pointer may not only 4 bytes), but the number of dimensions of the array Many, the longer the length of the type (of course, if the number of elements is 1, the length is not changed). Such as long *** p; then only assigns 4 byte memory space, and long a [2] [3] [5]; assigns 2 * 3 * 5 * Sizeof (long) = 120 bytes Memory space. As follows: long * p = & a, ** pp = & p; long b [2] [3] [4]; assuming that the above A map is 3000, then P is mapped 3004, PP map 3008, B map 3012.

After the value is assigned, the value of A is 0, the type is long; the value of P is 3000, the type is length 3004, the value of PP is 3004, the type of long **; B is 3012, the type is long [2] [ 3] [4]. For * (* (PP 1)) = 5;, the PP returns a number 3004 of the type long **, and the length of the original type long * is 4 bytes, so the PP 1 returns the number of type long ** 3008, and * (PP 1) only converts type, return the number 3008 of the type of address type of long *, return the type of LONG * number 3004, so * (* (pp 1)) Return the type of LONG Number 3004 of the type, * (* (PP 1)) = 5; then put 5 according to the storage rule identified by the LONG to the memory identified by the 3004, the value of P is 5 and no longer 3000 (luck Good 5 is a positive number, at this time, the digital conversion rules and long * is the same), and then, if you continue * p = 1; will make an error (you should pay attention to the hypothesis the compiler order to place A, P and PP, which in turn makes PP The address is more than P. 4. Different compilation settings and compilers will not necessarily place local variables in order, * (* (pp 1)) = 5; it will be possible to fail). For * (* (* (* (* (B 1) 1) 1) = 5; B return type is long [2] [3] [4] number 3012, the original type is long [3] [4], Then B 1 will first make implicit type conversion to convert 3012 to long (*) [3] [4], and sizeof (long [3] [4]) = 48 bytes, then B 1 will return the type For the number 3012 48 = 3060 of long (*) [3] [4], * (b 1) returns the number of address types of LONG [3] [4], and then returns the type long [3 Number 3060 of [4]. Then * (b 1) 1 Return to the number of type long (*) [4] 3060 sizeof (long [4]) = 3076, the same, * (* (* (b 1) 1) 1) Returns the number of address types of the LONG type 3076 sizeOf (long) = 3080, and 5 is placed in the memory identified by 3080. According to the front pair "[]", it is known to know * (* (* (b 1) 1) 1) = 5; equivalent to B [1] [1] [1] = 5; Question. It should be noted that although B is a multi-dimensional array, it is still a continuous memory space. Why have you have multi-level pointers and multidimensional arrays? Long a [3] [4]; and long a [12]; all assign a continuous 48-byte memory space, what is the difference? When will I use when used former? At the "C from the zero" series, you emphasize to write programs in semantics, so you can use them as long as the semantics of the pointers and arrays can be used. Array semantics and use - vector and containers

One type, consists of several identical elements, which is the semantics of the array type modifiers. This is just that the vector in the linear algebra, such as the point coordinates on the two-dimensional plane are two-dimensional vectors. Assume that Double is used to record the component of point coordinates, then Double A [2] can be considered to define a two-dimensional point coordinate, if you want more readability, you can typef Double Point_2D [2]; Point_2d A; In practice, it is easy to find that the array actually implements a collection, which can be used as a container to record multiple identical types. At this point, the semantic-vector-have been ignored on the type, the focus is the array variable defined, that is, the focus is no longer POINT_2D, but a. Such as: Double Container [300]; it is no longer a type through the variable name. The container is written as a Double Container [300]; it is not enough because it cannot know which elements are valid which is invalid, so other variables are needed to complete the basic functions of a container together. For this, a class is often prepared to hide the details of the basic functions of the container, which is semantically called containers, which are generally referred to as a container class or a collection class, such as container type vector in STL. This type is also referred to as a package class for array Container. What is the semantics of the multi-dimensional group? What is the meaning? This is actually very simple, because the array is a type modifier, do not need to take a one-dimensional or multi-dimensional, only use it to know that it is a type of elements of the original type. For example, long a [2] [3]; you can map into a two-dimensional vector, only each component is a three-dimensional vector, which is a matrix in linear algebra. So Typedef Matrix_23 [2] [3]; Matrix_23 A ;. Similarly, you can only pay attention to the defined array variables to ignore the semantics characterized by the type, such as Double A [300] [300]; Here A and Double B [90000]; What is the difference between defined B? The final memory is not distinguished, only a semantic difference - the container represented by the former needs two keywords (key) to locate a value, while the latter can locate the element with only one keyword (A [a 2] [3] = 3; equivalent to B [603] = 3;, but the former is less efficient). The former, such as the form in the spreadsheet, gives the cross-section of two coordinates to locate the location of the data; the latter is a general continuous container. It is also possible to focus on the type semantic-vector, vector, but also focused on the array example semantic-container, such as: Point_2d PContainer [300]; PCONTAINER type is actually Double [300] [2]. Quote and indirect

To explain the semantics of the pointer and its use, it is best to learn about the reference and indirect. The reference here is not referring to the reference type modifier "&" in C , but a language-independent concept, "C has been explained in detail in" B) from zero (eight) ", and then explains it: Quote indicates a connection Relationships, so that some means can be achieved, now another means can achieve, this means is often more advantageous than the original means. If someone's mobile phone number is a reference to someone; the number of books in the library is a reference to the book; someone's name is someone's reference. What is the use of reference? It is useless, there must be some means to achieve its "equivalent" purpose. If someone's mobile phone has no or no electricity, "mobile phone number" cannot complete the function equivalent to "and someone"; there is no correct emission book, the number of books is meaningless; there is no complete search system, give it out The name of the person cannot find people. This is because the reference is part of "indirect", what is the "C from scratch (11) Next article" What is indirect, pointing out three major advantages - simplified operation, improve efficiency (from a certain aspect) and add flexible Sex, below. Talking with mobile phones and someone is indirect and that people talking through mobile phones; seeing the landscape is indirectly watching the scenery through photos; the product sells indirectly through the salesperson (not the boss personally sold). That is, there is a "original means" to achieve the purpose, there is a "advanced means" to manipulate the "original means", by using the "Advanced Mean" to achieve the purpose of indirect, and "Advanced Means" configuration information (explain how Use "Advanced Means") to be referenced. The so-called means is a method or function, and the configuration information of the method is used to improve the method of use. If a speech is a method, and the person who speaks is a reference, ie, a speech, said that as long as you have a person, you can achieve a speech. "The sound is transmitted to the ear" is "original means", "" The mobile phone can pass the sound and make it in the ear "is" advanced means "," mobile phone number "determines how mobile phone (which mobile phone ); "Light of the scenery" is "original means", "photo reflection light into the eye" is "advanced means", "photo" decides how to reflect light; "Salesperson can sell goods" Yes "original "The means" "" Salesperson can be ordered "is" advanced means "and" salesperson "determine how to order the salesman selling goods (command which). "Mobile Number" quoted "and someone"; "photo" quoted "landscape"; "Salespeople" quoted "sell goods". Note that it is also a resource, which can be operated. When it is modified, the execution of the same "advanced means" will result in different results, therefore increases the flexibility. That is, the flexibility can be improved because the "Advanced Means" can be configured, and the flexibility cannot be improved indirectly if it is not configurable. It should also be paid to the "original means" may be another indirect "advanced means", such as a to b, b command C selling goods to get money, is indirect indirect. If the two-level indirect "advanced means" can be configured, the secondary indirect flexibility will might be higher than one level (just possible, if the "configurable" is used). Indirect necessarily reduce efficiency. Because of the original "original means" to achieve the goal, it is now necessary to implement two means of "advanced means" and "original means" to achieve the purpose. What is the meaning? It is necessary to be better than "original means" in a certain aspect.

For example, the simplified operation, such as the window package CWnd in the MFC; use the "Advanced Means" configurable to improve flexibility; unable to implement "high-level means", such as A did not have time The party b goes with the customer; "Advanced Means" is "advanced means" to simplify management, equivalent to classification, such as the marketing department sells goods rather than the salesman selling goods. Pointer semantics - reference

The above said so much, what is the need? The semantics of the pointer are referenced. In the "C from the zero" series, the program is described, the method is how to operate the resource, and the resources that can be operated in C are only numbers, and the numbers are stored in one memory with the rules determined by their type. The memory block is identified by its first address. The calculation of numbers of the number of address types will take content operation. The calculation of the number of pointer types does not take content, directly return the address, that is, the number of the pointer type is an address, and the address is unique in C . - Digital - The location where the store is stored, that is, it is a reference to a block memory block. Since the pointer is referred to as a reference, it will be brought into indirect. The calculation of numbers (ie, the rules defined by the number of numbers) are "original means", the pointer is referenced, and "Advanced Means" is taken (by taking the content operator "*" will be pointer type Change to the address type to implement). Note that the reference can also be used without using this "advanced means", others can, but need to ensure that this "advanced means" can control (or execute) "original means" - digital calculations (ie all C syntax can be Where the expression is placed, the pointer type The address type is only implemented by the form of operators, that is, it can be placed in the expression to achieve the purpose of the "original means"), such as type conversion. Now I have known the indirect introduced by the pointer. Let's see how to use this indirect. "Advanced Means" is more than the "original means" and calculate the number of numbers? Take the content with a unique configurable information - the location of the content, that is, the address. As mentioned earlier, the configurable band of "Advanced Means" is flexible, as follows: long A1 = 1, A2 = 2, A3 = 3, * P = 0; / * Some operations to determine the value of P * / * p = 5; The above flexibility is reflected in multiple execution * p = 5; this statement may increase the value in different memory 5. However, if A2 = 5;, no matter how many times is performed, it is 5 in the memory identified by the address corresponding to the A2. The reason why it can be because the pointer is a reference for the number of address types. Note that the address type is also brought into an indirect, which is a reference. The calculation of the numbers is "original calculation", and the content is "Advanced Means" (the same as the pointer, but the latter needs to take the content operator conversion, and the former is not required), the number of the address type is referenced. This also results in A3 = A1 A1; also has flexibility because it is not A3 = 1 1;, it is not a number of LONG types by the address. For A3 = * P * P; then indirectly obtain the address, then obtain the number in memory, this is a secondary indirect, its flexibility is higher than the A3 = A1 A1;, the pointer can also be said It is a reference to a number. The indirect simplified operations mentioned earlier are required, and since the "advanced means" is required, only the content operators are taken here, and the pointers are primarily used to increase flexibility. Note The reference is generally a smaller resource, which is easy to record will be considered reference. The A and B conversations can be implemented if only the B's mobile phone number is given to A without bringing B to A. When referenced is an operation of a certain resource, a small reference is given less than an instance of the kind of resource. At this time, the delivery reference is more efficient than the instance of the resource, which is the front. The so-called improvement efficiency. This is very popular in C , which is completely dependent on the secondary indirect of the pointer to implement reference to the numbers.

That is, a number is large, such as a length 300 bytes (such as CHAR [300]), and its reference-address-only 4 bytes, if you pass it to the function, the address should be passed, but the pointer type The number is the address, so the parameter type of the function should be a pointer (char (*) [300]) instead of the original type (CHAR [300]), the latter's delivery fee is higher. Application of pointer - indirect

At this point, according to the four application purposes of the pointer, it is already possible to increase flexibility, reference memory blocks, reference numbers, semantic needs, and are described below: Increase flexibility to write a piece of code, especially cyclic, cyclic body It is a place where the pointer is often used, as it can reflect the flexibility, it is the same approach to obtain different results, and therefore, the same cycle is performed multiple cycles, but the same cyclic body is obtained to achieve the purpose of simplified program (otherwise required Write a code for each result). If you need to increase the value in the memory block of 20-byte memory blocks, you can place the first address in a pointer, as follows: long * p; / * Initializes p * / for (long i = 0 i <100; i , p = 5) * p ; therefore, for places that do not want to change the code, in order to increase their applicable range, the pointer is often used to increase its flexibility. For example, within the function, within the library file, such as a dynamic connection library, within the module (referring to the program structure, such as the game logic computing module and the drawing module). Note that the existence of the function pointer. A prototype of the function represents a call rule, that is, "C " said in the interface from zero (18) ", the function pointer is a reference to the interface, then the two modules (or called components) are connected. If the logic calculation module calls Void Draw (); to draw, but in the drawing module (ie, the function DRAW) may determine the different drawing methods according to the current drawing data (such as scene complications, etc.), you can use a full bureau. Function pointer void (* g_pdraw) (); each drawing module sets this variable according to the drawing situation, and the logic calculation module becomes (* g_pdraw) (); not DRAW (); (this method is not recommended, It is only proposed here as an example). For member pointers, "C from scratch (Nine)" has pointed out that the offset of the non-static member variable is offset instead of the address, that is, the member variable pointer is not a reference to the memory block, only the number of the number of offset types, The number of digits of the offset type is four bytes long, which may be 8-byte long, so it is not used for the optimization of the previous transmission, and cannot reference the memory block, only increasing flexibility and semantic needs. Such as a structure is a student score, there is a score of 40 degree of learning, you want to calculate the average score, as follows: lang = en-us struct student {float course1, course2, ..., course40; static float student :: * pcourse [40] }; Float student :: * student :: pcourse [40] = {& student :: course1, ..., & student :: course40}; you can write a loop to simplify calculations, such as: Student A; float avg = 0.0f; For (long i = 0; i <40; i ) avg = a. * student :: pcourse [i]; avg / = 40.0f; the same is true for member function pointers, only use the aforementioned rules and semantics You can learn about the use of various pointers.

The reference memory block This is the original semantics of the pointer. When you want to pass the memory block, you can only rely on the pass pointer (memory block is not passed), such as Bool getPersonInfo; Personinfo Temp; GetPersonInfo (& Temp) ); // Use the parameters on the personal information returned in TEMP to transmit a memory block to the function getPersonInInInInInInInInInInInInInInInInInInInInInInInInInInInfo to make personal information in a given memory block for delivery. If Personinfo * getPersonInfo (); then the memory block referenced by the returned pointer needs to be released, but the code using GetPersonInfo cannot know how the memory block is allocated, which is not released, which belongs to memory management. Discuss in-depth. Another example is: Bool getMaxandmin (long * min); long a [10] = {5, 3, 10}, max, min; getMaxandmin (A, & Max, & min); reference number It is an indirect application that is formed by the indirectly brought by the number of the address type, the purpose is to deliver the size of the referenced number than the size of the pointer to reduce the delivery cost. As the long [10] is 40 bytes, if it passes its pointer, only 4 bytes, greatly reduces cost, as follows: BOOL getMaxandmin (long (*) [10], long *, long *); long A [10] = {5, 3, 10}, max, min; getMaxandmin (& A, & MAX, & min); the passage of array A here is much more efficient than before. Another PersonInfo * getPersonInfo (); not Personinfo getPersonInfo (); it is also due to sizeof (personfo *) sizeof (char), not only does not increase, but also reduces efficiency (for 32-bit compilers, this will not be due to transmission reduction Efficiency, but indirect reference digital reduction efficiency).

It should be noted that the reference number is due to the secondary indirect, which leads to a number of unnecessary references - reference to the memory block, this only wants to pass the number, the memory block of the link is also passed, will cause problems. As the previous GetMaxandmin (& A, & MAX, & min); after execution, the contents of the array A may be changed, because the memory block of the record A is also transmitted, the function getMaxandmin can arbitrarily modify the content of the passing memory block. It is the content of array a. When the function getMaxandmin and calling it are not the same person, the former can destroy the contents of A and cause the latter problems, which is called a vulnerability. So when designing the external interface, be careful that the parameter type should be the pointer type (note that the external interface, even if it is BOOL getMaxandmin (const long (*) [10], long *, long *); it is meaningless of).

Semantics requires the semantics of the pointer to reference, when the pointer is logically required, such as a reference to the next node in the node of the list, so it should have a pointer type when designing the node of the list. the member of.

For function pointers, the function is a program, the program is described, that is, the function pointer is a reference to the method. Such a container class has a reference method, which gives different sorting methods when using it to achieve different sorting (this is an increasing flexibility of "indirect"), so that container class should have a member variable. Is a function pointer type. Further, the function pointer can achieve a callback. When searching data, by calling the function search, it has a parameter to specify what should be done when searching time is timeout, so Search requires a reference to a function (code cannot be passed), that is, the function pointer, as follows:

BOOL BCONTINUE (unsigned long outconds)

{

IF (/ * Decision Continued * /)

{/ * Necessary processing * / return true;}

Return False;

}

BOOL Search (BOOL (*) (unsigned long), / * Other parameters * /);

Search (& BCONTINUE, / * Other parameters * /);

BCONTINUE can be called every other time to ask if you want to continue to search for a means to terminate over a long search.

For member pointers, the same, is a reference to members. In "C from zero (12)", the member variable is the properties and status of the corresponding resources. The member function is the function of the corresponding resource, and the member pointer is the reference to the properties and state of the resource, and the reference to the resource function. If the dog has three functions that walk wire, jump ring, and invert, there is a method to perform circus performance. In order to increase flexibility, the circus should maintain a reference to the function of the dog in this function, perform different circus with different fields.

As can be seen from it,

The so-called semantic needs should be designed according to the indirect benefits mentioned earlier, and then exhibit the needs of references from the semantic. But indirectly has bad place, that is, it may fail, and it can always be successful. "Original means" must be successful (because it is directly achieved, if it is in the multi-stage indirect, it is necessary to consider its effectiveness), failed because the "Advanced Means" control failed. The "Advanced Means" is controlled because its configuration information is invalid, that is, reference is invalid. For pointers, it is necessary to ensure that its value is valid. Once invalid, it may cause memory access violations. If there is no appropriate action, the program may crash. Therefore, most of the effectiveness is detected before using the pointer, the method of detecting is to determine whether the memory identified by the address it is cited is accessible (the operating system generally provides such an interface), but with a low efficiency of the operating system. It is generally considered that it is effective as it is not zero, so it is generally as follows:

IF (p) {/ * use pointer p * /}

So it is generally initialized to 0, such as long * p = 0 ;. This generally creates a macro or constant to express this semantic. In the MFC, the null macro defines the macro to represent 0, then: long * p = null;, NULL means an empty.

The pointer and its application have been explained, and the application of the pointer is based on indirect, and indirect advantages and disadvantages will help better use pointers.

转载请注明原文地址:https://www.9cbs.com/read-115409.html

New Post(0)