It's almost the new year. Don't worry about playing. Learn to relax and study all year

catalogue

Pointer

What is a pointer and what is the relationship between a pointer and memory

Pointer variable

Basic operation of pointer

&The address represents the address of the variable, and * represents a dereference of the variable found according to the address

Size of pointer variable

Type of pointer variable

Conclusion 1: the pointer type determines the size of the space allowed to be accessed by the pointer

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

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

Field pointer

What is a wild pointer

Three causes of wild pointer

Avoid wild pointer correctly

1. Initialize before use

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

Keywords: C Back-end

Added by helpmeplease1234 on Wed, 19 Jan 2022 20:48:03 +0200