Concept of pointer

xiaoxiao2021-03-06  69

Concept of pointer

The pointer is a special variable, which is interpreted as an address in memory. To figure out a pointer, you need to figure out the four aspects of the pointer: the type of pointer, the type pointed to by the pointer, the value of the pointer or the memory area pointed to by the pointer, and the memory area occupied by the pointer itself. Let us explain separately.

First declare a few pointers to put the example:

Example 1:

(1) INT * PTR;

(2) Char * PTR;

(3) int ** PTR;

(4) INT (* PTR) [3];

(5) INT * (* PTR) [4];

If you don't understand a few examples, please refer to the article I posted for some time. "How to understand the complex type declaration of C and C >>.

Type of pointer

From a grammatical point of view, you only need to remove the pointer name in the statement statement, and the remaining part is the type of this pointer. This is the type of pointer itself. Let's take a look at the type of each pointer in the example:

(1) INT * PTR; / / The type of pointer is int *

(2) Char * PTR; / / The type of pointer is char *

(3) INT ** PTR; / / The type of pointer is int **

(4) INT (* PTR) [3]; / / The type of pointer is int (*) [3]

(5) INT * (* PTR) [4]; / ​​/ The type of pointer is int * (*) [4]

how about it? Is it very simple to find the type of a pointer?

Type pointed to by pointer

When you pass the pointer to access the memory area points to the pointer, the type pointed to by the pointer determines what the compiler will treat the content in the memory area.

From the grammar, you only need to remove the pointer name and the pointer declare * on the left side of the name of the pointer statement. The remaining is the type pointed to by the pointer. E.g:

(1) INT * PTR; / / The type pointed to the pointer is int *

(2) CHAR * PTR; / / The type pointed to by the pointer is char

(3) INT ** PTR; / / The type pointed to by the pointer is int *

(4) INT (* PTR) [3]; / / The type pointed to by the pointer is int () [3]

(5) INT * (* PTR) [4]; / ​​/ The type pointed to by the pointer is int * () [4]

In the arithmetic operation of the pointer, the type pointed to by the pointer has a large role.

The type of pointer (ie, the type of pointer itself) and the type pointed to by the pointer are two concepts. When you are more familiar with C, you will find that the "type" "type" of the pointer stir together is divided into "the type of pointer" and "the type pointed to the pointer", which is the key point of the proficiency pointer. one. I have read a lot of books, I found some books that were poor, and the two concepts of the pointer were stirred together, so I looked at the conflict before and after, the more I saw it.

The value of the pointer, or the value of the memory area or address pointer to which the pointer is pointed is the value stored by the pointer itself, which will be used as an address instead of a general value. In a 32-bit program, all types of pointers are a 32-bit integer because the memory address is all 32-bit in the 32-bit program. The memory area pointed to by the pointer begins with the memory address represented by the value of the pointer, a memory area of ​​the length of Si Zeof (the type pointed to by the pointer). In the future, we said that the value of a pointer is XX, which is equivalent to the memory area that is the address of XX as XX; we say that a pointer points to a block memory area, which is equivalent to this pointer is this The first address of the memory area. The type of memory pointed to the pointer and pointer is two completely different concepts. In the example one, the type pointed to by the pointer is already, but since the pointer has not been initialized, the memory area indicted to it does not exist, or meaningless. In the future, every time a pointer should ask: What is the type of this pointer? What is the type of a needle finger? Where is this pointer pointing? What is the memory area pointer itself occupies how much memory itself occupies? You only need to use a function Sizeof (type of pointer) to know. In the 32-bit platform, the pointer itself occupies 4 bytes of length. The concept of the memory itself is useful when it is determined whether a pointer expression is a left value. The arithmetic operation pointer of the pointer can be added or minus an integer. The meaning of this operation of the pointer and the meaning of the usual value of the usual value are different. For example: 2: 1, Chara [20]; 2, INT * PTR = a; ... 3, PTR ; In the above example, the type of pointer PTR is int *, which point points to INT, It is initialized to point to the plastic variable a. In the next article 3, the pointer PTR is added 1, the compiler is processed: it adds the value of the pointer PTR with SIZEOF (int), in the 32-bit program, is added 4. Since the address is in units, the address pointed to by the PTR increases by 4 bytes from the address of the original variable A. Since the length of the CHAR type is one byte, the original PTR is four bytes that point to No. 0 unit of array A. At this point, at this point, at this point, at this point, at this point, the four bytes starting from the number 4 unit. We can use a pointer and a loop to traverse an array, see example: Example 3:

INTARRAY [20]; int * ptr = array; ... // This will be omitted to the code assigned to the integer array. ... for (i = 0; i <20; i ) {(* PTR) ; PTR ;} This example adds the value of each unit in the integer array 1. Since each loop is plugged in 1, the next unit of the array can be accessed each time a loop. Again: Example 4: 1, Chara [20]; 2, INT * PTR = a; ... ... 3, PTR = 5; In this example, PTR is added 5, the compiler is like this Treatment: Plus the value of the pointer PTR to 5 by sizeof (int), in the 32-bit program, add 5 multiplication 4 = 20. Since the unit of the address is byte, the address pointed to by the current PTR moves 20 bytes to the high address direction than the address pointed to the PTR after adding 5. In this example, it is not added to the four bytes starting from the PTR before 5, and the PTR has pointed to the legal range of the array A. Although this situation will have problems in the application, but it is possible in grammar. This also reflects the flexibility of the pointer. If in the previous example, PTR is subtracted 5, then the processing process is similar, but the value of the PTR is subtracted to be subjected to 5 multiply SizeOf (int), the new PTR pointing is lower than the address pointed to by the original PTR. The address direction moves 20 bytes. Summary, after a pointer Ptrold couples an integer N, the result is a new pointer PTRNEW, PTRNEW type, and the type of Ptrold, the type pointed to by PtrNew and the type pointed to by Ptrold. The value of the PTRNEW will add N-multiply SIZEOF (Type of Ptrold) by the value of Ptrold. That is to say, the memory area pointed to by PtrNew moves N-multiply SIZEOF (Type of Ptrold) by the memory area pointed to by PTROLD. After a pointer Ptrold minus an integer N, the result is a new pointer PTRNEW, the type of PTRNEW, and the type of Ptrold, the type pointed to by PtrNew and the type pointed to by Ptrold. The value of PTRNEW will reduce N-multiply size and the value of the N multiply sizeof (Type of Ptrold) by the value of Ptrold, that is, the memory area pointed to by PtrNew will move n-by-multiply SIZEOF in the memory area pointed to by PTROLD. (Type pointed to Ptrolt) byte. Operators & and * Here & It is to take the address operator, * is ... The book is called "indirect operator". The calculation result of & a is a pointer, the type of pointer is the type of A plus a *, the type pointed to by the pointer is the type of A, the address pointed to by the pointer, that is, the address of A. * P The calculation result is a five-flowers. In short, the result is something pointed to P, this feature: It is the type of P pointing, and its address is the address pointed to by P. Example 5:

INTA = 12; INTB; INT * PTR; P = & a; // & a result is a pointer, the type is int *, the point to which is int, the pointing address is the address of A. * P = 24; // * P results, here it is int, the address it occupies is the address pointed to by P, apparent, * p is the variable A. PTR = & P; // & p The result is a pointer, the type of the pointer is the type P, which is added *, here is int **. The type pointed to this pointer is the type of P, which is int *. The address points to the pointer is the address of the pointer P. * ptr = & b; // * Ptr is a pointer, and the result of & B is also a pointer, and the type of these two pointers is the same, so use & b to give * PTR assignment is no problem. ** PTR = 34; // * PTR's result is something pointed to by PTR, here is a pointer, and then doing the pointer again * calculation, the result is a Int type variable. The final result of a pointer expression is a pointer, then this expression is called a pointer. Here are some examples of pointer expressions: Example 6: INTA, B; Intarray [10]; int * Pa; PA = & A; // & A is a pointer expression. INT ** PTR = & Pa; // & pa is also a pointer expression. * PTR = & b; // * PTR and & B are both a pointer expression. PA = Array; PA ; // This is also a pointer expression. Example 7: char * arr [20]; char ** PARR = arr; // If arr is regarded as a pointer, Arr is also a pointer expression char * STR; str = * parr; // * Parr is a pointer expression STR = * (PARR 1); // * (PARR 1) is a pointer expression Str = * (PARR 2); // * (PARR 2) is a pointer expression due to pointer expressions The pointer expression also has four elements of the pointer: the type of pointer, the type pointed to by the pointer, the memory area pointed to by the pointer, the memory itself occupies. Ok, when a pointer expression results pointer have explicitly have the memory itself, this pointer expression is a left value, otherwise it is not a left value. In Example 7, & A is not a left value because it has not yet occupied a clear memory. * PTR is a left value, because * PTR This pointer has occupied memory, in fact, * PTR is a pointer PA, since PA has already had its own position in memory, then * PTR has its own position. The relationship between arrays and pointers If you don't understand the statement of the declaration array, please refer to the article I have been posted for some time. "How to understand the complex type declaration of C and C >>. The array name of the array is actually as a pointer.

Look at the example: 8: Intarray [10] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}, value; ... ... value = array [0]; / / Can also be written: value = * array; value = array [3]; // can also be written: value = * (array 3); value = array [4]; // can also be written: value = * (array 4); In the previous example, the general reporting group name array represents the array itself, the type is int [10], but if Array is as a pointer, it points to the 0th unit of the array, the type is int *, point pointed The type is the type of array unit, inT. So * Array is not surprising. Similarly, Array 3 is a pointer to the third unit of array, so * (array 3) is equal to 3. Others are so pushing. Example 9:

Char * STR [3] = {"Hello, THISASAMPLE!", "Hi, GoodMorning.", "HelloWorld"}; Chars [80]; STRCPY (S, STR [0]); // can also be written into strcpy (S , * STR); STRCPY (S, STR [1]); // can also be written into strcpy (s, * (STR 1)); STRCPY (S, STR [2]); // can also be written into strcpy (S , * (STR 2)); in the above example, STR is an array of three units that each unit of the array is a pointer, which points to a string. That a pointer is used as a pointer, it points to the number 0 unit of the array, its type is char **, which is a type of char *. * Str is also a pointer, its type is char *, which is the type of char, which is the address of the first character string "Hello, THISASAMPLE!", the address of 'h'. Str 1 is also a pointer, pointing to No. 1 unit of array, its type is char **, which is a type of char *. * (STR 1) is also a pointer, its type is char *, which is the type of char, which points to "Hi, GoodMorning." First characters 'h', and so on. The following is summarized below the number of group names of the array. Declare an array typeArray [N], then the array name Array has two meanings: First, it represents the entire array, its type is type [n]; second, it is a pointer, the type of the pointer is TYPE *, the type pointing to the pointer is Type, which is the type of array unit. The memory area pointed to by the pointer is an array No. 0 unit, which has a separate memory area, pay attention to it and the array No. 0 units The memory area is different. The value of the pointer cannot be modified, ie the expression like Array is wrong. ARRAY can play different roles in different expressions in different expressions. In the expression sizeof (array), the array name array represents an array itself, so the sizeOf function measured the size of the entire array at this time. In the expression * array, Array plays a pointer, so the result of this expression is the value of the array No. 0 unit. SizeOf (* array) is measured by the size of the array unit. Expression Array N (where n = 0, 1, 2, .....), Array plays a pointer, so the result of Array N is a pointer, its type is type *, it points to the type It is TYPE, which points to the array N number unit. Therefore, SizeOf (Array N) is measured by the size of the pointer type. Example 10:

INTARRAY [10]; int (* ptr) [10]; PTR = & array; on the previous example PTR is a pointer, its type is int (*) [10], the type he point to INT [10], we use The first address of the entire array initializes it. In the statement PTR = & Array, Array represents an array itself. In this section, the function SIZEOF () is mentioned, then I will ask questions, the size is measured by the size of the pointer itself, or the size of the type pointed to by the pointer? The answer is the former. For example: int (* ptr) [10]; in the 32-bit program, there is: sizeof (int (*) [10]) == 4 sizeof (int [10]) == 40 sizeof (PTR) == 4 In fact, SizeOf (object) is measured by the size of the object itself, rather than any other type of size. The relationship between pointers and structural types can declare a pointer to the structural type object. Example 11:

StructMystruct {INTA; INTB; INTC;} mystructss = {20, 30, 40}; // Declare the structural object SS, and initialize the three members of the SS to 20, 30 and 40. MyStruct * ptr = & ss; // Declare a pointer to the structural object SS. Its type is mystruct *, which points to which is mystruct. INT * PSTR = (int *) & ss; // Declare a pointer to the structural object SS. But its type and the type and PTR it point to it are different. How do I access the three member variables of SS by pointer PTR? Answer: ptr-> a; ptr-> b; ptr-> c; how to access the three member variables of SS by pointer PSTR? Answer: * PSTR; // Access the member a of SS. * (PSTR 1); // Access the member B of SS. * (PSTR 2) // Access the member C of SS. Although I have said the above code in my MSVC 6.0, I have to know that this use of PSTR to access structural membership is inquirable. In order to explain why I don't regular, let's see how to access the arrays by pointer to various units : Example 12: INTARRAY [3] = {35, 56, 37}; int * pa = array; the three units of accessing array array through pointer PA is: * pa; // Access No. 0 unit * (Pa 1); // Access No. 1 * (PA 2); // Accessing the No. 2 unit from the format is the same as the format of an unpredictable method of accessing the structure through the pointer. When all the C / C compilers are arranged in the array, the individual array units always store each array unit in a continuous storage area, and there is no gap between the unit and the unit. However, when the various members of the structural object, in some kind of compilation environment, it may need the word alignment or double word alignment or other alignment, need to add several "padding bytes" between adjacent two members. This leads to a number of bytes of voids between each member. So, in Example 12, even if the * PSTR accesses the first member variable A of the structural object SS, it is not guaranteed * (PSTR 1) will be able to access the structural member B. Because there may be some filling bytes between member a and members b, maybe * (PSTR 1) just visited these padding bytes. This also proves the flexibility of the pointer. If your purpose is to see if there is any fill byte between the members of each structure, hey, this is a good method. The correct way to access structural members through the pointer should be a method of using a pointer PTR in an example 12. The relationship between the pointers and functions can declare a pointer into a pointer to a function. INTFUN1 (CHAR *, INT); INT (* pfun1) (CHAR *, INT); PFUN1 = Fun1; .... .... INTA = (* PFUN1) ("AbcDefg", 7); // Through functions Pointer call function. The pointer can be used as a function of the function. In a function call statement, you can use a pointer expression as an argument. Example 13:

INTFUN (Char *); INTA; Charstr [] = "Abcdefghijklmn"; A = Fun (STR); ...... = 0; for (inti = 0; i {Num = * S; S ;} ReturnNum;} This example is the sum of the ASCII code value of each character in a string. The previously said, the name of the array is also a pointer. In the function call, when the STR is act After passing the parameters S, it is actually that the value of the STR is passed to the address pointed to by S, and the STR is consistent with the address pointed to by the STR, but the STR and S are each occupied the respective storage space. In the function, S Self-plus 1 calculation does not mean that STR has been self-adding 1 operation. The pointer type conversion When we initialize a pointer or give a pointer, the left side of the assignment number is a pointer, the right side of the assignment number is a pointer expression. In the example of our previous example, in most cases, the type of pointer and the type of pointer expression is the same, and the type of pointer and pointer expression points to the type. Example 14 : 1, floatf = 12.3; 2, float * fptr = & f; 3, int * p; in the above example, if we want the pointer P to point to the real f, what should I do? Is it using the following statement? P = & f; Not right. Because the type of pointer P is int *, it point to the type is int. Expression & F's result is a pointer, the type of pointer is float *, which point points to float. Both inconsistent, directly assigning The method is not good. At least on my MSVC 6.0, the type of assignment statement of the pointer requires the same type of the type, the type pointed to, and I have not tried it on other compilers. You can try it. In order to achieve our goal, "Mandatory Type Conversion": P = (INT *) & F; If there is a pointer P, we need to change its type and the type of type to Tyep * Type, then the syntax format is: (TYPE *) P; The result of this forced type conversion is a new pointer, the type of new pointer is type *, which point points to Type, the address it pointing is the address pointing to the original pointer P Every attribute is not modified. If a function uses a pointer as a ginseng, then a plurality of pointer types will occur during the combination of the actual parameters of the function call statement. Example 15:

VoidFun (char *); inta = 125, b; fun ((char *) & a); ... voidfun (char * s) {charc; c = * (S 3); * (s 3 ) = * (S 0); * (S 0) = C; c = * (S 2); * (S 2) = * (S 1); * (S 1) = C; }} Note This is a 32-bit program, so the int type accounts for four bytes, and the char type accounts for one byte. The function of function FUN is to reverse the order of the four bytes of an integer. Do you notice? In the function call statement, the result of the active argument & a is a pointer, its type is int *, which point points to INT. The type of parameter this pointer is char *, which is the type of CHAR. Thus, during the binding process of the arctic and meticulum, we must conduct a conversion from int * type to char * type. Combined with this example, we can imagine the process of transformation of the compiler: The compiler first constructs a temporary pointer char * TEMP, then execute Temp = (char *) & A, and finally passing the value of TEMP to S. So the final result is: the type of S is char *, which is the type of char, which is the first address of A. We already know that the value of the pointer is the address pointed to by the pointer. In the 32-bit program, the value of the pointer is actually a 32-bit integer. Can you assign an integer as a value of the pointer to the pointer? Just like the following statement: UNSIGNEDINTA; TYPE * PTR; // Type is int, char or structural type, and the like. ... a = 20345686; PTR = 20345686; // Our purpose is to make the pointer PTR point to address 20345686 (decimal) PTR = a; // Our purpose is to point the pointer PTR to address 20345686 (decimal) Compile it. It was found that the following two statements were all wrong. So can't our purpose you have? No, there is also a way:

Unsignedinta; type * ptr; // Type is int, char or structural type, and the like. ... a = a number, this number must represent a legal address; PTR = (Type *) a; // Oh, this is OK. Strictly speaking (Type *) and pointer type conversion (Type *) is still different. Here (Type *) means that the value of the unsigned integer A is treated as an address. The above emphasizes that the value of A must represent an legitimate address. Otherwise, if you use PTR, illegal operational errors will occur. Think of that you can't turn it, the value of the pointer to the pointer is taken out as an integer. absolutely okay. The following example demonstrates the value of a pointer as an integer, and then put this integer as an address to a pointer: Example 16:

INTA = 123, B; INT * PTR = & a; char * STR; b = (int) PTR; // Put the value of the pointer PTR as an integer. Str = (char *) b; // Put the value of this integer as an address to the pointer STR. Now we already know, you can take the value of the pointer as an integer, or you can assign an integer value as an address to a pointer. The security problem of pointers look at the example below: Case Seven:

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

New Post(0)