C language data structure (3) - pointer type

Pointer is the main characteristic application of C language. In C language, pointer is a basic data type, which can be combined with arrays, functions, structures, etc. to be used in various occasions. When learning pointers, we have to do two things: always know where each pointer points to; always know what the pointer points to.

pointers and pointer variables

Before learning pointers, we should figure out the meaning of variables. Each variable has two physical meanings, one is its own content, and the other is the address of the variable. We can think of the computer's memory as a row of houses on a long street. Each house can accommodate data and is identified by a house number. At this time, the data in the house is the content of the variable itself, and the room number is the address of the variable. A more accurate description should be:
the content of the variable is the data stored by the variable in the allocated storage space.
The address of a variable is the first address of the storage space allocated by the variable.

Then we need to figure out direct and indirect access . The access operation to variables in the program is to operate on several byte storage units at a certain address. In general, only the variable name needs to be pointed out in the program, and there is no need to know the specific address of each variable in the memory. The connection between each variable and the specific address is completed by the C compiler system. When the program is executed, the access operation to the variable is actually the operation on the storage unit of a certain address. This way of directly accessing the variable value according to the address of the variable is called "direct access". For example, if the integer variable name a is quoted in the program, the system will automatically directly access the 4-byte content of the variable a according to the address value of a.
If we define a special variable, this variable is specially used to store the memory address, which is called a pointer variable, as shown in the figure, suppose we define such a variable pa, which also has its own address 2004; if we want to change the address of variable a (1001) is stored in the variable pa. At this time, to access the storage unit represented by the variable a, you can first find the memory address (2004) of pa, take out the address of a (1001) from it, and then access the address starting with 1001 storage unit. This method of indirectly obtaining the address of variable a through variable pa, and then accessing the value of a is called "indirect access".
insert image description here

After figuring out the above two concepts, we can learn pointers more easily. What is a pointer? ——A pointer is an "address", and the address of a variable is called a pointer. As a data type, pointers can also be divided into pointer constants and pointer variables, and their variables have the same meaning as other types of variables. They need to be defined before they can be calculated or operated. The value of a pointer variable should be the address of a variable.
If the pointer variable already has an address value, it can be said that the pointer variable points to a certain variable, and the variable pointed to by the pointer variable is called the target variable. For example: the pointer variable pa establishes a pointing relationship with the a variable a through pa=&a, we call the pointer variable pa pointing to the variable a, and the variable a is the target variable of the pointer variable pa.

Note : The type of the pointer and the type pointed to by the pointer are two concepts. The type of a pointer is the type of the pointer itself, and the type pointed to by the pointer is the type of the variable pointed to by the pointer. For example:

int a=5,b;
float x;
int *pi;
float *pf;

Among them: the type of the pi pointer: int *, the type of the pf pointer: float *, the type pointed to by pi: int, the type pointed to by pf: float.

Definition of pointer variable

The general definition form of a pointer variable:

Data type* pointer variable name
Among them: " * " indicates that the following variable name is a pointer type; "data type" is the data type that defines the target variable pointed to by the pointer variable, and can also be called the base type of the pointer variable.

Initialization of pointer variables

Pointer variables can also be assigned initial values ​​when they are defined like other types of variables. The general form is:
data type * pointer variable name = initial address value

#include <stdio.h>
void main()
{
    
    
	float x,*p1=NULL,*p2=&x;
	int y,*p3=&y;
	char name[30],*cp=name;
	...
}

As shown above, make p1 a null pointer, and p2, p3, and cp respectively store the address of x, the address of y, and the first address of the name array. It can be said that p2 points to x, p3 points to y, and cp points to name[0].
Note : 1. When assigning the address of a variable as the initial value to the pointer, the variable must be defined first, and the data type of the variable must be consistent with the data type of the pointer

int n;
int *p=&n;

or with the following equivalent definition

int n,*p=&n;

2. You can also assign an initialized pointer value as an initial value to another pointer

float x,*p=&x,*q=p;

Both p and q have the same address value, both point to the same variable x.
3. A certain type of null pointer can also be defined by initialization

int *p=0;/*值0是唯一能够直接付给指针变量的整型数*/
int *p=NULL;

The above two lines of code have the same effect, and both define a null pointer.

Basic Operations on Pointers

1. The address operation
& requires the operation variable to be a variable or an array element, and it returns the address pointing to the variable or array element. The general form is:
& variable name or array element name

int a,*p;
pa=&a;

The implementation assigns the address of the variable to the pointer pa, and the pointer pa points to the integer variable a at this time.
2. Indirect access operation
The indirect access operator "*" is usually called "indirect access operation", which is a unary operator; its right operand must be a pointer value, and the return value is the value of its specified address. The general form is:
* The address of a pointer variable or target variable

int a,b,*p;
pa=&a;
b=*pa;

The operator "*" accesses the storage area with the address of pa, and the address of the variable a is stored in pa, so the address accessed by *pa is the start address of the variable a, which is the storage area occupied by a, all of the above The assignment expression for is equivalent to b=a.

It can be seen that the "&" operator and the "*" operator are inverse operations. Pay attention to distinguish the different meanings of the following different expressions:
pa——pointer variable
*pa——the target variable of pointer pa
&pa——pointer variable pa occupies the address of the storage area
3. Assignment operation
(1) assign the address of a variable to a same type of pointer, such as:

int  a, *pa;
pa=&a; 		/* 使pa指向变量a */

(2) Assign the value of a pointer to another pointer of the same type, such as:

char  c, *s1=&c, *s2;
s2=s1;      /* 结果s1和s2指向同一变量c */

(3) Assign address constants such as array names to pointers of the same type, such as:

char  *str,ch[80];
str=ch;      /* 使str得到字符数组ch的首地址,即str指向数组ch */

(4) The result of the arithmetic operation on pointers of the same type, if it is still an address, can be assigned to a pointer of the same type. For example:

int *p1,*p2,a[20];
p1=a;  p2=p1+5;  p1=p2-3

The difference between initial value assignment and assignment operation: initial value assignment is to assign a value to the variable while defining the variable, not an indirect access operation. The result of an indirect access operation is an integer variable that cannot receive an address value.

4. Arithmetic operations on pointers
(1) Add or subtract an integer from the pointer

int a[10],*pa=a,*p;
pa+=5;/*pa指向变量a[5]*/
pb=pa-3;/*pa指向变量a[2]*/

(2) Two pointers of the same type are subtracted

int a[10],*pa=&a[1],*pb=&a[8];
int dist;
dist=pb-pa;/*diat为7,表明pa与pb两个指针所指向的数组元素之间的距离*/

Key points of pointer addition and subtraction:
① Two pointer variables cannot be added.
② The addition and subtraction of pointers is meaningful only when the pointer variable points to an array, and only when the operation result still points to an element in the same array.
③ The result of pointer addition and subtraction is not in bytes, but in the size of the data type (ie sizeof(type)).
④ Only when two pointer variables point to the same array, it is practical to perform pointer subtraction.
⑤ *(p1+n) and (*p1)+n are two different concepts.
5. Relational operation of pointers
(1) Two pointers pointing to the same array can be used for relational operations
(2) It is meaningless to compare a pointer with an integer data, and the comparison between pointer variables of different types is illegal.
⑶ NULL can perform == and != operations with any type of pointer to determine whether the pointer is a null pointer.

pointers and arrays

In the C language, the relationship between pointers and arrays is extremely close. When introducing arrays, we already know the storage method of array elements in computer memory and how the addresses of arrays are allocated, and only the arithmetic operations and relational operations between pointers pointing to the same array are meaningful, so the combination of arrays and pointers There are also many applications in the C language.

Pointers and one-dimensional arrays

1. To create a pointer to a one-dimensional array, you can define it first, and then assign a value to the pointer. For example:

int a[5],*pa,*p;
pa=a;/*  pa=&a[0];  */

Because the array name a is the first address of the array, that is, the address of a[0], the pointer pa points to the first address of the array. At this time, the value of *pa is the value of a[0]. pa+1 points to the next element. In special cases, it is also possible to make the pointer point to an array element directly after the pointer is defined, such as: p=&a[5]; 2.
Refer to an array element through a pointer
Usually there are three ways to refer to an array element:
(1) Subscript method , such as the form of a[i];
(2) Array name address method, since the array name is the first address of the array, according to the calculation rule of the address, then a+i means the first address starting from the array name a i elements, that is, the address of a[i], then *(a+i) is a[i]
(3) Pointer method, there are two forms
①Pointer address method. Since there is pa=a, then pa+i means the i-th element starting from pa, that is, the address of a[i], then *(pa+i) is a[i] ② Pointer
down standard method. Since pa=a, *(pa+i) is equivalent to a[i], so the form of pa[i] is allowed to be directly used in C language to represent the i-th data of the same type starting from the position indicated by pa.

To sum up: for the pointer pa of the same data type and the array a, once the relationship pa=a is established between the two (that is, the pointer pa points to the first address of the array a), then the following for the array element a[i] Representation is equivalent:
a[i], * (a+i), * (pa+i), pa[i]

Pay attention when using the pointer method to access array elements:
(1) The value of the pointer variable can be changed, but the value of the pointer constant used as the array name cannot be changed. If a is an array name, p is a pointer, and b is a variable, it is wrong to try to change the value of a, but the pointer is an address variable, and its value can be changed.
(2) When using pointer variables to access array elements, the problem of array out-of-bounds must be considered.
(3) If pointer variables are used in the subscript representation of array elements, their subscripts can have negative values. If there is a pointer p and an array b, when p=&b[2], if the b[1] element needs to use the pointer variable p, the subscript notation is p[-1], and the pointer method is *(p-1)
(4) Special attention should be paid to the right associativity of unary operators in pointer variable operations. For example, y=* p++ is equivalent to y=* (p++), y=* ++p is equivalent to y=*(++p)

Pointers and 2D arrays

A two-dimensional array is similar to a one-dimensional array. After establishing the relationship between pointers and arrays, pointers can be used to represent the elements of the array.
Now if there is an array a[3][4],
the ways to indicate row elements are as follows:
a[0] can be indicated by * (a+0), that is, * a can be used to indicate that a[i] can be indicated
by * (a+i)
The ways of column elements are:
&a[1][3] can be represented by a[1]+3 or * (a+1)+3
&a[i][j] can be represented by a[i]+j or * (a+i )+j means

Two-dimensional array elements can be represented in the following ways:
array subscript: a[i][j]
pointer notation: * (* (a+i)+j)
row number subscript notation: * (a[ i]+j)
column number subscript notation: * (a+i)[j]

Summarize

Pointers are an important part of the C language and a major feature of the C language. To learn pointers well, you need to clarify the two physical meanings of variables, the address of the variable and the content of the variable. The pointer variable also has its variable address and variable content, but the variable content of the pointer variable is the address of other types of variables. When referencing the pointer variable It is the content of the variable pointed to by the indirect access pointer variable. When using a pointer variable, it is necessary to pay attention to the "*" identifier, which has different meanings in different situations. *p represents the target variable of the pointer p, and &p represents the address of the pointer p. Pay attention to the application of the combination of pointers and arrays, and the way arrays are represented by pointers.

Guess you like

Origin blog.csdn.net/Tao_9/article/details/129836560