We can define the pointer as follows:
Through the first address stored in the pointer, the application smoothly finds a variable. It's like I recently met a friend who told me to go to his house and sit down. Then he left his address. One weekend I was idle and suddenly remembered this friend. So I went to him based on his address. As a result, when I came to rent a house at No. 230, silly B Street, there was a person I didn't know, so I asked him where my friend went. The Stranger said, I just rented this house, you may be looking for the previous tenant.
Therefore, the address pointed to by the pointer may be variable B, variable F, or variable S. the pointer is the landlord who can rent the house to B, C, or F, it can dynamically allocate memory for the variable, or destroy the variable (delete). If you cannot afford the rent, you can get out of the way (destructor ).
From the above story, we can see two usage of pointers: Index memory and allocation memory.
Let's take a look at the example below.
[CPP]
View plaincopyprint?
- # Include <stdio. h>
- Void main ()
- {
- Int * pint =
Newint (100 );
- Printf ("* pint value: % d \ n", * pint );
- Printf ("Pint value: 0x % x \ n", pint );
- Getchar ();
- }
# Include <stdio. h> void main () {int * pint = new int (100); printf ("* pint value: % d \ n", * pint ); printf ("Pint value: 0x % x \ n", pint); getchar ();}
You can guess what will happen after it runs?
We can see that the pint contains the first address of the integer 100, because it is an int *, It is a pointer to the int, so the pointer knows, find the first address, I only pay attention to the four consecutive bytes starting from the first address. I don't care about them because I only know that int has four bytes. In the above example, we can see that the pint value is 0x10f1968, which is the first address of integer 100 in the memory. Therefore, the memory block of 100 may be:
0x10f1968, 0x10f1969, 0x10f196a, 0x10f196b
In short, it is a continuous memory block to save these four bytes.
New int (100) indicates that the pointer pint creates a four-byte area in the memory area with the first address 0x10f1968, and the value saved in the area is an integer of 100. Therefore, pint gets the first address of 100, and adding the * number is different. Let's take a look at the above example. * The pint value is 100. In this way, we get another skill:
Use the pointer identifier * Before the pointer variable to obtain the actual value stored in the address indicated by the pointer.
It's a simple skill for me. Let's look at the following two lines of code.
Int * P = new int (200 );
Int P = 200;
It is acceptable to place * after the type or before the variable name, that is, int * pint and int * pint are reasonable. In this way, we may consider int * pint as int (* pint) and the entire * pint as a whole. Does this look like the following statement?
Int A = 30;
Therefore, in int * P = new int (30), * P returns 30 of the int value, while P returns 30 of the first address.
Let's look at the following code:
[CPP]
View plaincopyprint?
- # Include <stdio. h>
- Void main ()
- {
- Int * arrint = newint [3];
- Arrint [0] = 20;
- Arrint [1] = 21;
- Arrint [2] = 22;
- For (INT I = 0; I <3; I ++)
- {
- Printf ("array [% d] = % d \ n", I, arrint [I]);
- }
- Delete [] arrint; // clear memory
- Getchar ();
- }
# Include <stdio. h> void main () {int * arrint = new int [3]; arrint [0] = 20; arrint [1] = 21; arrint [2] = 22; for (INT I = 0; I <3; I ++) {printf ("array [% d] = % d \ n", I, arrint [I]);} delete [] arrint; // clear the memory getchar ();}
Now you can guess what the running result is.
From the code above, we can see the third function of the pointer:Create an array.
In the preceding example, an array with three elements is created. After use, delete is used to delete the allocated memory. Therefore, in our first example, the memory is not completely cleaned.
Int * pint = new int (100 );
/****/
Delete pint;
Why can an array be created by a pointer? As I mentioned above, the Pointer Points to the first address, so think about it. If our array is allocated memory on the stack, are they also stored in a continuous memory address in a certain order, and the entire array also forms a memory block.
2. Get the address Symbol &
Many books and tutorials call this symbol a reference, but I do not like to translate it into a reference because it is hard to understand the reference. If it is called an address character, you will probably understand it, it is the first address of a variable.
Let's look at the example:
[CPP]
View plaincopyprint?
- # Include <stdio. h>
- Void main ()
- {
- Int A = 50;
- Int * P = &;
- Printf ("value of A: % d \ n", );
- Printf ("P value: 0x _ % x \ n", P );
- Getchar ();
- }
# Include <stdio. h> void main () {int A = 50; int * P = & A; printf ("value of A: % d \ n", ); printf ("P value: 0x _ % x \ n", P); getchar ();}
We cannot directly assign values to pointer variables. To pass the address of the variable to the pointer, we need to use the address character &. In the above Code, we declare the int type variable A with a value of 50, and store the address of variable A to the P pointer through the & Symbol. In this way, P points to the first address of variable A. Therefore, the value of a is 50, and the value of P is the address of.
So what are the benefits of doing so? Let's extend the above example to the following:
[CPP]
View plaincopyprint?
- # Include <stdio. h>
- Void main ()
- {
- Int A = 50;
- Int * P = &;
- Printf ("value of A: % d \ n", );
- Printf ("P value: 0x _ % x \ n", P );
- /* Changing the value in the address block pointed to by the pointer is equivalent to changing the value of the variable */
- * P = 250;
- Printf ("new value of A: % d \ n", );
- Getchar ();
- }
# Include <stdio. h> void main () {int A = 50; int * P = & A; printf ("value of A: % d \ n", ); printf ("P value: 0x _ % x \ n", P);/* changes the value in the address block pointed to by the pointer, it is equal to changing the variable value */* P = 250; printf ("new value of A: % d \ n", a); getchar ();}
Preview The result first.
I don't know what you found in this example?
We defined the variable A with a value of 50, and the pointer P points to the first address of a, but note that I only changed the value in the memory that P points, I didn't modify the value of A. But you can see that the value of a has also changed to 250. Think about it. Why?
Iii. parameter transfer method
Many books, including some computer second-level exam content, the silly s brick house just came up with a lot of inexplicable questions related to pointers, but it is hard to find out what the pointer can do in practical use, I guess those brick companies do not know themselves. Therefore, the biggest failure of our exam is to make students learn nothing.
The above section describes how to use pointers to store the first address, allocate memory, create arrays, and get the address operator? You will certainly ask, why should I use a pointer to store the first address if I declare a variable directly to occupy the memory?
Well, I will not answer the question first. Let's talk about passing function parameters. Let's look at the example below.
[CPP]
View plaincopyprint?
- # Include <stdio. h>
- Void FN (int x)
- {
- X + = 100;
- }
- Void main ()
- {
- Int A = 20;
- FN ();
- Printf ("A: % d \ n", );
- Getchar ();
- }
#include <stdio.h>void fn(int x){x += 100;}void main(){int a = 20;fn(a);printf(" a : %d\n", a);getchar();}
We hope that after the FN function is called, the value of variable A will be added with 100. Now let's run it and see the result:
We may be disappointed. Why? I clearly uploaded 20 to the FN function. Why does a's value remain unchanged? Don't worry. Let's change the code:
[CPP]
View plaincopyprint?
- # Include <stdio. h>
- Void FN (int x)
- {
- Printf ("parameter address: 0x _ % d \ n", & X );
- X + = 100;
- }
- Void main ()
- {
- Int A = 20;
- FN ();
- Printf ("A: % d \ n", );
- Printf ("A address: 0x _ % x \ n", & );
- Getchar ();
- }
# Include <stdio. h> void FN (int x) {printf ("parameter address: 0x _ % d \ n", & X); x + = 100;} void main () {int A = 20; FN (a); printf ("A: % d \ n", a); printf ("A address: 0x _ % x \ n ", & A); getchar ();}
The running result is as follows:
Have you seen it? The addresses of the parameters X in the and FN functions are different. What does this mean? This indicates that, although the value of variable A is passed to the parameter X, it is actually a new variable X, and the value of X is 20, and then 100 is added, the value of X is 120, but the value of A is not changed, because in the function, the value of + 100 is not variable A, but variable X (parameter ).
This explains why the value of a remains unchanged after the function is called.
So, how can we change variable A to 120 after the function is called? There are two methods:
(1) pointer method. Change the parameter to the pointer type.
[CPP]
View plaincopyprint?
- # Include <stdio. h>
- Void FN (int * X)
- {
- * X + = 100;
- }
- Void main ()
- {
- Int A = 20;
- FN (& A); // It is transmitted using an address operator because the pointer stores the address
- Printf ("A: % d \ n", );
- Getchar ();
- }
# Include <stdio. h> void FN (int * X) {* x + = 100;} void main () {int A = 20; FN (& ); // It is passed with an address get, because the pointer is the printf ("A: % d \ n", a); getchar ();}
Note,To pass a variable to a parameter of the pointer type, use the get URL &.
So, is this operation correct?
Now, we can see the desired result.
(2) The reference method is to change the parameter to & passed.
[CPP]
View plaincopyprint?
- # Include <stdio. h>
- Void FN (Int & X)
- {
- X + = 100;
- }
- Void main ()
- {
- Int A = 20;
- FN (a); // directly pass the variable name.
- Printf ("A: % d \ n", );
- Getchar ();
- }
# Include <stdio. h> void FN (Int & X) {x + = 100;} void main () {int A = 20; FN (); // directly pass the variable name to printf ("A: % d \ n", a); getchar ();}
We can see that the running result is correct.
Iv. pointers and objects
Whether it is a class or a structure (in fact, the structure is a special class), they still need to create memory during creation, but there are two ways to create class objects, directly declare and assign new instances with pointers.
[CPP]
View plaincopyprint?
- # Include <iostream>
- Using namespace STD;
- Class Test
- {
- Public:
- Test ();
- ~ Test ();
- Void Do (char * C );
- };
- Test: Test ()
- {
- Cout <"test object is created. "<Endl;
- }
- Test ::~ Test ()
- {
- The cout <"test object is destroyed. "<Endl;
- }
- Void test: Do (char * C)
- {
- The do method is called in cout <"<C <. "<Endl;
- }
- Void func1 ()
- {
- Test T;
- T. Do ("func1 ");
- /*
- When the function execution is complete, t's lifecycle ends and the structure is generated.
- */
- }
- Void func2 ()
- {
- Test * PT = new test;
- Pt-> do ("func2 ");
- /*
- Objects Created with pointers are not destroyed even if the lifecycle of the pointer variable ends.
- Therefore, the Destructor is not called.
- */
- }
- Int main ()
- {
- Func1 ();
- Cout <"---------------------" <Endl;
- Func2 ();
- Getchar ();
- Return 0;
- }
# Include <iostream> using namespace STD; Class test {public: Test ();~ Test (); Void Do (char * C) ;}; test: Test () {cout <"test object is created. "<Endl;} test ::~ The test () {cout <"test object is destroyed. "<Endl;} void test: Do (char * c) {cout <" The do method is called in "<C <. "<Endl;} void func1 () {test T; T. Do (" func1 ");/* after the function is executed, the life cycle of t ends and the structure is generated. */} Void func2 () {test * PT = new test; Pt-> do ("func2");/* object created with pointer, even if the lifecycle of the pointer variable ends, the objects in the memory are not destroyed. Therefore, the Destructor is not called. */} Int main () {func1 (); cout <"-------------------" <Endl; func2 (); getchar (); Return 0 ;}
Let's take a look at this example. First, a class test is defined. In the class constructor, output the information of the object to be created, and the output object is destroyed during the analysis.
Then, we create the test class objects in the two functions respectively, because the objects are defined inside the function. According to the lifecycle principle, the objects will be released when the function returns, data in the memory will be destroyed. In theory, what will happen after the program is actually running?
At this time, we found an interesting phenomenon. The objects directly created in the form of variables in the first function are destroyed after the function is executed, because the Destructor is called. However, we can see that this did not happen in the second function. The object created with the pointer did not call the Destructor when the function was completed.
Directly create an object, and the variable is directly associated with the class instance. As a result, when the life cycle of the variable ends, it will be processed and the instance created with the pointer will be used, the pointer variable itself does not store the data of the instance. It only stores the first address of the object instance and the pointer is not directly related to the instance. Therefore, after the second function is executed, the destroyed object is test *, instead of the test object. The pointer that saves the first address is released, and the test object still exists in the memory. Therefore, after the second function is completed, the destructor of test will not be called because it is not dead yet.
So how can we let the second function destroy the object instance when returning? Remember, I mentioned it earlier. Yes, delete ..
[CPP]
View plaincopyprint?
- Void func2 ()
- {
- Test * PT = new test;
- Pt-> do ("func2 ");
- Delete pt;
- }
void Func2(){Test* pt = new Test;pt -> Do("Func2");delete pt;}
Now let's see if the objects can be destroyed when both functions return.
Now, do you understand?
Therefore, we can draw a conclusion:Pointers are only responsible for allocating and clearing the memory for objects and are not directly related to the object instances in the memory.
Source: http://blog.csdn.net/tcjiaan/article/details/8493072