C ++ pointer application and precautions
Pointers are a headache for c/c ++ to learn. During programming, pointers are often the cause of implicit bugs. Next, let's talk about the application of pointers and some issues that need to be paid attention to. There may be issues that you have not noticed at ordinary times, hoping to help readers understand pointers.
1. Let's first recall the pointer concept for the convenience of the following introduction.
A pointer is a variable or constant that stores the address value. For example, int a = 1; & a indicates a pointer constant ("&" indicates an address operator, that is, a reference ). Int * B, B indicates the pointer variable (Note: B indicates the pointer variable rather than * B), and * indicates the pointer variable. Note that int * B [2] and int (* B) [2] are different. int * B indicates a pointer array, while int (* B) [2] indicates the int pointer containing two elements. Here, we need to pay attention to the computing priority problem, which helps us to understand the pointer problem.
It is enough to introduce the basic concepts here. As for the specific usage methods, such as assigning values, many books have introduced them, so I will not talk about them much.
II. Application and precautions
1. Understanding the key to pointers-understanding the pointer type and the type pointed to by the pointer
① Pointer type: you can remove the pointer name. The rest is the pointer.
For example, int * a; // the pointer type is int *
Int ** a; // the pointer type is int **
Int * (* a) [8]; // the pointer type is int * (*) [8]
② Type pointed to by the pointer: refers to the type that the compiler will regard as the memory. Here, we only need to remove the pointer name and the "*" number on the right of the name in the pointer declaration statement. The rest is the type pointed to by the pointer.
The reason why I put them first is to find out that they are the focus of learning c/c ++ pointers, and correct understanding of them can help you lay a good foundation for c/c ++ programming.
2. pointer application-passing parameters.
In fact, it can be equivalent to the implicit return value, which is more flexible than the return method, and more values can be returned. The following example naturally understands:
# Include "iostream. h"
Void example (int * a1, int & b1, int c1)
{
* A1 * = 3;
++ B1;
+ + C1;
}
Void main ()
{
Int *;
Int B, c;
* A = 6;
B = 7; c = 10;
Example (a, B, c );
Cout "* a =" * a <
Cout "B =" <
Cout "c =" <
}
Output: * a = 18
B = 8
C = 10
Note that No, * the values of a and B have changed, but c has not changed. This is because a1 points to * a (= 6) pointer, that is, it points to the same address as a, so when a1 points to the value changed, * The value of a is changed. The parameter in the function uses reference (int & b1). b1 is the alias of B. It can also be understood as a special pointer, so the value of B will change. The int c1 parameter in the function only plays a role in the function. It disappears when the function ends,
So it does not work in main.
3. A question about global variables and local variables
Let's stop talking nonsense. Let's first look at the program:
# Include "iostream. h"
Int a = 5;
Int * example1 (int B)
{
A + = B;
Return &;
}
Int * example2 (int B)
{
Int c = 5;
B + = c;
Return & B;
}
Void main ()
{
Int * a1 = example1 (10 );
Int * b1 = example2 (10 );
Cout "a1 =" * a1 <
Cout "b1 =" * b1 <
}
Output result:
A1 = 15
B1 = 4135
* How can b1 be 4135 instead of 15? Is it a program problem? Right?
Because a is a global variable and stored in the memory area of the global variable, it always exists, while local variables exist in the stack area of the function. When the function example2 () after the call is completed, B points to an uncertain region, resulting in Pointer suspension.
The following is the disassembly of example1 () and example2 () (Compiled using TC ++ 3.0 ):
Example1 ():
Push bp; inbound Stack
Mov bp, sp
Mov ax, [bp + 04]; passing Parameters
Add [00AA], ax; add
Mov ax, 00AA; returns the address of the result
Pop bp; resume stack and exit Stack
Ret; exit function
Example2 ():
Push bp; inbound Stack
Mov bp, sp
Sub sp, 02
Mov word ptr [bp-02], 0005
Mov ax, [bp-02]; PASS Parameters
Add [bp + 04], ax; add
Lea ax, [bp + 04]; the problem lies here
Mov sp, bp
Pop bp; resume stack and exit Stack
Ret; exit function
After comparison, can we see it? Ax should store the result address. In example2 (), the returned content is [bp + 04], so the pointer points to an uncertain place and the resulting pointer suspension. In example1 (), ax returns the correct result address.
4. Memory problems: Use pointers to pay attention to memory allocation and boundary.
When using pointers, a proper space should be provided for the variables to avoid invisible errors.
See the following code:
# Include "iostream. h"
Void main ()
{
Char * a1;
Char * a2;
Cin a1;
Cin a2;
Cout "" a1 = "<
Cout "" a2 = "<
}
Input: abc
123
Output:
A1 = 123
A2 =
Null pointer assignment
The Pointer Points to "null ". The solution is to allocate the appropriate memory to the two strings. Corrected code
As follows:
# Include "iostream. h"
Void main ()
{
Char * a1;
Char * a2;
A1 = new char [10];
A2 = new char [10];
Cin a1;
Cin a2;
Cout "a1 =" <// cout "" a2 = "<
Delete (a1); Do not forget to release memory space
Delete (a2 );
}
The correct result can be output.
After the appropriate memory is allocated, pay attention to the release of internal reference space. At the same time, be sure not to exceed the size of the allocated memory. Otherwise, overflow will occur, leading to unpredictable results.
5. Special pointer-Reference
Sometimes, the reference is more flexible than the pointer. When it is used to return data, it does not generate copies of any variables. This reduces the memory usage and improves the execution speed. References are more intuitive and easier to use than pointers. When referenced as a parameter, the parameter address is not changed, so it can be used as the left value.
The following is an example:
# Include "iostream. h"
Char ch [5] = "ABCD ";
Char & example (int B)
{
Return ch;
}
Void main ()
{
Cout "" ch = "<
Example (2) = "c ";
Cout "" ch = "<
}
Ch = ABCD
Ch = ABcD
In the actual programming process, you can flexibly reference or pointer to improve program readability and execution efficiency as much as possible.
Iii. Summary:
Pointers are the key and difficulty in learning c/c ++. The main reason is that pointers are abstract and difficult to understand. When using pointers, you must understand where the Pointer Points and how to make the pointer point to the correct place. A large number of pointers need to be applied to the underlying system. Therefore, you need to understand the basic concepts of pointers, such as pointer types and types pointed to by pointers. At ordinary times, you should pay attention to observe and understand the working process of the program. If necessary, you can disassemble the program to deepen your understanding of the pointer. This method is also suitable for learning other programming knowledge.
Iv. End:
Pointers are widely used. To become a good programmer, you must have a deep understanding of pointers. The purpose of this article is to give you a deeper understanding of pointers and improve the application capability of pointers. Most of the content is a problem I encountered in actual programming. I believe this will help you.