Chapter One. The concept pointer of the pointer is a special variable, which is interpreted as an address in the 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 article I posted for some time. "How to understand the complex type declaration of C and C >>.
1. The type of pointer looks at the grammatical point of view, you only need to remove the pointer name in the pointer 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 pass the 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. What is the memory area of the pointer itself accounts for how much memory is occupied by the memory area 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. 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: 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 shaping 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: INT Array [20]; int * ptr = array; ... // This will be omitted to the code of the integer 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 each time a 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: add the value of the pointer PTR to 5 * 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 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. third chapter. Operator & 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: It is the type of P pointing, and its address is the address pointed to by P. Example 5: INT A = 12; INT B; INT * P; int ** PTR;
P = & a; // & A's result is a pointer, the type is int *, the pointing type 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, apparently * 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.
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 some examples of 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 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.
chapter Five. Array and pointer relationship
If you don't understand the statement of the declaration array, please refer to the article I 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: Example 8: Int Array [10] =, value; ... value = array [0]; // can also be written: value = * array; value = array [3]; // Can be written: value = * (array 3); value = array [4]; // can also be written: value = * (array 4); in the upper example, generally the number of group name array represents the array itself, the type is INT [10], but if Array sees as a pointer, it points to the 0th unit of the array, the type is int *, the type pointed to which 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, this is a name!", "Hi, Good Morning.", "Hello World"}; char s [80]; STRCPY (S, Str [0]) ; // can also be written as 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 *, the type it is pointing is char, which pointing the address is the first character of the string "Hello, this is a sample!", 'h' address. 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, Good Morning." first characters 'h', and so on. 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 Array N is a pointer, its type is type *, it points to the type 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 on the previous 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 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. 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 =; // 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 * PTR = (int *) & ss // declares a pointer to the structural object SS. But its type and the type and PSTR it point to PSTR 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 repel the above code in my MSVC 6.0, I have to know that I use PSTR 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] =; int * pa = array; the method of accessing the three units of array array through a pointer PA is: * Pa; // Access No. 0 unit * (PA 1); / / Access No. 1 unit * (PA 2); // Accessing the No. 2 unit is as follows in the format of the format, the same format. 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.
Chapter VII. The relationship between the pointers and functions 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); ///// The function is called through the function of the 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 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, the type pointed to the pointer and the type pointed to by the pointer expression. Example 14: 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 the real number f, what should I do? Is it the following statement? P = & f is wrong. Because the type of pointer P is int *, the type it points to 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 assignment number, the type pointed to the same, the same type, I have not tried it on other compilers, everyone can try it. In order to achieve our goal, "Forced 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; The result of such a forced type conversion is a new pointer, the type of pointer Type *, which point points to 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 occur during the combination of the actual parametric and metall parameters of the function call statement. Example 15: Void fun (char *); int A = 125; int 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 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: unsigned int a; 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: 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. 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, then uses this integer as an address to a pointer: Example 16: INT A = 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. 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