catalogue
What is a pointer and what is the relationship between a pointer and memory
2. Be careful that the pointer is out of range
3. After the space pointed to by the pointer is released, the pointer is assigned as a null pointer
4. Determine the validity of the pointer before use
Pointer
It is often said that pointer is the soul of C language, which is very difficult. Indeed, when you don't understand pointer, you will find it very difficult, but we try to understand pointer through the essence of pointer
What is a pointer and what is the relationship between a pointer and memory
What is the pointer? Next, I'll explain it with Baidu, and then explain it in detail
In computer science, a pointer is an object in a compiled language. Using an address, its value directly points to a value stored somewhere in the computer memory. Since the required variable unit can be found through the address, it can be said that the address points to the variable unit. Therefore, visualizing the address as a pointer means that the memory unit with it as the address can be found through it
C language is a computer programming language directly linked to memory. We define variables and call functions to apply for a space in memory for operation. As mentioned earlier, variables are a box and constants are the contents of the box. Now we compare the box to a house and the people living in it are constants. Then you live in a community, Your house must have a corresponding house number, which is the address in the memory. We divide the memory image into memory units, one byte corresponds to one memory unit, and apply for different numbers of memory units in the memory according to the needs
Pointer variable
The pointer we often mention is actually a pointer variable, which is a box that stores a special constant such as address. The pointer and these three symbols are always linked * & []. We must keep this in mind. Next, let's talk about pointer variables slowly
Basic operation of pointer
Taking the pointer of int type as an example, we will briefly introduce the simple use of pointer
#include<stdio.h> int main() { int a = 5; int* p = &a; printf("a=%d\n", a); *p = 10; printf("a=%d\n", a); }
&The address represents the address of the variable, and * represents a dereference of the variable found according to the address
So the result is
Size of pointer variable
The size of the pointer variable depends on the size of the compiler environment. In the 32-bit environment, the size of the pointer is four bytes, the address number is an eight bit hexadecimal sequence, the size of the 64 bit environment is eight bytes, and the address number is a hexadecimal sequence
Type of pointer variable
Pointer variables are different from general variables. Different pointer types do not determine the size of pointer variables
Conclusion 1: the pointer type determines the size of the space allowed to be accessed by the pointer
#include<stdio.h> int main() { int arr[5] = { 1,2,3,4,5 }; char* p = (char*)arr; for (int i = 0; i < 5; i++) { *(p + i) = 0; } for (int i = 0; i < 5; i++) { printf("%d ", arr[i]); } }
So what is the result of this code?
He changed only the first and second elements, not the five elements.
We all know that a char is a byte and an int is 4 bytes. According to the above conclusion, it can be explained that the pointer variable type determines the number of bytes accessed by the pointer, but why 2 has changed is related to the data storage structure
Conclusion 2: the pointer plus or minus integer represents how many steps to move, and the pointer type determines the size of one step to move
The above code carries out p+i, where i is an integer, that is, the pointer p moves i steps, + represents moving to the high address and - represents moving to the low address. Next, we use a piece of code to understand
#include<stdio.h> int main() { int arr[10] = { 1,2,3,4,5,6,7,8,9,10 }; int*p = arr + 5; scanf("%d%d", p - 1, p + 1); for (int i = 0; i < 10; i++) { printf("%d ", arr[i]); } }
So what is the result of the code when we enter two zeros?
According to the conclusion and the process of code execution, the result of the code should be that 5 and 7 are replaced with 0
There is no error in analyzing the result according to the conclusion, so the integer operation of the pointer represents the movement of the pointer
Conclusion 3: the result of pointer subtraction is the number of elements in the addresses at both ends. The comparison of pointers is that the high address is greater than the low address
There are also operations between pointers. According to the previous conclusion, the pointer plus integer represents the movement to the high address, and the pointer minus integer represents the movement to the low address. Let's prove it with this code
#include<stdio.h> int main() { int arr[10] = { 1,2,3,4,5,6,7,8,9,10 }; int* p = arr + 5; printf("arr+5=%p\n", arr+5); printf("arr+8=%p\n", arr+8); printf("%d %d\n", &arr[5] - &arr[8], &arr[8] - &arr[5]); printf("%p\n", p); printf("%p\n", p + 1); printf("%p\n", p - 1); return 0; }
Let's first think about the running results of this string of code, and then compare the answers
It is not difficult for us to find the correctness of the conclusion. Of course, another point is that the hexadecimal sequence of high address is large and the hexadecimal sequence of low address is small
Field pointer
When using pointers, you must pay attention. If you are not careful, you may encounter pointer problems
What is a wild pointer
A wild pointer is a pointer pointing to an unknown position. This unknown position may be random, incorrect, or unrestricted.
Three causes of wild pointer
1. The pointer is not initialized
Take a simple code as an example
#include<stdio.h> int main() { int* p; *p = 10; printf("%d", *p); return 0; }
The pointer p here is uninitialized and belongs to a wild pointer. An error will occur when running the code
2. Pointer cross-border access
We all know that the subscript of the array starts from 0. For an arr array with a length of 10, the arr[10] operation belongs to cross-border operation, which belongs to cross-border access
3. The space pointed to by the pointer is released
We all know that a function call will apply for a space in the stack area. After the function call, the space will be destroyed. If the pointer we use points to the temporary variable created in the function, the space will be released after the function call. At this time, the pointer belongs to a wild pointer. There are three main situations
Call the function to end the space release, dynamic memory release and close the file
We will not contact the latter two cases at present. Let's take the first case as an example
#include<stdio.h> int* test() { int a = 5; return &a; } int main() { int* p = test(); *p = 10; printf("%d\n", *p); return 0; }
The compiler in gcc environment will report an error because the space requested by a has been released
Avoid wild pointer correctly
Wild pointers sometimes kill people invisibly, and sometimes even crash programs. Since wild pointers are so terrible, we must find ways to avoid wild pointers
1. Initialize before use
When defining a pointer, we must initialize it If you want the pointer to point to an existing variable, you can directly point to that variable. If you don't know who to point to, you can assign a null pointer such as int a=10; int*pa=&a; int*pb;//We don't know who to point to, but pb is useful. Let's assign it to null first int*pb=NULL;
NULL means NULL pointer
2. Be careful that the pointer is out of range
Pointer out of bounds is a headache, so we must judge whether the pointer is out of bounds when using pointer sequential access or random access
#include<stdio.h> int main() { int arr[10] = { 1,2,3,4,5,6,7,8,9,10 }; int *p = arr; int *p1 = arr + 5; int *p2 = arr + 8; int *p3 = arr + 15; for (int i = 0; i < 10; i++) { if (p + i < arr + 10)//arr+10 is a boundary of the array printf("%d ", *(p + i)); if (p1 + i < arr + 10) printf("%d ", *(p1 + i)); if (p2 + i < arr + 10) printf("%d ", *(p2 + i)); if (p3+ i < arr + 10) printf("%d\n", *(p3 + i)); } return 0; }
We use arr+10 to judge the boundary. Of course, some partners say that > arr-1 can also judge the boundary. Here is a rule of pointer comparison
A pointer to an array element is allowed to be compared with a pointer to a memory location after the last element of the array, but it is not allowed to be compared with a pointer to a memory location before the first element
Let's look at the result of this code
The result shows that there is no problem, indicating that this does not cross the boundary, so we can check that the pointer crosses the boundary in this way
3. After the space pointed to by the pointer is released, the pointer is assigned as a null pointer
Simply put, after the position pointed to by the pointer cannot be used, we will assign the pointer with NULL. This will be described in detail in dynamic memory and file pointer
4. Determine the validity of the pointer before use
#include<stdio.h> int main() { int arr[10] = { 1,2,3,4,5,6,7,8,9,10 }; int *p = arr; int *p1 = arr + 5; int *p2 = arr + 8; int *p3 = arr + 15; for (int i = 0; i < 10; i++) { if (p != NULL && p + i < arr + 10)//arr+10 is a boundary of the array printf("%d ", *(p + i)); if (p1 != NULL && p1 + i < arr + 10) printf("%d ", *(p1 + i)); if (p2 != NULL && p2 + i < arr + 10) printf("%d ", *(p2 + i)); if (p3 != NULL && p3 + i < arr + 10) printf("%d\n", *(p3 + i)); } return 0; }
We modified the previous code, P= Null is a very effective judgment
Well, that's all for today's sharing. The next section will deeply analyze the pointer address and array to help you better master the pointer