Pointer basic summary and detailed explanation

1. What is a pointer

Speaking of pointers, students who have had the basics may know that it is a memory address, but in order to better understand pointers, we must start with the computer's memory. The prerequisite for a good understanding of pointers is to understand what memory is.

1. Memory

Memory is a very core hardware device of a computer, and it is also a very important resource when writing programs.
We can understand it like this:The memory is a very long hotel corridor. This corridor is composed of many rooms. The size of a room is 8 bits (1 byte). We use the hexadecimal method to count each room with a door number. Number, this house number is the address of our memory, which is the pointer, the pointer is our house number here.
Insert picture description hereWe often use G to measure memory size, here

A G has 1 billion bytes

2. External memory and internal memory

Both memory and external memory are used to store data, but the CPU can only access the memory. Careful students may find that when buying a computer, there is generally such a choice:
Insert picture description here
16G here is the memory size (the memory bar is plus memory Size), 512G is the external memory size. (Mechanical hard drives and solid state drives are all external storage)

The difference between memory and external memory: different volatility, different performance, different storage duration, different access rights

3. Pointer

The pointer is a variable that stores the address (number) of the memory unit.
Let's explain in detail with the help of a small code:

#include <stdio.h>
int main()
{
    
    
 int a = 10;//一个变量开辟四个房间
 int *p = &a;//这里我们对变量a,取出它的地址,可以使用&操作符。
   //将a的地址存放在p变量中,p就是一个之指针变量。
 return 0;
}

4. Secondary pointer

So since the pointer is a variable, where does the address of the pointer exist?

In the second-level pointer, the variables of the second-level pointer are stored in the third-level pointer, which is an infinite loop...
Insert picture description here

This kind of multiple pointers is generally not used, so just understand it. If you encounter it, you can use typedef (change your alias) to simplify it.

5. Summary

A pointer is a variable, a variable used to store an address. (The value stored in the pointer is treated as an address)
Since the address is a variable, it also has the size in the memory, right?

In a 32-bit operating system, the size of a pointer variable is 4 bytes.
In a 64-bit operating system, the size of a pointer variable is 8 bytes.

Two, pointers and pointer types

1. Types and definitions of pointers

Pointers are also variables. Variables have different types, integer, floating point, etc. Is there any
type of pointer ? To be precise: yes.
We express the pointer type in the following way:

char  *pc = NULL;
int   *pi = NULL;
short *ps = NULL;
long  *pl = NULL;
float *pf = NULL;
double *pd = NULL;

Different pointer types represent the size of the memory space it points to.

Similar to int*, char*, and short*, the data types with * are our pointers.
In a 32-bit operating system, the size of a pointer variable is 4 bytes.
In a 64-bit operating system, the size of a pointer variable is 8 bytes.

So note that the size of the pointer types themselves is fixed.
Here we must distinguish between the memory space pointed to by the pointer and the memory space where he himself is located.
Insert picture description here

2. The meaning of pointer types

Since it is a fixed size, what are the other meanings of int*, char*, and short*?

2.1 Dereference size permissions

The type of the pointer determines how much authority (can manipulate several bytes) when dereferencing the pointer. For example, the dereference of char* pointer can only access one byte, while the dereference of int* pointer can access four bytes.

#include<stdio.h>
#include<stdlib.h>
int main()
{
    
    
 int n = 0x11223344;
 char *pc = (char *)&n;
 int *pi = &n;
 *pc = 0;   //重点在调试的过程中观察内存的变化。
 *pi = 0;   //重点在调试的过程中观察内存的变化。
 system("pause");
 return 0;
}

2.2 The scope of a pointer access

The type of pointer determines how far the pointer can go one step forward or backward. (For example: int type +1 address forward four bytes, char type +1 address forward 1 byte)

#include<stdio.h>
#include<stdlib.h>
int main()
{
    
    
	int n = 10;
	char* pc = (char*)&n;
	int* pi = &n;
	printf("%p\n", &n);
	printf("%p\n", pc);
	printf("%p\n", pc+1);
	printf("%p\n", pi);
	printf("%p\n", pi+1);
	system("pause");
	return 0;
}

Insert picture description hereThe third one adds 1 number (1 byte) and the
fifth adds 4 numbers (4 bytes)

Three, wild pointer

1. Concept

Concept: A wild pointer means that the location of the pointer is unknowable (random, incorrect, and not clearly restricted). If the pointer variable is not initialized when it is defined, its value is random, and the value of the pointer variable is another variable. Address means that the pointer points to a variable whose address is uncertain. At this time, to dereference is to visit an uncertain address, so the result is unknowable

The whole sentence is to visit an illegal address

2. Causes of wild pointer

Here we carefully discuss the common situations of pointer access illegal addresses:

2.1 The pointer is not initialized

#include <stdio.h>
int main()
{
    
    
 int *p;//局部变量指针未初始化,默认为随机值
    *p = 20;
 return 0;
}

There is no initialization and no address is specified, so random values ​​will appear.

2.2 Pointer access out of bounds

This problem is very common in arrays:

#include <stdio.h>
int main()
{
    
    
    int arr[10] = {
    
    0};
    int *p = arr;
    int i = 0;
    for(i=0; i<=11; i++)
   {
    
    
        //当指针指向的范围超出数组arr的范围时,p就是野指针
        *(p++) = i;
   }
    return 0}

Only legal addresses can be dereferenced, and wild pointer dereference is undefined behavior.

2.3 The space pointed to by the pointer is released

Local variables in functions are prone to this kind of problem.

3. Avoid wild pointers

1. Pointer initialization
2. Be careful that the pointer goes out of range
3. The pointer points to the space even if it is set to NULL
4. Check the validity of the pointer before use

Four, pointer arithmetic

1. Pointer addition and subtraction integer

It is to visit the next and previous element.

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

Insert picture description here

2. Pointer minus pointer

The pointer can be subtracted from the pointer, provided that it is on a contiguous memory address.
The result of pointer subtraction is a few "elements" between the two addresses.
This makes sense:

#include <stdio.h>
int main()
{
    
    
	int arr[4] = {
    
     1, 2, 3, 4 };
	int* p1 = &arr[0];
	int* p2 = &arr[2];
	printf("%d\n", p2- p1);
	system("pause");
	return 0;
}

Insert picture description here

3. Pointer relational operations

Pointers can also perform relational operations. The relational operations of pointers include <, >, <=, >=, ==, !=.

Note: pointer comparison operations (<, >, <=, >=) require two pointers to point to the same continuous effective memory space, so that it makes sense.

We can use a simple code to experience the relational operations of pointers:

#include <stdio.h>
int main()
{
    
      
	int num = 10;
	int* p = &num;
	if (p) {
    
    
		printf("不是空指针\n");
	} else {
    
    
		printf("是空指针!\n");
	}
	system("pause");
	return 0;
}

Insert picture description here


#include <stdio.h>
int main()
{
    
      
	int num = 10;
	int* p = &num;
	if (p != NULL) {
    
    
		printf("不是空指针\n");
	} else {
    
    
		printf("是空指针!\n");
	}
	system("pause");
	return 0;
}

Insert picture description here
Here we can see:
if (p != NULL) is equivalent to if (p)
Similar can be summed up:
if (p == NULL) is equivalent to if (! p)
The code here only shows that pointers can perform relational operations.

Five, pointers and arrays

Pointers and arrays are the most easily confused in the problem of pointers, but pointers and arrays are two completely different things. We only need to understand the similarities and differences.
The most important points are:

In C language, array names are often implicitly converted to pointers;
pointers can also be subscripted using [], which behaves like arrays.

1. Pointer array and array pointer

An array of pointers is a kind of array. Instead of ordinary int, char and other data, it stores pointers such as int*, char*, etc.
int * arr[5]={0};

int arr[5]={
    
    0};//(普通数组)
//可以理解成arr[5]里面的是int
int* arr[]={
    
    0};
//arr[5]里的是int*

Array pointer is a kind of pointer that points to an array.
Note: It is different from the address of the first element represented by the array name.

//我们可以通过打印地址求证
//指针+1是跳过一个元素
int arr[5]={
    
    0};
int(*p)[5]=&arr;
printf("%p\n",arr);
printf("%p\n",arr+1);//首元素指针
printf("%p\n",&arr+1);//int(*)[5]

We will find that the address of the first element is 4 and the array pointer is 20

2. What is the name of the array

We write this line of code:

#include <stdio.h>
int main()
{
    
    
 int arr[10] = {
    
    1,2,3,4,5,6,7,8,9,0};
    printf("%p\n", arr);
    printf("%p\n", &arr[0]);
    system("pause");
    return 0;
}

Insert picture description hereWe found that the array name is the same as the address of the first element of the array.
So the array name represents the address of the first element of the array.
So we can implement code like this:

int arr[3]={
    
    0,1,2};
int* p=arr;//p存放的是数组首元素的地址

3. Pointer implicit conversion

This implicit conversion will only happen whenC language, other languages ​​will not happen.
Next, we elaborate on the implicit conversion of C language to pointers:

1.1. Array name participates in operation

we knowArrays cannot be operated with ±, but pointers can be added and subtracted, If you see this happening, it proves that an implicit conversion has taken place at this time.

At this time, the array name points to the address of the first element, not the address of the array. The address of the array is pointed to by the array pointer (array pointer and pointer array are advanced items in the array, which I will summarize later)

#include <stdio.h>
int main()
{
    
      
	int arr[3] = {
    
     0,1,2 };
	printf("%d\n", sizeof(arr));
	printf("%d\n", sizeof(arr + 0));
	system("pause");
	return 0;
}

Insert picture description here12 represents the number of bytes in the arr array;
4 is the number of bytes pointing to the first element pointer, which is fixed 4 (mine is a 32-bit setting)

1.2. Function parameter transfer

#include <stdio.h>
void change(int arr){
    
    
	printf("%d\n", sizeof(arr));
}
int main()
{
    
      
	int arr[3] = {
    
     1,2,3 };
	printf("%d\n", sizeof(arr));
	change(arr);
	system("pause");
	return 0;
}

Insert picture description here
12 represents the number of bytes in the arr array;
4 is the number of bytes pointing to the first element pointer, which is fixed 4 (mine is a 32-bit setting)

4. [] operation of pointer

[] Is the operation of taking the index of the array, which can also happen in the pointer.
Note:The pointer index can be negative, and the array can only be in a fixed range

#include <stdio.h>
int main()
{
    
       
	int arr[4] = {
    
     1, 2, 3, 4 };
	int* p = arr + 1;
	 //这个操作是允许的,数组下标一定是 [0, size-1] 范围
	// 但是指针的下标不一定. 取决于指针初始情况下指向谁. 
	printf("%d\n", p[-1]);
	printf("%d\n", *(p - 1));
	system("pause");
	return 0;
}

Insert picture description here

Guess you like

Origin blog.csdn.net/zhaocx111222333/article/details/109703060