[C ++ exploration journey] Part 1 Lesson 12th: a pointer to the challenge

Source: Internet
Author: User

[C ++ exploration journey] Part 1 Lesson 12th: a pointer to the challenge

Introduction

1. Part 1TenthLesson 2:Who is fighting for power

2. Part 1 Lesson 13th notice: Part 1 quiz

Who is fighting for power

In the first part of the "C ++ exploration Journey" section 11th: small exercises and word guesses, we used a small game to summarize the knowledge points learned in previous lessons.

Now, I finally come to the last knowledge point in the first part. It is also the last lecture in the basic part of C ++. The second part will start the object-oriented journey. Therefore, this lesson is doomed to be extraordinary. Fasten your seat belt, because the horsepower is enough!

Pointer is the difficulty of the C series language (the famous C language also has pointers), so that countless heroes "fold", is also one of the most difficult lessons in this series of courses. But don't worry, as long as you patiently follow the small series, how can we not wet shoes... Oh, no, it will certainly cure you "waist disc highlight "!

As long as the waist is recovered, you will find that many other knowledge points will become very clear and easy. Moreover, the waist is not sour, the leg does not hurt, one breath can go to the fifth floor ...... make up you enough...

Pointers are widely used in C ++ programs. We have been using it in the previous course, but you didn't realize it. As long as you have learned the pointer, the level of control over the memory has taken another step.

Okay, no appetite. Let's go ~

Memory Address Problems

Do you still remember the lesson about memory? This is Part 4 of [C ++ exploration journey]: memory, variables, and references. I hope you can review that lesson, especially the memory diagrams.

As mentioned in that lesson, when we declare a variable, the operating system will lend us a small memory space and give it a name (the name of the variable ). It's like lending us a drawer and sticking a label out of the drawer. For example:

intmain(){intuserAge(16);return0;}

 

We can use the memory diagram to illustrate the above Code:

 

 

It's simple and clear, isn't it? However, it simplifies a lot of things.

 

You will gradually find that everything in the computer is orderly and logical. Previously, we compared the address space in the memory to a drawer, which is labeled (if assigned to a variable), that is, the name of the variable. The actual situation is more complex than this.

 

The computer's memory is indeed composed of multiple "Drawers", and we have not said wrong before. Moreover, modern computers have up to billions of "Drawers" in memory "!

 

Therefore, we need a system to help us find the right drawer in the vast ocean of drawers. Each drawer in the memory has a unique ID, that is, the memory address. As shown in:

 

 

, We see the "Drawers" in the memory, each drawer corresponds to a memory address.

 

Our previous program only used one of the "Drawers" and its memory address was 53768. This drawer stores our variable userAge.


Note: Each variable has a unique memory address, and each memory address can only store one variable at a time.

 

In our previous course, we used the variable name to access a variable, for example:

 

UserAge = 18; // use the variable name to access the variable and assign a value to the variable.

 

However, we can also use the variable address as the medium for accessing the variable. For example, we can say "hello" to the computer and show me the content on memory address 53768.

 

Maybe you will say: since the first method to access a variable with a variable name is simple and efficient, why the second method?

 

Yes, but we will immediately see that sometimes it is necessary to use the memory address to access the variable.

 

Before that, we should first learn how to know the memory address of the variable.

 

Display memory address

 

In C ++, like the C language, it is used to obtain the memory address of a variable. We need to use the & symbol. & Also known as "Get address ".

 

If I want to get the memory address of the variable userAge, it is very simple. I just need to write it like this:

 

&userAge

 

Try to write a program:

 

# Include
 
  
Usingnamespacestd; intmain () {intuserAge (16); cout <"the memory address of the variable userAge is" <& userAge <
  
   

 

After running, what is displayed on my computer is:

 

The memory address of the variable userAge is 0x22ff0c.

 

 

When you run your program, the displayed memory address is generally different from mine. After all, the memory address is allocated by the operating system.

 

Although the memory address shown above contains letters, it is actually a number.

 

The memory address is displayed in hexadecimal format by default (0x at the beginning indicates that the following number is in hexadecimal format, so it is actually a hexadecimal number.22ff0c). We are very familiar with decimal, that is, we generally use the number system. The bottom layer of the computer actually only knows the binary consisting of 0 and 1.

 

However, in decimal, binary, and hexadecimal formats, they can be converted to each other. As for how to switch, I have been taught in schools. If not, Baidu is not difficult. Or you can use the calculator program that comes with your computer to implement the conversion between systems.

 

For example, the above hexadecimal number (0x22ff0c) is converted into a decimal value of 2293516 and a binary value of 1000101111111100001100.

 

Our & symbol is used to display the variable address here. We also use the & symbol when talking about references. Therefore, do not confuse the two usage methods.

 

Next, let's take a look at what these addresses can do.

 

Pointer, which type?

 

The memory address is actually expressed in numbers.

 

We already know that in C ++, there are multiple data types that can store numbers: int, unsigned int, double, and so on. So can we store the memory address in the variable?

 

The answer is yes.

 

However, to store the memory address, we should use a special type instead of the common variable types we have seen before: pointer.

 

Pointer, in short, is a variable that stores the memory address of another variable.

 

Remember this sentence.

 

Declare a pointer

 

Declaring a pointer is similar to declaring a common variable. Two things are required:

 

Type

Name

 

As for the name, it is the same as before. As long as it complies with the rules, you can take whatever name you like.

 

However, the pointer type is somewhat special. This type must specify the type of the variable on the address we want to store, and add a * number. For example:

 

int*pointer;

 

Does it look special? An asterisk (*) is added to the declaration of an int type variable (*). It is this * That indicates that this is a pointer variable.

 

The above Code declares a pointer named pointer, whose content is the memory address of the int type variable. It can also be said that pointer points to an int type variable (the reason why it is called a "pointer ).


We can also write it as follows:

 

int*pointer;

 

This time we set * to be adjacent to int. Previously we wrote * to be next to pointer. The two statements have the same effect, but we recommend the previous one.

 

Why? If it is written in the form of int * pointer, it is easy to think that int * is a whole. If we declare multiple pointers at the same time on a row, it is easy to write like this:

 

int*pointer1,pointer2,pointer3;

 

Our original intention is to declare three pointer variables pointer1, pointer2, and pointer3, all pointing to int variables. But in fact, only pointer1 is successfully declared as a pointer variable, and the following pointer2 and pointer3 are only int variables!

 

This is important for beginners. Therefore, we generally write as follows:

 

Int * pointer1, * pointer2, * pointer3; // declare three pointer Variables


Similarly, we can declare pointers to other variable types. For example:

 

Double * pointerA; // declare a pointer, where you can store the address of the double type variable unsignedint * pointerB; // declare a pointer, here, the address of the unsignedint type variable can be stored as string * pointerC; // declare a pointer, where the address vector of the string type variable can be stored.
    
     
* PointerD; // declare a pointer, which can store the vector
     
      
Type Variable address intconst * pointerE; // declare a pointer, where the address of the intconst type variable can be stored
     
    

 

Note: A pointer is a variable type. The variable type has a fixed size on each operating system, as if it were int or double. Do not think that the pointer can store the address of the int type variable. This pointer is an int type pointer. This statement is inaccurate.

 

You can test to use the sizeof operator to obtain the number of bytes occupied by the pointer type.

 

For example:

 

Cout <"the pointer size is" <
    
     

 

On my computer, the printed result is

 

The pointer size is 4.

 

That is to say, the pointer size is 4 bytes and does not change with the type of the variable on the memory address it points.

 

For the moment, the pointers above are only declared and are not assigned a value.

 

This is dangerous!

 

In this case, the pointer can contain any memory address. If you use an unassigned pointer, you do not know which address you are in the memory. It is possible that this memory address stores extremely important data.

 

Therefore, always remember: After declaring a pointer, you must assign a value to it before using it.

 

Therefore, a good habit is to assign an initial value to the pointer while declaring it, even if it is initialized. Usually, it is used to assigning 0, for example:

 

int*pointer(0);double*pointerA(0);unsignedint*pointerB(0);string*pointerC(0);vector
      
       *pointerD(0);intconst*pointerE(0);
      

 

Do you still remember the memory image we gave at the beginning of this lesson? The number of the first available drawer of the memory is 1 rather than 0. The memory space with the address 0 is generally unavailable.

 

Therefore, when we assign an initial value of 0 to a pointer variable, it means that it does not point to any memory address. It's like using a reins to tie a messy Hummer to the pile of 0 ("horse-riding man, you are mighty and mighty ...").

 

Therefore, it is necessary to assign an initial value 0 to a pointer variable without deciding the address to which it points.


Store a memory address

 

Now we will declare the pointer variable. Next we will learn how to store the memory address of another variable to this pointer variable.

 

We already know that to obtain the memory address of a variable, the & symbol is used. This is simple, for example:

 

Intmain () {intuserAge (16); // an int type variable int * ptr (0); // a pointer variable, the memory address ptr = & userAge; // store the address of the int variable userAge In the pointer variable return0 ;}

 

In the above procedures, the most critical sentence is

 

ptr=&userAge;

 

After executing this command, the content in the pointer variable ptr becomes the address of the userAge variable. We say: ptr points to userAge.

 

Use a memory graph to describe:

 

 

In, we see our old friend userAge. This variable is stored at memory address 53768 and the variable value is 16.

 

The newly added content is pointer. There is a pointer variable in the memory address 14566 (of course, these memory addresses are for example). The name is ptr. Note that the ptr value is 53768, that is, the address of our userAge.

 

Well, now you almost understand it.

 

Of course, you may still have a question: why should I store the memory address of a variable in another variable? What are the benefits?

 

Believe me, you will "keep the cloud and see the moon.

 

If you understand it, it is time to study in depth.

 

Display memory address

 

Pointer is also a type of variable, so we can display its value.

 

Write a program:

 

# Include
      
       
Usingnamespacestd; intmain () {intuserAge (16); int * ptr (0); ptr = & userAge; cout <"the memory address of the variable userAge is" <& userAge <
       
        

 

Run the above program:

 

The memory address of the variable userAge is0x22ff0c

The pointer variable ptr value is0x22ff0c

 

 

Have you seen it? The memory address of our userAge variable is the same as the ptr value of the pointer variable.

 

Content pointed to by the Access pointer

 

Do you still remember the role of pointers? It allows us to access a variable without passing the variable name.

 

How can this problem be solved? Use the * sign to obtain the value of the variable pointed to by the pointer.

 

For example:

 

Intmain () {intuserAge (16); int * ptr (0); ptr = & userAge; cout <"the value of the variable pointed to by the pointer ptr is" <* ptr <
         
          

 

When the program runs to cout <* ptr, the following operations are performed in sequence:

 

Find the memory address space named ptr

Read content in ptr

"Followed by" pointer pointing to the address (that is, the ptr value), find the memory space of the address

Read the content (value of the variable userAge)

Print this value (16 here)

 

Here we use the asterisk (*) Again, the term is: "unreferencing" a pointer.

 

Do you still remember that we used asterisks to declare pointer variables? Therefore, the same symbol may be used differently under different circumstances.

 

Symbol Summary

 

I admit, these symbols are a little dizzy. So far, asterisks (*) have two functions and are used for reference before this lesson.

 

You can't blame me for this, right? You must blame the father of C ++.

 

Let's summarize:

 

Suppose we have the following code:

 

intnumber=16;int*pointer=&number;

 

So:

 

For int variable number

 

Number: Value of number

& Amp; number: Memory Address of number

 

For pointer

 

Pointer: the pointer value, that is, the memory address of another variable it points. That is, the address of number, that is, & number

* Pointer: the memory value pointed to by the pointer, that is, the value of number.

 

If you do not understand it, you can draw some diagrams to help you grasp it.

 

Dynamic Allocation

 

Do you want to know what the pointer can do? Well, let's first learn the first usage: dynamic allocation.

 

Automatic Memory Management

 

In our previous courses on variables, we have learned that when variables are defined, the program actually takes two steps:

 

The program requests the operating system to allocate a piece of memory space to it. In professional terms: memory allocation.

Fill in the memory space with a value, which is called variable initialization.

 

The above two steps are automatically completed, and the program will take care of us. In addition, when our program is executed to the end of the function, the memory space allocated by the operating system will be automatically returned. The terminology is: memory release. In this case, the memory is released automatically.

 

Now we can learn that it is neither an automatic method nor a manual method. Yes, you should have guessed it. We should use pointers.

 

Allocate memory space

 

To manually apply for memory space, we need to use the new operator.

 

The meaning of "new" in English.

 

New will apply for a memory space. If it succeeds, a pointer pointing to this memory space will be returned. So it's our turn to play. For example:

 

int*pointer(0);pointer=newint;

 

The second line of the above two programs requests a memory address from the operating system to store int variables. The address value of this memory address will be stored in the pointer. Shows the principle:

 

 

 

We can see that we use a total of two Memory Spaces:

 

The address of the first memory space is 14563, which stores an int variable that has not been assigned an initial value, and this variable has no name.

The address of the second memory space is 53771, which stores our pointer and the pointer value is 14563.

 

Remember: The variables at memory address 14563 have no variable names and can only be accessed through the pointer.

 

Therefore, if we modify the pointer value, we lose the chance to access the untagged memory. You cannot use or delete the memory. This memory seems to be lost, but it also occupies memory. The term is memory leakage. So be careful!

 

Once the manual allocation is successful, this variable is used in the same way as the current variable. But we operate on this variable by pointing to the pointer, because we didn't give the variable a name. Dereference (*) is required (*).

 

Int * pointer (0); pointer = new int; * pointer = 2; // access the memory through the pointer to rewrite the content.

 

The memory space without tags (equivalent to a variable without a variable name) is now filled with a value of 2. Therefore, the memory is as follows:

 

 

After using this memory address, we need to return this memory address (the memory address pointed to by the pointer) to the operating system ).

 

Release memory

 

We use the delete operator to release the memory.

 

Delete indicates "delete, clear" in English. For example:

 

Int * pointer (0); pointer = new int; delete pointer; // release the memory. Note: The memory to which the pointer is directed is released.

 

After the above operation is performed, the memory pointed to by the pointer will be returned to the operating system. However, the memory still exists and still points to that memory. However, we have no right to use this pointer again. As shown in:

 

 

It is still relatively visual. If we follow the arrow indicated by the pointer, we will reach a memory that is no longer ours. Therefore, we can no longer use this memory.

 

"Where will I go if I am married? How to solve the problem, only porridge"

 

Therefore, in order to avoid misoperation of the memory, we need to delete the arrow pointing to memory that is not ours after the delete operation. Intelligent, as you should have thought, is to set the pointer value to 0 (invalid memory address ). If this step is not set to 0, the program will often crash, even if it is not failed at the moment, it is also a hidden danger.

 

Int * pointer (0); pointer = new int; delete pointer; // release memory pointer = 0; // point the pointer to an Invalid Address

 

Remember: After the memory is manually allocated, the memory must be released after use. Otherwise, your memory will be less and less. Once the memory is insufficient, your program will crash.

 

A complete example

 

Let's end this section with a complete example: Ask the user's age and use the pointer to show the age

 

# Include
           
            
Using namespace std; int main () {int * pointer (0); pointer = new int; cout <"What is your age? "; Cin> * pointer; // use the pointer variable pointer, we have rewritten the cout content on the memory address pointed to by pointer <"you" <* pointer <"years old. "<endl; // use the pointer again? ? Delete pointer; // do not forget to release the memory? Pointer = 0; // and point the pointer to an invalid address? ? Return 0 ;}
           

 

Through this example, we have learned how to allocate and release memory through pointers.

 

Then, we will learn how to use Qt to develop a graphic interface program. We often use the combination of new and delete, for example, when creating and destroying a form.

 

When should we use pointers?

 

In the last section of this lesson, we need to explain: when to use pointers?

 

Pointers are usually used in the following three cases:

 

You want to control the allocation and release of memory space by yourself

Share a variable in multiple code blocks

Select between multiple elements

 

In other cases, we do not need to use pointers.

 

First, we have learned. Let's see the last two types.

 

Share a variable

 

For pointer usage, I will not give you a complete sample code for the moment. When we talk about Object-Oriented Programming in the second part, we will naturally have instances. However, I will give a more visual example.

 

Have you ever played a strategy game? If you have never played it, you may have heard of it.

 

For example, one of these games is famous: Warcraft III, a work of blizzard. As follows:

 

 

Writing such a large RPG Game is very complicated. We will not discuss games here, but use cases here.

 

In the middle, we can see red and blue beasts fighting. Each role in the game has an attack target.

 

For example, almost all the forces of the beasts are under attack, and the Shadow Hunter becomes the king of the hill of a small animal (that is, the "small animal" at the mouse point "). The human forces are attacking the swordsmanship.

 

In C ++, how do we specify the red target? Of course, you still don't know how to implement it with code, but you should have some idea? Think back to the topic of this lesson.

 

Yes, it is a pointer. Each role in the game has a pointer pointing to the target of their attack. In this way, each role will know who to attack at a certain moment. For example, you can write the following code:

 

Personage * target; // a pointer to the target

 

Before the two sides fight, the target Pointer Points to address 0, that is, there is no attack target. Once the two armies are connected, the target Pointer Points to the target of the attack. As the game proceeds, the target can be switched.

 

Therefore, in such a game, a pointer can associate a role with its attack target.

 

Then we will learn how to write such code. In the second part, we can also write a small role-playing game (RPG Game ).

 

Select between multiple elements

 

The third purpose of pointer is to make different responses based on different user choices.

 

For example, we will give you a Multi-choice question with three options. Once the answer is selected, we use a pointer to show which answer is selected. The Code is as follows:

 

# Include
           
            
# Include
            
             
Using namespace std; int main () {string responseA, responseB, responseC; responseA = "autistic space Phobia"; responseB = "Alzheimer's Disease"; responseC = "delusion "; cout <"What does Alzheimer's disease mean? "<Endl; // ask A question // display the answer cout <" A) "<responseA <endl; cout <" B) "<responseB <endl; cout <"C)" <responseC <endl; char response; cout <"your answer is (enter A, B, or C ):"; cin> response; // extract the user's answer string * userResponse (0); // pointer to the selected answer switch (response) {case 'A': userResponse = & responseA; break; case 'B': userResponse = & responseB; break; case 'C': userResponse = & responseC; break ;} // use a pointer to display the selected answer cout <"you have selected the answer" <* userResponse <endl; return 0 ;}
            
           

 

Of course, pointers are still useful and we will learn them later.

 

Summary

 

Each variable is stored in a different address space in the memory.

Each address can only store one variable at a time.

You can use the & symbol to obtain the address of a variable. Its usage is: & variable

A pointer is a special variable type that stores the address of another variable.

A pointer is declared as follows: int * pointer; (in this case, the pointer points to an int type variable)

If we print the content of a pointer, we get the memory address in it. If we use the * symbol to obtain the memory (* pointer) pointed to by the pointer, print the variable values stored on the address pointed to by the pointer:

We can manually apply for a memory address with the new keyword. If the new keyword is used for dynamic memory allocation and this variable is not used, we need to use the delete keyword to manually release this memory (because it will not be automatically released ).

Beginner pointers may find it hard to understand. But don't worry. You can read this lesson again. He has read books for hundreds of times, and he has his own opinions. However, you must also work with the exercises. Don't be afraid. We will often use pointers in the future, so you will become proficient.

Part 1 Lesson 4 advance notice

Today's class is here. Come on!

In the next lesson, we will learn:Part 1 quiz

    Contact Us

    The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

    If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

    A Free Trial That Lets You Build Big!

    Start building with 50+ products and up to 12 months usage for Elastic Compute Service

    • Sales Support

      1 on 1 presale consultation

    • After-Sales Support

      24/7 Technical Support 6 Free Tickets per Quarter Faster Response

    • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.