Pointer is an important concept in C and C++ languages. It is a variable that stores the memory address of another variable. The value of the variable can be accessed indirectly through a pointer. Pointers are widely used in memory management, data structures, system programming and other fields. When using pointers, you need to pay attention to the correctness and safety of the pointers, and avoid incorrect uses such as null pointers and wild pointers to avoid unpredictable behavior of the program.
Article directory
1. Definition and use of pointers
Pointer is an important concept in C language. It is a variable that stores the address of another variable. Through pointers, we can access and modify the value of variables indirectly.
Pointers can be defined and used in the following ways:
- Declare a pointer variable:
int* ptr;
Declare aint
pointer to typeptr
. - Initialize pointer: Initialize
int* ptr = #
the pointerptr
tonum
the address of the variable. - Dereference pointer:
int value = *ptr;
Dereference the pointerptr
and obtain the value pointed by the pointer.
Here is a simple example of a pointer:
#include <stdio.h>
int main() {
int a = 10; // 定义一个整数变量a,并初始化为10
int *p; // 定义一个指针变量p
p = &a; // 将a的地址赋给p
printf("a的值:%d\n", a); // 输出a的值
printf("a的地址:%p\n", &a); // 输出a的地址
printf("p指向的值:%d\n", *p); // 输出p指向的值,也就是a的值
printf("p的地址:%p\n", p); // 输出p的地址,也就是a的地址
*p = 20; // 通过指针修改a的值
printf("a的新值:%d\n", a); // 输出a的新值,也就是20
return 0;
}
explain:
int a = 10;
An integer variable is defineda
and initialized to10
.int *p;
A pointer variable is definedp
, which stores the address of an integer variable.p = &a;
This line of codea
assigns the address of top
. Now,p
what is stored isa
the address of .printf("a的值:%d\n", a);
This line of code outputsa
the value of , and the result is10
.printf("a的地址:%p\n", &a);
This line of code outputsa
the address of , which results in0x7fff5fbffb68
a memory address similar to this.printf("p指向的值:%d\n", *p);
This line of code outputsp
the value pointed to by , which isa
the value of . Becausep
storesa
the address of , it*p
means accessing the value at this address, and the result is10
.printf("p的地址:%p\n", p);
This line of code outputsp
the address of , which isa
the address of . This is becausep
storesa
the address of , so the output address is alsoa
the address of .*p = 20;
This line of code modifiesa
the value of through the pointer. Becausep
storesa
the address of , it*p
means accessing the value at this address. Now setting this value20
to actually modifiesa
the value of .printf("a的新值:%d\n", a);
This line of code outputsa
the new value of , ie20
. It can be seen that the value of is modified through the pointera
.
Second, the memory occupied by the pointer
Different systems and compilers may allocate different byte sizes to pointers. Generally speaking, in 32-bit systems, pointers occupy 4 bytes (32-bit = 4 bytes), while in 64-bit systems, pointers occupy 8 bytes . This is because in a 32-bit system, the address space is 2 32 , so each address must be represented by 32 bits (4 bytes). Likewise, in a 64-bit system, the address space is 2^64, so each address must be represented with 64 bits (8 bytes).
You can sizeof
get the byte size of a pointer using C operators.
Here's a simple example:
#include <stdio.h>
int main() {
int *p;
printf("指针p的字节大小:%zu\n", sizeof(p));
return 0;
}
This code will output p
the byte size of the pointer variable. On a 32-bit system, the result is 4; on a 64-bit system, the result is 8.
3. Null pointer
A null pointer is a special type of pointer that does not point to any object or function. A null pointer is usually used to represent a situation where there is no valid pointer.
In the C and C++ languages, the representation of a null pointer is NULL
(also available in C++ nullptr
). When a pointer is initialized NULL
to , it is a null pointer.
Using a null pointer may result in undefined behavior because the memory location pointed to by the pointer cannot be determined. To avoid this, it's better to check if a pointer is null before using it. For example:
int *ptr = nullptr;
if (ptr != nullptr) {
// 指针不为空,可以使用它
int value = *ptr;
} else {
// 指针为空,不能使用它
// 可以进行适当的错误处理或初始化操作
}
In the above code, we first check if the pointer is null before using it. This avoids undefined behavior.
4. Wild pointer
A wild pointer refers to an uninitialized pointer or an unreleased pointer in C and C++. Wild pointers are dangerous and can cause your program to crash or behave unexpectedly.
In order to avoid the problem of wild pointers, programmers should initialize the pointer when defining it, or release the memory in time after using the pointer. For example:
int *ptr = malloc(sizeof(int)); // 正确的方式,先分配内存,再定义指针
if (ptr == NULL) {
// 处理错误
}
// ... 使用 ptr ...
free(ptr); // 释放内存
ptr = NULL; // 将指针设置为 NULL,避免野指针
In the above code, we first malloc
allocate memory using a function and then define a pointer to that memory. After using the pointer, we use free
the function to free the memory and set the pointer to NULL
. This avoids the problem of wild pointers.
5. const modified pointer
In C language, const
keywords can be used to modify pointers to limit the usage rights of pointers.
When const
modifying pointers, const
there are two different syntaxes available, depending on the position:
const
On the left side of the pointer symbol, it means that the pointer points to a constant, that is, the value at the address cannot be modified through the pointer. For example:
const int *p;
Here, const
the variable of type int is modified, and the pointer p points to this variable. This means that you cannot modify the value at this address through the pointer p, that is:
*p = 10; // 编译错误,不能通过指针修改该地址上的值
const
On the right side of the pointer symbol, it means that the pointer itself is a constant pointer, that is, once the pointer points to a certain address, it cannot point to other addresses. For example:
int *const p;
Here, const
what is modified is the pointer p itself, not p
the variable pointed to. This means that p
once the pointer points to a certain address, it can no longer point to other addresses, that is:
p = &a; // 可以编译通过,p指向变量a的地址
p = &b; // 编译错误,p不能指向其他地址
const
You can also modify the pointer itself and the data pointed to by the pointer at the same time, indicating that the data pointed to by the pointer cannot be modified by the pointer, and the pointer itself cannot be reassigned. For example:
const int *const p;
Here, the type data const
pointed to by the pointer p is modified int
, indicating that p
the data cannot be modified through the pointer; at the same time, const
the pointer itself is also modified p
, indicating that the pointer p
cannot be reassigned. Therefore, p
once the pointer points to a certain address, it can no longer point to other addresses, and p
the value at that address cannot be modified through the pointer.
6. Pointers and arrays
There is a close connection between pointers and arrays because the name of an array can be used as a pointer . The following will introduce the relevant knowledge of pointers and arrays respectively, as well as the connection between them.
- pointer
A pointer is a variable whose value is the address of another variable. Through a pointer, you can access another variable indirectly. Pointers are divided into pointers to data types and pointers to functions. A pointer to a data type is used to store the address of the data type, and a pointer to a function is used to call the function.
- array
An array is an ordered data structure that can store multiple elements of the same type. The name of an array can be thought of as a pointer to the first element of the array. Therefore, array elements can be accessed through the array name.
- The relationship between pointers and arrays
There is a close relationship between pointers and arrays. First, the name of an array can be thought of as a pointer to the first element of the array. Secondly, array elements can be accessed through pointers. For example, you can use pointer addition to iterate over an array.
Here is a sample code that demonstrates the connection between pointers and arrays:
#include <stdio.h>
int main() {
int arr[] = {
1, 2, 3, 4, 5};
int *p = arr; // 数组名称可以看作是一个指向数组第一个元素的指针
// 使用指针遍历数组
for (int i = 0; i < 5; i++) {
printf("%d ", *(p + i));
}
return 0;
}
In the above code, an array of integer type named arr is defined and initialized to {1, 2, 3, 4, 5}
. Then, a pointer to an integer type is defined p
and initialized to arr
. Here, arr
it can be seen as a pointer to the first element of the array. Next, use the pointer p
to iterate through the array and output the value of each element.
It should be noted that when using pointers to access array elements, pointer addition operations need to be used to calculate the address of the element. For example, *(p + i)
it means that the address pointed to by the pointer p plus i
the size of the element is to access the th i
element of the array.
7. Pointers and functions
There is also a certain connection between pointers and functions. A pointer allows you to call a function by passing its address to another function. In addition, pointers can also be used as parameters of functions to achieve more flexible and efficient operations.
Here is a sample code that demonstrates the connection between pointers and functions:
#include <stdio.h>
void func(int *p) {
printf("Value: %d\n", *p);
}
int main() {
int a = 10;
int *p = &a; // 指针p指向变量a的地址
// 调用函数,传递指针p作为参数
func(p);
return 0;
}
In the above code, a function called func is defined, which accepts a pointer to an integer type as a parameter. In the main function, an integer type variable a is defined and initialized to 10. Then, a pointer p to an integer type is defined and initialized to the address of a. Next, the func function is called and the pointer p is passed to the function as a parameter. In the func function, access the value of variable a through pointer p and output the result.