当前位置:网站首页>Deep analysis of C language pointer (Part I)

Deep analysis of C language pointer (Part I)

2022-04-23 20:47:00 Computer white

Catalog

Preface

  One 、 What is the pointer ?

1.1 Memory 、 Pointer to the variable 、 Pointer size

1.1.1 Memory

1.1.2 Pointer to the variable  

1.1.3 Pointer size

Two 、 Pointer type and pointer class

2.1 Pointer types

2.2 The meaning of pointer type

2.  Dereference of pointer  

3、 ... and 、 Pointer arithmetic  

3.1 The pointer +- Integers

3.2  The pointer +- The pointer

3.3  The relational operation of pointers

Four 、 Pointers and arrays

  5、 ... and 、 The secondary pointer

6、 ... and 、 Pointer array  

7、 ... and 、 Wild pointer


Preface

  One 、 What is the pointer ?

In the computer , Memory is also divided into many small memory blocks , Each block has its own memory number , The pointer is the number of the smallest unit in memory , That's the address , We can imagine that the memory number is The pointer ; What we usually say in spoken English is the pointer , Usually it means Pointer to the variable , Variables used to store memory addresses .

1.1 Memory 、 Pointer to the variable 、 Pointer size

1.1.1 Memory

Let's start with a piece of code :

#include<stdio.h>
int main()
{
	int a = 10;
	int b = 20;
}

This code is very simple , Is the declaration of two variables , Assigned values respectively 10、20.  We think of memory as a school , that "int a = 10;" int b = 20;" The meaning expressed is as follows :

1. The dormitory number of the school is dor_x,dor_y.                                                                                         

2.10,20 Two students checked into the school dormitory .                                                                                     

3.dor_x,dor_y It's called variables a,b The address of .                                                                                 

4.10,20 The two students passed the dormitory number ( Variable a,b Memory address of dor_x,dor_y) Found the bedroom (a,b).

1.1.2 Pointer to the variable  

Let's start with a piece of code : 

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

Here we can conclude that :

It is through &( Fetch address ), Take out a The address of the variable , Store this address in another variable p in , This variable p It's a pointer variable .

int It's plastic surgery , Some data in memory is very large , In order to avoid stack ( Memory ) An error is reported when overflow occurs , This will only change the variable a The address of the first byte is stored in p variable ,p It's a pointer variable ( The variable used to hold the address , The values stored in the pointer are treated as addresses )

1.1.3 Pointer size

The smallest memory unit space is 1 Bytes . And for pointers , How many bytes a pointer occupies is determined by the number of bits in the computer operating system . Here we use 32 Example of bit operating system :32 The computer of bit , with 32 Follow your address line , When addressing, it will live forever 0( Low voltage ) and 1( high voltage ), that 32 How many addresses will be generated with the address line , Let's see :

00000000 00000000 00000000 00000001
00000000 00000000 00000000 00000002
00000000 00000000 00000000 00000003
00000000 00000000 00000000 00000004
         ...........
01111111 11111111 11111111 11111111
11111111 11111111 11111111 11111111

From the perspective of mathematical probability , There will be 2^32(2 Of 32 Power ) A number of probabilities , And the probability number here is our address number ;32 individual 0 and 1 The binary sequence of is combined into an address , Converted to bytes is 4 Bytes , Then the address has to be 4 Bytes to store , And the pointer variable is the address , therefore , Every pointer variable is 4 Bytes ( stay 32 Position is 4 Bytes ,64 Next is 8 Bytes )               

The pointer is used to store the address , An address is a unique identifier of an address space                                                     The size of the pointer is 32 Bit platform is 4 Bytes , stay 64 Bit platform is 8 Bytes

Two 、 Pointer type and pointer class

2.1 Pointer types

Let's start with a piece of code :

#include <stdio.h>
int main()
{
	int num = 10;
    int* p = &num;    //int*  A pointer to a type is to hold  int  The address of a type variable .
    
    // The following pointer variables are incompatible , because int It is different from other types of storage ,
    // This depends on the type of variable you define , Here can speak .

	char* p = &num;   //char*  A pointer to a type is to hold  char  The address of a type variable .
	short* p = &num;  //short*  A pointer to a type is to hold  short  The address of a type variable .
	long* p = &num;   // And so on 
	float* p = &num;
	double* p = &num;
	return 0;
}

take &num( take num The address of ) Store in p in , Here we know p It's a pointer variable , The pointer type is shown in the code above ; But what? , Incompatibilities may occur between different types during compilation , So how to deal with such a situation ?

2.2 The meaning of pointer type

Let's start with a piece of code :

#include <stdio.h>
#include <stdio.h>
int main()
{
	int n = 10;           // Variable n The type of int plastic 
	char* pc = (char*)&n; // take n The address of , Send a char Pointer variable of type pc,(char*)&n It's right n Do type conversion 
	int* pi = &n;

	printf("%p\n", &n);   //&n and pc The address memory is the same , Because the memory address of the first byte is stored 
	printf("%p\n", pc);

	printf("%p\n", pc + 1);//pc Represents the address of the first element ,pc+1 It's equivalent to skipping a char The address of 
	printf("%p\n", pi);    //pi Save n The address of , It's like printing n The address of 
	printf("%p\n", pi + 1);//pi representative n The address of the first element ,pi+1 It's equivalent to skipping a int The address of 
	return 0;
}

The operation results are as follows : 

           

  summary :

The type of pointer determines the distance that pointer variables are addressed in memory .

2.  Dereference of pointer  

Let's start with a piece of code :

#include<stdio.h>
// First code 
int main()
{

	int n = 0x11aabbcc; //0x11aabbcc in ,cc It's the low address bit 
	char* pc = (char*)&n;
	*pc = 0;   // there "*" Dereference operator ,n The address in is 0x11aabbcc,&n take n My address was sent to pc,
			   //*pc = 0; The meaning of this sentence is through pc Stored in n The address of n, take 0 Fu n;
	printf("%p\n", n); // Here the print 11aabb00 Because of the limitation of pointer type , Only one byte has been changed 
	return 0;
}


#include<stdio.h>
 Second code 
int main()
{
	int n = 0x11aabbcc;
	printf("%p\n", n);
	char* pc = (char*)&n;
	int* pi = &n;
	*pc = 0;
	printf("%p\n", n);
	*pi = 0;
	printf("%p\n", n);
	return 0;
}

The running result is : 

summary : The pointer dereference operator will have access to the address size , This is determined by the type of pointer ; for example char* Only one byte can be accessed by dereferencing the pointer of , and int* Four bytes can be accessed by dereferencing the pointer of .

3、 ... and 、 Pointer arithmetic  

3.1 The pointer +- Integers

The addition and subtraction of the pointer indicates how many memory units are moved forward or backward in memory , The number of memory units is determined by the size of the pointer type .

3.2  The pointer +- The pointer

Let's start with a piece of code :

#include <stdio.h>
int main()
{
	int arr[10] = { 0 };
	printf("%d",&arr[6]-&arr[3]);// Print 3
	return 0;
}

The pointer - The value obtained by the pointer is the number of elements between the pointer and the pointer , But it must be the same memory space .

3.3  The relational operation of pointers

Suppose there is an array of pointers arr[10]:

#include <stdio.h>
int main()
{
	int arr[10] = { 0 };
	if(&arr[6] > &arr[3])  
		printf("&arr[6] The memory address of is greater than &arr[3]");// Conditions established , prints 
	else
		printf("&arr[6] The memory address of is less than &arr[3]");
	return 0;
}

The relational operation of pointers is also conditional , There may be cross-border situations , There is such a rule : Allows a pointer to an array element to be compared with a pointer to the memory location after the last element of the array , However, it is not allowed to compare with a pointer to the memory location before the first element .

Four 、 Pointers and arrays

  Let's start with a piece of code :

#include <stdio.h>
int main()
{
    int arr[10] = { 1,2,3,4,5,6,7,8,9,0 };
   
    int sz = sizeof(arr) / sizeof(arr[0]); //sizeof( Array name ): An array represents the entire array , It's the whole number  
                                           // The size of the group , Unit is byte 
    printf("%d %p\n", sz, &arr);         //& Array name : The array name represents the entire array , It takes out the address of the entire array 
    
    printf("%p\n", arr);
    printf("%p\n", &arr[0]);
    return 0;
}

  Running results :

  From the above, we can see that the name of the visible array is the same as the address of the first element of the array , But there are two exceptions :

sizeof( Array name ): An array represents the entire array , It calculates the size of the entire array , Unit is byte

& Array name : The array name represents the entire array , It takes out the address of the entire array

We can also access arrays through pointers : 

#include<stdio.h>
void Print(int* arr,int sz)
{
	int* p = arr;
	for (int i=0;i<sz;i++)
	{
		printf("%d ",*(p+i)); // therefore  p+i  It's actually an array  arr  Subscript to be i The address of .
	}
}
int main()
{
	int arr[] = { 1,2,3,4,5 };
	int sz = sizeof(arr) / sizeof(arr[0]);
	Print(arr,sz);// Print array 
	return 0;
}

 

  5、 ... and 、 The secondary pointer

The secondary pointer : Pointer variables are also variables , If it's a variable, it has an address , Where is the address of the pointer variable stored ? Here we derive the second level pointer .

Let's start with a piece of code :

#include <stdio.h>
int main()
{
    int a = 10;
    int* b = &a;
    int** c = &b;
    **c = 30;  // Through the dereference operator , find a The address of , Then on a Modify the stored data 
    printf("%d",a);// Print 30
    return 0;
}

As shown in the figure : 

a The address of is in b in , b The address of is in c in .b Is the first level pointer , and c It's a secondary pointer .                        c Available through storage b The memory address of points to b, and b You can also store a The memory address of points to a;

  For two-level pointer operation, there are :

*b Through to b Dereference the address in , Just find a More data stored in (20)

int a = 20; 
int*b = &a;// Equivalent to  b = &a;

 **c adopt *c  find b , Then on b  Dereference *b(*c) , And find  a, Then on a Change the value of .

int** c = &b;
**c = 30;

6、 ... and 、 Pointer array  

Pointer arrays are arrays . Is an array of pointers . Arrays we already know about shaping arrays , A character array .

char arr[5];
int arr[5];
int* arr[5];// arr Is an array , There are five elements , Each element is an integer pointer int*.

What is shown above is

7、 ... and 、 Wild pointer  

Wild pointer : We have understood that the pointer will point to a memory unit , And the wild pointer means , The address pointed to by this pointer is unknown to us , That is, random , incorrect 、 There is no definite limit to . In the following cases, the wild pointer will appear :

Pointer not initialized                         Pointer cross boundary access                       The space pointed to is not released

//1. When defining a pointer variable, it is not initialized , The random value of a pointer variable means that the memory it points to is random 
int *p;


//2、 Base note: dynamic open memory space after use. free The function frees up this memory space ,
int func()
{
    int *p = malloc(sizeof(int));
    free(p);// No will p Set as NULL The operation of , Although the open space is released, the pointer still exists .
}

//3、 The operation on the pointer has exceeded the scope of the pointer variable 
int arr[1] = {0};// only one 
int *p = arr;
*(P++);          // When the pointer points to an array arr The scope of time ,p It's a wild pointer 

End of this chapter , The next chapter continues !

版权声明
本文为[Computer white]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/04/202204210546128202.html