Serve for beginners. This is my post. I am also an initiator (emphasizing countless times)
I used my understanding to write the beginners to write out with shallow language. Due to the primary school
Didn't learn well, so do your best, you may not be able to achieve this. Try to do our best.
The pointers are difficulties and focuses in C and C . I only master the BASIC under DOS. C language other
Sex, 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 am very clear, I just said in the book I have seen.
Chu or did not say, and I think I understand something I understand. 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 make a clear point to you need to make a clear pointer: the type of pointer, pointer points to
The value of the type, the value of the pointer, or the memory area pointed to by the pointer, and the memory area occupied by the pointer itself. yield
We 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 text of my last time? LT; complex type declarations >>. 1. Type of pointer. From the perspective of syntax, you only need to remove the pointer name in the statement statement, the rest of the part It is the type of this pointer. This is the type of pointer itself. Let us look at the various pointers in the case Types of: (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? 2. The type pointed to the pointer. When you access the memory area pointed to by the pointer, the type pointed to by the pointer determines the compilation. Will treat the contents of the memory area to see. From the grammar, you only need to declare the pointer name and the pointer declare on the left of the name of the name. * Remove, the rest 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 in C When you are more familiar, you will find that the "type" of the type "of the concept" this concept is "pointer. Two concepts of type "and" pointers "are one of the key points of proficiency pointers. I have seen it. In the book, I found some books that were poor, and the two concepts of the pointer were together, so I saw a book. It is contradictory before and after, the more you look at 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 the 32-bit program, all types of pointers are 32-bit integers because The memory address in the 32-bit program is all 32-bit long. The memory area pointed to by the pointer starts from the memory address represented by the value of the pointer, and the length is Si. A memory area of ZEOF (the type pointed to by the pointer). In the future, we say that the value of a pointer is XX, When the pointer points to a memory area with the address of XX; we say a pointer points to a block The memory area is equivalent to the value of the pointer is the first address of this memory area. The type of memory pointed to the pointer and pointer is two completely different concepts. In Example No. 1 The type pointed to by the pointer is already, but because the pointer has not been initialized, it points to the memory area. It doesn't exist, or it is meaningless. In the future, every time a pointer should ask: What is the type of this pointer? Pointer What is the type? 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 the 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 calculation of the pointer and the addition and decrease of the usual value The meaning of the operation is different. E.g: 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 pointing Variables a. In the next article 3, the pointer PTR is added 1, the compiler is processed: it puts a pointer The value of the PTR plus SIZEOF (int), in the 32-bit program, is added 4. Since the address is used by bytes In the 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 beginning to point to No. 0 unit of array A. Four bytes, pointing to four bytes from the array A in the array A. We can use a pointer and a loop to traverse an array, see example: Example 3: Example 3: Int arch [20]; INT * PTR = Array; ... // This is 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. Due to each cycle, PTR plus 1, Access the next unit of the array at each cycle. Look again: 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 Take SizeOf (int), in the 32-bit program, add 5 multiplied 4 = 20. Since the unit of the address is byte, The address pointed to by the PTR is moved to the high address direction than the address pointed to the PTR after adding 5. 20 bytes. In this example, the PTR beforehand is not added to the four bytes starting to the No. 0 unit of the array A. After add 5, PTR has pointed to the legal scope of array A. Although this situation will be questioned in the application Question, but 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 reduced. Going to 5 multiply Sizeof (int), the new PTR pointing to the address will be lower than the address pointed to by the PTR. Two bytes moving towards it. Summarize, after a pointer Ptrold adds an integer N, the result is a new pointer PtrNew, The type of PTRNew and the type of Ptrold are the same, the type pointed to the PTRNew and the type pointed to by Ptrold. Also the same. The value of PtrNew will add N-multiply SIZEOF (Type Point to Ptrold) by the value of Ptrold. Section. That is to say, the memory area pointed to by PTRNEW will move to the high address direction than the memory area points to the Ptrold. Move N-multiply SizeOf (Type Point to Ptrold) bytes. After a pointer Ptrold subtracts an integer N, the result is a new pointer PtrNew, the class of PtrNew Type and Ptrold type, the type pointed to by PtrNew and the type pointed to by Ptrold. PT RNEW's value will reduce N-multiply sizeof (Type of Ptrol) by the value of Ptrold, means The memory area pointed to by PtrNew will move N-by-multiply SIZ in the memory area points to the memory area points to the PTROLD. EOF (Type Point to Ptrold) bytes. 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 a 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 thing has this Some features: It is the type of P pointing, and 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 which is int, pointing address Is the address of A. * P = 24; // * p The result, here it is int, the address it occupies is the point pointed to by P Site, obvious, * P is the variable a. PTR = & p; // & p The result is a pointer, the type of the pointer is the type of P, adding a *, here is Int **. The type pointed to this pointer is the type of P, which is int *. The address points to this pointer is the pointer p My address. * PTR = & b; // * Ptr is a pointer, and the result of & B is also a pointer, and the type and place of these two pointers The type pointing 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, to this point The needle is done again * 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 are some examples of pointer expressions: Example 6: INT A, B; Int arch [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 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 pointers. Features: The type of pointer, the type pointed to by the pointer, the memory area points to the pointer, the pointer itself RAM. Ok, when a pointer expression results pointer have explicitly have the memory that the pointer itself occupies If 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 is already There is a location in the memory, then * PTR has certain positions. chapter Five. Array and pointer relationship If you don't understand the statement of the declaration array, please refer to the text of my last time I posted? Lt; Understand the complex type declaration of C and C >>. The array name of the array is actually as a pointer. Look at the case: Example 8: Int Array [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 above example, the general two group name array represents the array itself, the type is int [10], but if a RRAY as a pointer, it points to the 0th unit of the array, the type is int *, the type pointed to the number The type of set unit is int. So * Array is not surprising. Similarly, Array 3 is a Point points to the first unit of the array, so * (array 3) is equal to 3. Others are so pushing. Example 9: 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 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, these fingers The needle points to a string. That's a pointer, pointing to a pointer, pointing to No. 0 of the array Unit, its type is char **, which point points to Char *. * STR is also a pointer, its type is char *, which is pointed to the type, which point points to The address is the address of the first character of the string "Hello, this is a sample!", 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 *, the type it points to is char, which pointing "Hi, Good Morning." The first character 'h', and so on. The following is summarized below the number of group names of the array. Declare an array type array [n], then arrays 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 *, which is TYPE, which is Type, which is an array. The type of unit, the memory area points to which the pointer is the number No. 0 unit, which has a separate inside. The storage area, pay attention to the memory area occupied by the array No. 0 unit. The value of this pointer cannot be modified. That is, the expression like Array is wrong. ARRAY can play different roles in different expressions in different expressions. In Expressive Sizeof (Array), array name array represents an array itself, so the sizeof function is at this time. The measured is the size of the entire array. In the expression * array, Array plays a pointer, so the result of this expression is the array The value of the 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 ARR The result of AY N is a pointer, its type is type *, which point points to TYPE, pointing to the array N number unit. Therefore, SizeOf (Array N) is measured by the size of the pointer type. Example 10: Int arch [10]; INT (* PTR) [10]; PTR = & array; In 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 a number of groups. body. In this section, the function sizeof (), then I will ask questions, SIZEOF (pointer name) measured It is actually 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]; In the 32-bit program, there is: SIZEOF (int (*) [10]) == 4 SizeOf (int [10]) == 40 SIZEOF (PTR) == 4 In fact, the size of the SIZEOF (object) is the size of the object itself, not something else. Type size. 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 the structural object SS, and initiates the three members of the SS Turn 20, 30 and 40. MyStruct * ptr = & ss; // Declare a pointer to the structural object SS. Its type is MyStruct *, the type it points to is mystruct. INT * PSTR = (int *) & ss; // Declare a pointer to the structural object SS. But it's Types and PTRs that it points to them are different. How do I access the three member variables of SS by pointer PTR? answer: Ptr-> a; PTR-> B; Ptr-> C; Also ask 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 am in my MSVC 6.0, I have to pass the above code, but I have to know that I use P. STR to access structural membership is inquirable, in order to explain why it is not regular, let us see how Needle to access various units of arrays: Example 12: Int arch [3] = {35, 56, 37}; INT * PA = Array; The method of accessing the three units of array array through the pointer PA is: * Pa; // Visit No. 0 unit * (PA 1); // Access the No. 1 unit * (Pa 2); // Accessing No. 2 unit From the format, it is the same as the format of the unflavible method of accessing the structure by the pointer. When all C / C compilers are arranged in the unit of array, they always store each array unit in continuous. There is no gap between the unit and the unit in the storage area. But when all members of the storage structure object are stored, in some kind In the compilation environment, you may need the word alignment or double word alignment or other alignment, you need to neighbor Add a number of "quot; padding bytes" between members, this causes several bytes that may be between each member Void. So, in Example 12, even if * PSTR accesses the first member variable A of the structural object SS, Cannot guarantee * (PSTR 1) will be able to access structural member B. Because members a and members b may have Several filling bytes, maybe * (PSTR 1) just accessed these padding bytes. This also proves that The flexibility of the needle. If your purpose is to see if there is any padding byte between the members of each structure. Hey, this is a good way. 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. 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); // The function is called through the function. The pointer can be used as a function of the function. In the function call statement, you can use the pointer expression as a Arguments. 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. Foregoing The name of the array is also a pointer. In the function call, after the STR is transmitted to the conformance S It is actually transmitted the value of the STR to S, S, which is consistent with the address pointed to by the STR, but Str and s each occupies the respective storage spaces. Self-adding 1 operation in the function, does not mean When STR is used, it has been used for STR. chapter eight. Pointer type conversion When we initialize a pointer or assign a pointer, the left side of the assignment number is a pointer, assignment The right side of the value 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 and pointer expression pointing to the pointer. The type 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 f, what should I do? With 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 one The type of pointer, the type of pointer is float *, which is the type of float. The two are inconsistent, directly assigned The method is not good. At least on my MSVC 6.0, the assignment statement of the pointer requires the class on both sides of the value. The same type, the type pointed to, and I haven't tried it on other compilers. You can try it. in order to To achieve our goal, "Mandatory Type Conversion" is required: P = (int *) & f; If there is a pointer P, we need to change its type and the type pointed to Tyep * and 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 *, it points to The type is Type, which pointing the address is the address pointing to the original pointer. And all attributes of the original pointer P Not modified. A function If the pointer is used as a ginseng, then the end of the function calls the statement and ginseng In the process, the conversion of the pointer type will also occur. Example fifteen: 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 that this is a 32-bit program, so the int type accounts for four bytes, and the char type accounts for one byte. letter The role of the fun is to reverse the order of the four bytes of an integer. Do you notice? Call in function In the statement, the results of the real parameters & a are a pointer, its type is int *, which point points to INT. shape The type of this pointer is char *, which is the type of char. In this way, the combination of the arctic and shape In the process, we must conduct a conversion from int * type to Char * type. Combine this example, we can With this way to imagine the compiler, the compiler first constructs a temporary pointer char * TEMP, Then execute Temp = (char *) & A, and finally pass the value of TEMP to S. So the last result is: s The type is char *, which is pointing to 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 It is a 32-bit integer. Can you assign an integer as a value of the pointer to the pointer? As if 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 the pointer PTR point to the address 20345686 (decimal) Compile it. It was found that the following two statements were all wrong. So, our purpose cannot be reached. Yet? No, there is also a way: Unsigned int A; 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 (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 a legal address. Otherwise, when you use PTR. It will have an illegal operation error. Think of that you can't turn it, the value of the pointer to the pointer is taken out as an integer. Finish Come. The following example demonstrates the value of a pointer as an integer, and then put this Integer is assigned to a pointer as an address: Example 16: INT A = 123, B; INT * PTR = & A; Char * STR; B = (int) PTR; // Take out 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 Put a integer value as an address to a pointer. Chapter nine. Pointer security problem Look at the example below: Example 17: CHAR S = 'a'; INT * PTR; PTR = (int *) & s; * PTR = 1298; The pointer PTR is an int * type pointer, which is the type whose point is Int. The address it points to is s First address. In the 32-bit program, s is one byte, and the int type is four bytes. The last statement is not only Changes one byte of S, and also changes the three bytes of the high address direction in S. These three What is the one is doing? Only the compiler knows that the writer is unlikely. Maybe These three bytes have been stored very important data, perhaps the three bytes is just a code of the program. And because of your horses and tiger applications, these three bytes have been changed! This will cause collapse error. Let's take another example: Example 18: 1. Char a; 2. INT * PTR = & A; ... ... 3. PTR ; 4. * PTR = 115; This example can be compiled and can be executed. But did you see? The third sentence is performed on the pointer PTR After 1 operation, PTR points to a storage area in the high address direction adjacent to the plastic variable A. This storage What is the area? we do not know. It is possible that it is a very important data, and it may even be a generation. code. The fourth sentence actually writes a data in this storage area! This is a serious mistake. So in use When the needle, the programmer must be very clear about: Where is my pointer pointing? When accessing arrays with a pointer, be careful not to exceed the low-end and high-end boundaries of the array, otherwise It will also cause a similar error. Mandatory type conversion in the pointer: PTR1 = (Type *) PTR2, if SIZEOF (PTR2 type) is large At SIZEOF (Type of PTR1), it is secure when using the pointer PTR1 to access the storage area pointed to PTR2. If SIZEOF (Type of PTR2) is less than SizeOf (PTR1 type), then the pointer PTR1 is used. It is not safe when accessing the storage area pointed to PTR2. As for why, the reader combined with the case of seventeen Think, it should be understood.