Detailed explanation of C++ pointers (turn)

 

1. Getting to know the pointer

What is a pointer? Think about what the pointer in our mind looks like:

Insert picture description here
such? Then let's talk about how to use the "pointer" table today!

Insert picture description here
Ahem, no kidding!
In programming languages, pointers are much more abstract than the "pointers" you can see above. So when we study, we often know that there is such a thing as a pointer, but we are confused and don't know how to use it. Next, I will take you to intuitively feel what a pointer is!

Simply put, a pointer is a special kind of variable. The special point is that this variable does not store ordinary values ​​(such as 1, 2, 100,'q'); it stores memory addresses, such as 0x101, 0x886, etc.

It doesn't matter if you don't understand it. Below I have drawn a schematic diagram to let everyone intuitively see what a pointer is:
Insert picture description here
Note: The 0x886 in the figure is for the convenience of explaining the assumed virtual address.

We all know that the storage of variables takes up memory space.
In the figure, Age is a variable, its storage address is 0x886, and its stored value is 18.
pAge is a pointer, which can also be said to be a special variable. Its storage address is 0x601, and its stored content is 0x886.

By comparison, it is easy to find that pointers and variables have many similarities; the difference is that pointers store memory addresses.

If you look closely, you can find that: the address stored in the pointer pAge = the memory address of the variable Age. Therefore, it can also be said that the pointer pAge is a special variable that points to the memory unit Age.

I believe that at this point, everyone has an intuitive understanding of the pointer. So how do we use it?
Master the following four parts, you can easily get started with pointers:

  1. Declare pointer
  2. Use & to get variable address
  3. Use pointers to store addresses
  4. Use * to access the pointed data

Let's study these four parts separately!

(1) Declare pointer

As a special variable, pointers also need to be declared. Let's recall first, how we declared an int type variable in the [C++ Development Plan] to explain in a simple way-variable scope (Day3) :

int Age; //声明一个变量Age
  •  

When declaring a pointer, you also need to specify the type. And this type, such as int, corresponds to the type of the number stored in the memory unit that the pointer points to.

int *pAge; //声明一个指针变量
  •  

When declaring a variable, we generally initialize the variable to 0. Similarly, when declaring a pointer, we don't want it to point to a random memory unit. Therefore, the pointer is initialized to NULL.

int Age = 0;
int *pAge = NULL;
  •  

Note: A pointer initialized to NULL is called a NULL pointer or a null pointer. A null pointer (ie pAge) is a constant defined in the standard library with a value of zero.

(2) Use & to get variable address

The symbol & is called 引用运算符. If Age represents a variable, &Age will be the memory address where the variable is stored.
Below, we give a simple example to get the address of the variable Age:

#include<iostream>
using namespace std;
int main()
{
	int Age=18;
	cout<<"变量Age存放在内存中的地址是:"<<hex<<&Age<<endl;
	return 0;
}

Output results after running:
Insert picture description here
Note: The hex in the program is for the output format to be hexadecimal, which is a convention for address representation.

(3) Use pointers to store addresses

We know that a pointer is a variable used to store memory addresses, and how to declare a pointer and get the address of a variable. Now you can associate them and use pointers to store & get the address.
Insert picture description here
As shown in the figure above, this time we can get the address directly through &Age and pass it to the pointer pAge.
Here is a small example to declare and initialize pointers.

#include<iostream>
using namespace std;
int main()
{
	int Age = 18;
	cout<<"变量Age存放在内存中的地址是:"<<hex<<&Age<<endl;
	int *pAge = &Age;
	cout<<"指针pAge中存放的地址是:"<<hex<<pAge<<endl;
	return 0;
}

 

 

Operation result: It
Insert picture description here
can be seen that the address stored in the memory of the variable Age = the address stored in the pointer pAge. Explain that the reference operator & got the memory address of Age and passed it to the pointer pAge.

(4) Use * to access the pointed data

The symbol * is also called 解除引用运算符. Usually, as long as it is a valid pointer pAge, we can access it through *pAge 指针pAge包含的地址处存储的值. (Note that it is the value corresponding to the access address, not the address)
Here is a simple example:

#include<iostream>
using namespace std;
int main()
{
	int Age = 18;
	cout<<"Age = "<<Age<<endl;
	int *pAge = &Age;
	cout<<"*pAge = "<<*pAge<<endl; 
	return 0;
}

 

Operation result:
Insert picture description here
Simply put, the pointer pAge points to the memory unit corresponding to the variable Age, so the value corresponding to Age can be obtained through the symbol *.

2. Dynamic memory allocation

In order to help developers better manage the memory occupied by applications, C++ provides two operators: new and delete. Pointers are variables that contain memory addresses and play an important role in efficiently allocating memory.

(1) New/delete dynamically allocates and releases memory

When you use new to allocate a memory block, if successful, new will return a pointer to an allocated memory, otherwise an exception will be raised.
Use new to allocate memory for an int type number:

int *pNum = new int;

Use new to allocate memory for multiple elements:

int *pNums = new int[10];

Note: When new requests to allocate memory, there is no guarantee that the request will always be satisfied, because it depends on the state of the system and the availability of memory resources.

The memory allocated using new will eventually need to be released using the corresponding delete:

  1. For the case of one element:
int *pNum = new int;  //分配内存空间
-----程序块-----
delete pNum;  //释放内存空间
  1. The case of multiple elements
int *pNums = new int[10];  //分配内存空间
-----程序块-----
delete[] pNUms;  //释放内存空间

Note: After the allocated memory is no longer used, it must be released by delete, otherwise a memory leak may occur.

Here is a simple example: open up a memory space to store the age, and release the allocated memory space after outputting the memory address for storing the age.

#include<iostream>
using namespace std;
int main()
{
	int *pAge = new int;
	cout<<"请输入您的年龄:";
	cin>>*pAge;
	cout<<"存储年龄的内存地址是:"<<hex<<pAge<<endl;
	delete pAge;
	return 0;
}

operation result:
Insert picture description here

(2) Pointer with keyword const

In the previous [C++ Development Plan] explained in simple language-variable scope (Day3) , when a variable is declared as const, the value of the variable is fixed to the initial value during the entire life cycle. The value of this variable cannot be modified.
Pointers are also variables, so const can also be used for pointers. There are three types of const pointers:

  1. The data pointed to by the pointer is constant and cannot be modified. But the address contained in the pointer can be modified, that is, the pointer can point to other places.
int Age = 18;
const int *pAge = &Age;  //不能更改pAge指向的数据Age的值
 2. 想将Age改为20,错误的做法
*pAge = 20;  //错误
 3. 正确的做法
int CopyAge = 20;
pAge = &CopyAge; //可改变指针指向的地址
  1. The address contained in the pointer is constant and cannot be modified. Only the data pointed to by the pointer can be modified.
int Age = 18;
int* const pAge = &Age;
*pAge = 20; //做法正确,可以改变值
  1. The address contained in the pointer and the value it points to are constants, so neither can be modified.
int Age = 18;
const int* const pAge = &Age;

(3) Pointer VS array

When we declare an array, such as the following:

int Array[10];

The compiler will allocate fixed memory for storing 10 integers. It also provides you with a pointer to the first element in the array. In other words, Array is a pointer to the first element Array[0]. The following program demonstrates this relationship:

#include<iostream>
using namespace std;
int main()
{
	int Array[10]={0,1,2,3,4,5,6,7,8,9};
	int *pNum = Array;
	cout<<"*pNum = "<<*pNum<<endl;
	cout<<"Array[0] = "<<Array[0]<<endl; 
	return 0;
}

Operation result:
Insert picture description here
It can be seen that the array name is a pointer and points to the first element.

3. Common mistakes when using pointers

(1) Memory leak

If the memory dynamically allocated by new is no longer needed, and the developer does not use delete to release the memory in time, the memory will be reserved and allocated to your application. This will reduce the amount of system memory available for other applications, and even slow down the execution speed of the application, which is what it is said 内存泄漏.
For example, the following:

int* pNums = new int[10];
-----程序块-----
//忘记进行delete[]

Forgetting to delete the memory that has been requested for allocation can easily cause memory leaks. We must pay attention to this when we use new requests to allocate dynamic memory.

(2) Invalid pointer

When the operator * is used to dereference a pointer to access the pointed-to value. Make sure that the pointer points to a valid memory unit, otherwise the program may crash.
There are many reasons for invalid pointers, but they all come down to poor memory management. Here are only two common situations that cause pointers to be invalid:

  1. In the process of declaring the pointer, it was not initialized to NULL, and no valid address was assigned to the pointer later.
  2. When using new to apply for dynamic memory for pointers, when the memory demand is particularly large, the allocation may not succeed, resulting in invalid pointers. For example, the following:
int* pNums = new int[10000000000]; //申请的内存量太大,可能导致分配不成功

Guess you like

Origin blog.csdn.net/qq_14874791/article/details/107778460