Today, the teacher told us a list, and everyone is very good as the old man's book, which is easy to listen. So here, I will no longer be repeated. Everyone will slowly look at the chain of the old Tantan book, and it will never feel difficult, but also some vivid examples come to illustrate. Below I found some articles about the pointer from the Internet, this person is definitely a master, everyone should study it. I believe that there is a probably a pointer after reading the first pass, the second time I have impressed in my mind, and the third time I can tell it. ^ _ ^
Sender: Girlrong (Along), News District: C
Title: Items in my eyes - Author
Sending station: Netease Virtual Community (MON AUG 2 16:12:02 1999), station letters
Serve for beginners. This is my post. I am also an initiator (emphasizing countless times), I put it out with my understanding of the initiator. Due to the language of the primary school, the language is not necessarily to achieve this goal. Try to do our best. The pointers are difficulties and focuses in C and C . I only master the BASIC under DOS. Other various features of C language, there are similar things in Basic. Only pointers are not available in Baisc. The pointer is the soul of C. I don't want to repeat most books, I just said that I didn't know if I have seen the book I have seen, and I think I understand something that I understand is a bit. My purpose is: 1. Written by writing these things, clearing the blurred knowledge about C in my head. 2. Give beginners a little prompt. 3. Earn a few experience values. (Because it is suspicious of these things without irrigation)
Chapter One. 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 several 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 text I posted for some time. LT; "How to understand the complex type declaration of C and C >>.
1. 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 Example: (1) INT * PTR; / / The type of pointer is int * (2) char * PTR; / / pointer type 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]; // pointer Type is int * (*) [4]? Is it very simple to find the type of a pointer?
2. The type pointed to the pointer. When you use a pointer to access the memory area pointed to by 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. For example: (1) INT * PTR; / / The type pointed to by the pointer is int (2) char * PTR; / / The type pointed to by the pointer is the CHAR (3) int ** PTR; / / pointer points to Type is int * (4) int (* ptr) [3]; / / The type pointed to by the pointer is int () [3] (5) INT * (* PTR) [4]; / / pointer points to The type 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. 3. The value of the pointer or the memory area or address pointed to by the pointer. The value of the pointer is the value stored in the pointer itself, which will be used as an address by the compiler, not 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 pointing to the pointer? Where is this pointer pointing? 4. The memory area occupied by the pointer itself. How much memory itself does the pointer itself? 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.
Chapter two. Arithmetic operation of pointer
The pointer can add 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: Example 2: 1. CHAR A [20]; 2. INT * PTR = a; ... 3. PTR ; In the above example, the type of pointer PTR is int *, which point points to INT, which is initialized to point to the intersive 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 of unit, 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: Example 3: Int Array [20]; int * ptr = array; ... // This is slightly went into the intersection of the total array assignment. ... 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 at each loop. Look at the example: Example 4: 1. CHAR A [20]; 2. INT * PTR = a; ... 3. PTR = 5; In this example, PTR is added 5, the compiler is processed: adding the value of the pointer PTR plus 5 by sizeof (int), in the 32-bit program plus 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 ask questions on the application, it is ok. 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 will move n-multiply SIZEOF (Type of Ptrold) by the memory area pointed to by PTROLD. After a pointer Ptrold subtracts an integer N, the result is a new pointer PTRNEW, PTRNEW type and Ptrold type, and the type pointed to by PtrNew and the type pointed to by Ptrold. The value of PT RNEW will reduce N-multiply SIZEOF (Type of Ptrold) by the value of Ptrold, that is, the memory area pointed to by PtrNew will move n multiply from the memory area pointed to by the PTROLD. SIZ EOF (Type Point to Ptrold) One byte.
third chapter. Calculation? Amp; and *
Here & 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 has these features: its type is the type P pointing, the address it occupies is the address pointed to by P. Example 5: INT A = 12; int b; int * p; int ** PTR; P = & a; // & a result is a pointer, the type is int *, the point to the type is int, the pointing address is A address. * P = 24; /// * p The result, 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 this pointer again * calculation, the result is an int type variable. Chapter Four. Pointer expression.
The last result of an expression If it is a pointer, then this expression is called a pointer expression. Here is an example of some pointer expressions: Example 6: Int A, b; int Array [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
Since the result of the pointer expression is a pointer, the pointer expression also has four elements of the pointer: the type of pointer, the type pointed to by the pointer, the memory area indicated by the pointer, the memory itself occupies the memory itself. 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 the memory, then * PTR is of course its own position.
chapter Five. Array and pointer relationship
If the statement of the declaration array is not understood, see the text I posted for some time to post? LT;
The following is summarized below the number of group names of the array. Declare an array type array [n], then 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 of pointer is Type, which is the type of array unit. The memory area points to which the pointer points is an array No. 0 unit, which accounts for a separate memory area, pay attention to it and the array No. 0 unit 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 Arr Ay N is a pointer, its type is type *, which points to which it is TYPE, it points to the array N number. Therefore, SizeOf (Array N) is measured by the size of the pointer type. Example 10: Int Array [10]; int (* ptr) [10]; PTR = & array; upper example PTR is a pointer, its type is int (*) [10], the type he point to INT [10 ], We initialize it with the first address of the entire array. In the statement PTR = & Array, Array represents a number of groups. In this section, the function SIZEOF () is mentioned, then I ask questions, the size of the SIZEOF (pointer name) is the size of the type of the pointer itself or the size of the type pointer? The answer is the former. E.g:
INT (* PTR) [10]; then in 32-bit programs,: sizeof (int (*) [10]) == 4 sizeof (int [10]) == 40 sizeof (PTR) == 4 actually SIZEOF (Object) is measured by the size of the object itself, rather than anything else.
Chapter Six. Relationship between pointers and structural types
A pointer to the structural type object can be declared. Example 11: struct mystruct {int A; int b; int C;} mystruct ss = {20, 30, 40}; // Declare structure object SS, and initialize SS three members 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. Oh, although I have said the above code in my MSVC 6.0, I have to know that I use P Str to access structural membership is inquirable. In order to explain why I don't regular, let's see how to access arrays through the pointer Each unit: Example 12: Int Array [3] = {35, 56, 37}; int * pa = array; three units of accessing array array through pointer PA is: * pa; // Access No. 0 unit * (Pa 1); // Access No. 1 unit * (PA 2); // Accessing the No. 2 unit from the format is the format of an unflavible method of accessing the structure through the pointer same. 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. But when the various members of the structural object, in some compilation environment, it may need the word alignment or double word alignment or any other alignment, need to add a number of quot; padding bytes between adjacent two members ", This leads to a number of bytes of voids between each member. So, in Example 12, even if * PSTR accesses the first member variable A of the structural object SS, it is not guaranteed * (PSTR 1) You 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 accessed these padding bytes. This also proves pointers Flexibility. If your purpose is to see if there is any fill byte between each structure, hey, this is a good method. The correct way to access structural members through the pointer should be the use of pointers in an example 12. PTR method. Chapter 7. Relationship between pointers and functions
You can declare a pointer into a pointer to a function. INT FUN1 (CHAR *, INT); INT (* PFUN1) (CHAR *, INT); PFUN1 = Fun1; .... .... Int a = (* PFUN1) ("Abcdefg", 7); // Call via function pointer 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: INT Fun (Char *); Int A; char str [] = "abcdefghijklmn"; a = fun (str); ... int fun (char * s) {int Num = 0; for (int i = 0; I {Num = * S; S ;} return num;) The function FUN in this example statistss the sum of the ASCII code values of each character in a string. As mentioned earlier, the name of the array is also a pointer. In the function call, after the STR is transmitted to the formation S, the value of the STR is passed to the address pointed to the STR, which is consistent with the address pointed to by the STR, but the STR and S are occupied. Storage space. Self-adding 1 calculation in the function body does not mean that the STR has been used in the same time.
chapter eight. Pointer type conversion
When we initialize a pointer or assign 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 we mentioned earlier, in most cases, the type of pointer and the type of pointer expression is the same, and the type pointed to by the pointer is the same. Example fourteen: 1. Float f = 12.3; 2. Float * fptr = & f; 3. INT * P; in the above example, if we want the pointer P to point to real num f, what should I do? Is it the following statement? P = & f; wrong. Because the type of pointer P is int *, it is pointing to the type is Int. The result of expression & f is a pointer, the type of pointer is float *, which point points to float. The two are inconsistent, and the method directly assigned is not. At least on my MSVC 6.0, the assignment statement of the pointer requires the same type of type, the type pointed to, and I haven't tried it on other compilers. You can try it. In order to achieve our purpose, "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 * and Type, then the syntax format is : (TYPE *) P; This is the result of the forced type conversion is a new pointer. The type of the new pointer is type *. It points to the type, which is the address pointing to the original pointer. And all attributes of the original pointer P have not been modified. A function If the pointer is used as a ginseng, the pointer type conversion will also occur during the combination of the actual parameters and shape of the function call statement. Example 15: Void Fun (Char *); INT A = 125, B; Fun ((char *) & a); ... void fun (char * s) {char C; 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 the function FUN is to put 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 the pointer is char *, which is the type of char. In this way, in the combination of the arctic and meticulous parameters, we must conduct a conversion from int * type to char * type once. In conjunction with this example, we can imagine the compiler for the process of transform: the compiler first constructs a temporary pointer char * TEMP, then executes Temp = (char *) & A, and finally transmitting 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 a 32-bit integer. Can you assign an integer as a value of the pointer to the pointer? Just like the following statement: unsigned int a; type * ptr; // type is int, char or structural type, and the like. ... a = 20345686; PTR = 20345686; // Our purpose is to make pointer PTR points to address 20345686 (decimal) PTR = a; // Our purpose is to make pointer PTR points to address 20345686 (decimal) to 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: unsigned int a; type * ptr; // Type is int, char or structural types and so on. ... 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. The meaning here (Typ E *) 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, then put this integer as an address to a pointer: Example 16: Int a = 123, b; int * Ptr = & a; char * Str; b = (int) PTR; // Take 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.
Ok, now we already know, you can take the value of the pointer as an integer, or you can use an integer value as an address to a pointer.
Chapter nine. Pointer security problem