[C Language] Comprehensive analysis of pointers, sorting out pointer knowledge points

Table of contents

Foreword:

1. The concept of pointers

2. Types of pointers

3. Wild Pointer

3.1 Causes of wild pointers:

 3.2 How to avoid wild pointers?

4. Pointer operations

5. Pointers and arrays

6. Secondary pointer

7. Array of pointers

Summarize: 


Foreword:

For C language, pointers are a difficult point. If you use C language to write data structures, it is necessary to master the usage of pointers. If you do not learn pointers well, it will be very difficult to learn data structures. So I hope everyone must grasp the pointer! ! !

1. The concept of pointers

1. A pointer is a variable used to store an address , which uniquely represents a piece of memory space.

ps: (memory number = address = pointer)

2. The size of the pointer is fixed at 4/8 bytes (32-bit platform/64-bit platform)

2. Types of pointers

The pointer has a type, and the type of the pointer determines the step size of the pointer+-integer, and the permission when the pointer is dereferenced.

Let me explain the meaning of the red part above. For example, take a look at the following code and running results:

#include<stdio.h>
int main()
{
	int a = 4;
	int* p1 = &a;
	char* p2 = &a;
	printf("%p\n", p1);
	printf("%p\n", p2);
	printf("%p\n", p1+1);
	printf("%p\n", p2+1);
	return 0;
}

ba55661f49c94ab7a066716ea0918eaa.png

 At the beginning, the addresses of p1 and p2 are the same, but later, p1 and p2 are respectively +1, and the result is different later, the 1 added to p1 is 1 of int type, and the 1 added to p2+1 is of char type .

We mentioned above that the size of the pointer is fixed at 4/8 bytes . Assuming it is a 32-bit platform, then a pointer occupies 4 bytes. If I define an integer pointer and a character pointer at this time, then the integer pointer can access 4 bytes when dereferencing, while the character pointer can only access 1 byte.

3. Wild Pointer

The concept of the wild pointer is: the position of the pointer is unknown

3.1 Causes of wild pointers:

There are two reasons for the wild pointer : 1. The pointer is not initialized 2. Out-of-bounds access to the pointer

Let me explain to you:

pointer is not initialized

This should be easy to understand, that is, we did not let it point to any object when we created the pointer variable

For example: int* p; so that p is a local variable and p is a random value 

pointer out of bounds access

Take a look at the code below:

#include<stdio.h>
int main()
{
	int arr[5] = { 1,2,3,4,5 };
	int* p = arr;
	int i = 0;
	for (i = 0; i < 6; i++)
	{
		printf("%d ", *p);
		p++;
	}
	return 0;
}

Let me explain the principle of this code first, int* p = arr ; here arr is the name of the array, and the name of the array is the address of the first element

So now p is the address of the first element, dereferencing p is *p, and the value of *p is 1

p++; This line of code is to make the address of p ++; the size of the pointer is fixed at 4/8 bytes , and the int data is also 4/8 bytes in C language . The address of a byte , and the array is continuous in memory , p++ just moves one data backward.

But now the arr array has only 5 elements in total, but looping 6 times will inevitably cause the array to go out of bounds, so let's take a look at the running results

7f25a0ea626045aea04d77885f090aca.png

The first 5 numbers are the numbers in the arr array, and the sixth value is a random value. Because when the loop reaches the sixth time, p has no object pointed to, and p is a wild pointer at this time.

 3.2 How to avoid wild pointers?

1. Be good at using NULL and initialize pointers in time

If you have already thought of the object pointed to by the pointer variable when you define the pointer variable, then initialize it directly.

If you don't know the object pointed to by the pointer when you define it, and you don't know whether to use the pointer later, then assign NULL to the pointer variable   

NULL means empty . If int *p=NULL; then p is a null pointer at this time, which can be reassigned later without affecting subsequent use. If a pointer is null, don't use it until you have initialized it.

2. Avoid pointer out of bounds

3. Avoid returning the address of a local variable

4. Pointer operations

Take a look at the following code:

#include<stdio.h>
int main()
{
	//指针地址加减整数
	int arr[5] = { 1,2,3,4,5 };
	int* p1 = arr;
	int i = 0;
	for (i = 0; i < 5; i++)
	{
		printf("%d ", *p1);
		p1++;
	}
	printf("\n");
	//解引用后的指针加减整数
	int b = 10;
	int* p2 = &b;
	(*p2)++;
	printf("%d", *p2);
	return 0;
}

p1++ is to add and subtract integers to the address, which has been introduced above, so I won’t introduce too much now

And (*p2)++, I defined a b variable, then assigned it to 10, and then gave the address of b to p2, and *p2 got 10 by dereferencing, (*p)++ is equivalent to 10 ++ , the result is 11.

Take a look at the running results:

99cb2eef764e46979bb9eedd09d45640.png

 ps: Pointers can be compared in size

Pointers can also subtract pointers

for example:

#include<stdio.h>
int main()
{
	int arr[5] = { 1,2,3,4,5 };
	printf("%d", &arr[4] - &arr[0]);
	return 0;
}

There is no subtraction of pointer variables here, which is actually the same. After all, pointers are addresses.

When two pointers point to the same space, the absolute value of the pointer minus the pointer is the number of data between the two pointers.

Note that this is not  specified by the C language for the size of the number * data type

af9a52f60daa4d51ac506d832356e418.png

5. Pointers and arrays

1. Arrays can be accessed through pointers , you can refer to the code I wrote above.

2. Usually, the array name is the address of the first element 

But there are exceptions to everything:

        1. sizeof (array name) gets the size of the entire array 

        2.&+array name here is the address of the entire array.

3. When passing function parameters, if the formal parameter is an array, you can design the formal parameter as a pointer. Of course, if the formal parameter is an array, you can also pass a pointer as an actual parameter.

6. Secondary pointer

The secondary pointer is used to store the address of the primary pointer (pointer variable).

#include<stdio.h>
int main()
{
	int a = 5;
	int* pa = &a;
	int** ppa = &pa;
	return 0;
}

At this time, pa is a first-level pointer, ppa is a second-level pointer, and ppa takes out the address of pa and puts it in ppa

**ppa is *pa to find pa, dereferencing pa to find a

7. Array of pointers

Definition of pointer array: int* array name [size]  

Usage of array of pointers:

#include<stdio.h>
int main()
{
	int arr1[3] = { 1,2,3 };
	int arr2[3] = { 4,5,6, };
	int* arr3[2] = {arr1,arr2};
	int i = 0;
	int j = 0;
	for (i = 0; i < 2; i++)
	{
		for (j = 0; j < 3; j++)
		{
			printf("%d ", *(arr3[i] + j));
		}
		printf("\n");
	}
}

The pointer array can be simulated to implement a two-dimensional array, and arr[i] stores the addresses of arr1 and arr2. +j is to obtain the address of each bit of the array element, and then *dereference to get the value inside. The output can also be changed to   printf("%d ", arr3[i][j]); the effect is the same.

5f65ae621b1044ea9bb35d742de02f6c.png

Summarize: 

Pointers are really important! Pointers are really important! Pointers are really important! (Say important things three times) Must master

I hope this article can help you (the level is limited, if you have any questions, please correct me! Thank you!)

Guess you like

Origin blog.csdn.net/m0_63463510/article/details/125113551