C language pointer learning

1. Reference array through pointer

(1) Recognize pointers to array elements

A variable has an address, and an array contains several elements. Each array element occupies a storage unit in memory, and they all have the same address. The pointer to an array element is the address of the array element. For example:

int a[10]={1,2,3,4,5,6,7,8,9,10};            //Define a as an array containing 10 integer data
int *p;                                      //Defines p as a pointer variable to an integer variable
p = &a[0];                                   //Assign the address of the a[0] element to the pointer p 

The index method or pointer method can be used to reference array elements, that is, the required elements can be found by pointing to the array elements.

C Language, the array name represents the address of the first element in the array, so the following code is equivalent
p = &a[0];             //The value of p is the address of a [0]
p = a;                 //The value of p is the address of the first element of array a 
When defining a pointer variable, you can initialize it, such as:
int * p = &a[0];
It is equivalent to the following two lines:
int * p;
p = &a[0];    //Cannot be written as * P = & A [0]
Of course, the definition can also be written as
int * p = a;
Its function is to a The address of the first element of the array is assigned to the pointer variable p 

2. Pointer operation when referring to array elements

When the pointer points to an array element, you can perform the following operations on the pointer:

Add an integer, such as p+1, and subtract an integer, such as p-1, or p + +, p --;

When two pointers are subtracted, such as p1 - p2, it is meaningful only when p1 and p2 point to the same array element. For example, when p1-p2 is executed, the result is that the difference between the two addresses is divided by the length of the array element. The two addresses cannot be added and have no meaning.

If the pointer variable p points to an element in the array, p+1 points to the next element of the same array, and p-1 points to the previous element of the same array.

Note: when p+1 is executed, the value (address) of P is not simply added by one, but the number of bytes occupied by an array element.

3. Reference array elements through pointers

There are generally two ways to reference array elements:

(1) Subscript method, such as form a [i]

(2) Pointer method, such as * (a+1) or * (p+i), where a is the array name, p is the pointer variable pointing to the array element, and the initial value is a

[example] there is an integer array a with 10 elements. It is required to output all the elements in the array

#include<stdio.h>
int main()
{
	//subscripts 
	int i,a[10];
	for(i=0;i<10;i++){
		scanf("%d",&a[i]);
	} 
	for(i=0;i<10;i++){
		printf("%d ",a[i]);
	}
	printf("\n");
	return 0;
}

Operation results:

#include<stdio.h>
int main()
{
	//Calculate the address of the array element through the array name and find out the value of the array element 
	int i,a[10];
	for(i=0;i<10;i++){
		scanf("%d",&a[i]);
	} 
	for(i=0;i<10;i++){
		printf("%d ",*(a+i));
	}
	printf("\n");
	return 0;
}

Operation results:

#include<stdio.h>
int main()
{
	//Point to array elements through pointer variables 
	int i,a[10],*p;
	for(i=0;i<10;i++){
		scanf("%d",&a[i]);
	} 
	for(p=a;p<(a+10);p++){
		printf("%d ",*p);
	}
	printf("\n");
	return 0;
}

Operation results:

Note: the third method cannot be changed to

for(p=a;a<(p+10);a++){
    printf("%d",*a);
}

Because the array name a represents the address of the first element of the array, it is a pointer constant, and its value is fixed during the operation of the pointer. Since it is unchanged, a + + cannot be implemented.

Note the current value of the pointer variable, for example:

[title] output 10 elements of integer array a through pointer variables

Idea: use the pointer variable p to point to the array element and output it by changing the value of the pointer variable

#include<stdio.h>
int main()
{
	int i,a[10],*p=a;
	for(i=0;i<10;i++){
		scanf("%d",p++);      
	} 
	for(i=0;i<10;i++,p++){
		printf("%d ",*p);
	}
	printf("\n");
	return 0;
}

Operation results:

Obviously, the output value is not each value of array a. the problem lies in the pointing of pointer variable P. the initial value of pointer variable p is the first element of A. after reading the data in the first for loop, P has pointed to the end of array A. therefore, when executing the second for loop, the initial value of P has changed to a+10. Therefore, the program should be changed to:

#include<stdio.h>
int main()
{
	int i,a[10],*p=a;
	for(i=0;i<10;i++){
		scanf("%d",p++);      
	} 
	p = a ;                 //Re point p to a 
	for(i=0;i<10;i++,p++){
		printf("%d ",*p);
	}
	printf("\n");
	return 0;
}

Operation results:

Pointer variables pointing to array elements can also have subscripts, such as p [i]. When the pointer variable points to the array element, the pointer variable can carry subscripts, because during program compilation, the processing method of subscripts is converted into addresses, and p [i] is processed into * (p+i).

The program can also be rewritten as

for(i=0;i<10;i++){
	printf("%d",*p++);
} 

Their functions are exactly the same. They all output the value of * p first, and then add 1 to the value of p, so that the next cycle will be the value of the next element

*(p + +) and * (+ + p) have different functions. The former takes the value of * p first and then adds one, while the latter first adds one and then takes the value of * p,

++(* P) indicates that the element value pointed to by P is increased by 1. If p=a, + + (* P) is equivalent to + + a [0]. If the value of a [0] is 3, the value of a [0] becomes 4 after executing + + (* P). Note that the value of a [0] is increased by 1, not the value of pointer P If the current point is to the ith element of the array, a [i], then * (P --) is equivalent to a [I --] performing "*" operation on P first, and then p subtracts itself.

*(+ + p) is equivalent to a [+ + i]. First add p, and then perform "*" operation

*(-- p) is equivalent to a [-- i]. First subtract p, and then perform "*" operation

Using the + + and -- operators for pointer variables is very effective. You can move the pointer variable forward or backward and point to the next or up array element. For example, if you want to output 100 elements of array a, you can use the following method:

p=a;
while(p<a+100){
	printf("%d",*p++);
} 
perhaps
p=a;
while(p<a+100){
	printf("%d",*p);
	p++;
} 

4. Use the array name as the function parameter

Previously, we know that the array name can be used as the parameter of the function, for example:

#include<stdio.h>
void fun(int arr[],int n);   //Declaration of fun function 
int main()
{
	int array[100];
	........
	fun(array,10);            //Use function 
	return 0;
}

void fun(int arr[],int n){    //Define fun function
.......


}  

Array is the name of the argument array, and arr is the name of the shape parameter group. When the array name is used as the parameter, if the value of each element in the formal parameter array changes, the value of the argument array elements will change together. Let's first look at the array element as an argument. If a function is as follows:

void swap(int x,int y); 

Assuming that the function is used to exchange the values of two formal parameters (x, y), now there are the following function calls:

swap(a[1],a[2]); 

Using array elements a [1] and a [2] as arguments is the way of value transfer. Pass their values to x and y, and then exchange the values of x and y, but the values of a [1] and a [2] do not change. If the array name is used, the array name of the argument represents the address of the first element of the array, and the formal parameter is used to receive the address of the first element of the array passed from the argument. Therefore, the formal parameter should be a pointer variable (only the pointer variable can store the address). c compilation takes the formal parameter array name as a pointer variable, for example:

fun(int arr[],int n)

When compiling the program, the arr is processed as a pointer variable, which is equivalent to writing:

fun(int * arr,int n)

After receiving the address of the first element of the argument array, arr points to the first element of the argument array, that is, to arr [0], * (arr+i) and arr[i] are unconditionally equivalent, so the function change can be realized.

Note: the name of the argument array represents a fixed address, that is, a pointer constant. The name of the formal parameter array is not a fixed address, that is, a pointer variable.

After the function call combines virtual and real, the value of the formal parameter is the address of the first element of the argument array. When the function is executed, it can be assigned again, for example:

void fun(arr[],int n){
	pritf("%d\n",*arr);     //Value of output arr[0] 
	arr=arr+3;              //The formal parameter array name can be assigned 
	printf("%d\n",*arr);    //Value of output arr[3] 
}

[example] store n integers in array a in reverse order.

#include<stdio.h>
void inv(int x[],int n);   //Declaration of inv function 
int main()
{
	int i,a[10]={1,2,3,4,5,6,7,8,9,10} ;
	for(i=0;i<10;i++){                               //Output the elements of the original array 
		printf("%d ",a[i]);
	}
	printf("\n");
	inv(a,10);                                     //Call function
	for(i=0;i<10;i++){
		printf("%d ",a[i]);                          //Output each element of the array after exchange 
	} 
	return 0;
}
 
void inv(int x[],int n){   //Define inv function 
	int temp,i,j,m=(n-1)/2;
	for(i=0;i<m;i++){
		j=n-1-i;
		temp=x[i];
		x[i]=x[j];
		x[j]=temp; 
	}
} 

Operation results:

When defining the inv function, you can not specify the size of the shape parameter group, because the formal parameter array name is actually a pointer variable.

Some changes can be made to this procedure. Change the formal parameter x in the function inv into a pointer variable, and the corresponding argument is still array name a.

Modification procedure:

#include<stdio.h>
void inv(int x[],int n);   //Declaration of inv function 
int main()
{
	int i,a[10]={1,2,3,4,5,6,7,8,9,10} ;
	for(i=0;i<10;i++){                               //Output the elements of the original array 
		printf("%d ",a[i]);
	}
	printf("\n");
	inv(a,10);                                     //Call function
	for(i=0;i<10;i++){
		printf("%d ",a[i]);                          //Output each element of the array after exchange 
	} 
	return 0;
}
 
void inv(int *x,int n){   //Define inv function 
	int *p,temp,*i,*j,m=(n-1)/2;
	i=x;
	j=x+n-1;
	p=x+m;
	for(;i<=p;i++,j--){
		temp=*i;
		*i=*j;
		*j=temp;
	}
} 

Operation results:

Summary: if there is an argument array and you want to change the value of this array element in the function, there are four corresponding relationships between the argument and the formal parameter.

(1) Both formal and actual parameters use array names, for example:

int main(){
	int a[10];
	......
	f(a,10);
	......
	return 0;
}
int f(int x[],int n){
	......
}

Since the formal parameter array name x receives the address of the first element a[0] of the argument array, it can be considered that the formal parameter array and the argument array share a memory unit during the function call.

(2) Array name for argument and pointer variable for formal parameter, for example:

int main(){
	int a[10];
	......
	f(a,10);
	......
	return 0;
}
int f(int * x,int n){
	......
}

The actual parameter a is the array name and the formal parameter x is an int * pointer variable. After calling the function, the formal parameter x points to a[0]. Through the change of x value, it can point to any element of array a.

(3) All arguments and formal parameters use pointer variables, for example:

int main(){
	int a[10];
    int * p = a;
	......
	f(p,10);
	......
	return 0;
}
int f(int * x,int n){
	......
}

Both argument P and formal parameter X are int * pointer variables. First, make the argument pointer variable p point to array a[0], and then pass the value of P to formal parameter pointer variable x. the initial value of X is also the address of a[0]. Through the change of x value, it can point to any element of array a.

(4) The argument is a pointer variable and the formal parameter is an array name, for example:

int main(){
	int a[10];
    int * p = a;
	......
	f(p,10);
	......
	return 0;
}
int f(int x[],int n){
	......
}

The actual parameter p is a pointer variable. It points to the first element of array a, and the formal parameter is the array name X. the compilation system processes x as a pointer variable. Now pass the address of a[0] to formal parameter x, so that x also points to a[0]. It can also be understood that formal parameter x and array a share the same memory unit.

[example] rewrite the previous question and use pointer variables as arguments.

#include<stdio.h>
void inv(int *x,int n);   //Declaration of inv function 
int main()
{
	int i,arr[10],* p = arr;
	for(i=0;i<10;i++,p++){
		scanf("%d ",p);
	}
	printf("\n");
	p=arr;
	inv(p,10);
	for(;p<arr+10;p++){
		printf("%d ",*p);
	}
	printf("\n");
	return 0;
}
 
void inv(int *x,int n){   //Define inv function 
	int *p,temp,*i,*j,m=(n-1)/2;
	i=x;
	j=x+n-1;
	p=x+m;
	for(;i<=p;i++,j--){
		temp=*i;
		*i=*j;
		*j=temp;
	}
} 

[example] use the pointer method to output 10 integers from small to large

#include<stdio.h>
void sort(int x[],int n);                          //sort function declaration
int main()
{
	int i,*p,a[10];
	p=a;
	for(i=0;i<10;i++){
		scanf("%d",p++);                           //Enter 10 integers 
	}
	p=a;                                           //Pointer variable p points back to a[0]
	sort(p,10);                                    //Call sort function 
	for(p=a,i=0;i<10;i++){
		printf("%d ",*p++);                        //Output sorted elements 
	}
	return 0;
 } 
void sort(int x[],int n)
{
	int i,j,k,t;
	for(i=0;i<n-1;i++){
		k=i;
		for(j=i+1;j<n;j++){
			if(x[j]>x[k]){
				k=j;
			}
			if(k!=i){
				t=x[i];
				x[i]=x[k];
				x[k]=t;
			}
		}
	}
}

Operation results:

5. Reference multidimensional array through pointer

Pointer variables can point to elements in one-dimensional arrays or multi-dimensional arrays, but they are more complex in concept and usage.

(1) Address of multidimensional array element

Take a two-dimensional array as an example. Suppose there is a two-dimensional array a, which has three rows and four columns. Its definition is

int a[3][4] = { {1,3,5,7} , {9,11,13,15} , {17,19,21,23} };

A is the name of a two-dimensional array. Array a contains three lines, that is, three line elements: a[0],a[1],a[2]. Each row element is a one-dimensional array, which contains four elements, that is, four column elements. It can be considered that a two-dimensional array is an "array of arrays".

From the perspective of two-dimensional array, a represents the address of the first element of the two-dimensional array. The current first element is not a simple integer element, but a one-dimensional array composed of four integer elements. Therefore, a represents the address of the first line element, and a+1 represents the starting address of the line with sequence number 1. If the starting address of the first line of the two-dimensional array is 2000, an integer data accounts for 4 bytes, Then the value of a+1 is 2000 + 4 * 4 = 2016 (because there are four integer data in row 0), a+1 points to a [1], and a + 2 points to a [2] A [0] + 1 stands for a [0] [1], and a [0] + 2 stands for a[0][2]

As we know earlier, a[0] and * (a+0) are equivalent, and a[1] and * (a+1) are equivalent, so a[0]+1 and * (a+0) + 1 both represent & a[0][1], a[0] + 2 and * (a+0) + 2 both represent & a[0] [2]. Since a[0]+1 and * (a+0) + 1 both represent the address of a[0][1], then * (a[0]+1) is the value of a[0][1]. Similarly, * (a[i]+j) and * (* (a+i) + j) are the values of a[i][j].

It is necessary to further explain the nature of a [i]. If a [i] is a one-dimensional array, it represents the ith element of the one-dimensional array. If it is a two-dimensional array, a [i] is the name of the one-dimensional array, which is just an address.

First of all, a+1 is the starting address of the row with sequence number 1 in two-dimensional array a, and * (a+1) is not the value of a+1 unit. Because a+1 is not the address of an array element, * (a+1) is a [1], that is, the name of one-dimensional array, that is, the address, which points to a [1] [0]

The address information of C language includes location information and data type information. Now a [0] is a one-dimensional array name, which is the address of the starting element in the one-dimensional array, and a is a two-dimensional array name, which is the starting address of the first row of the two-dimensional array. Their pure addresses are the same, but their base types are different, that is, they point to different data types. The former is integer data, The latter is a one-dimensional array. If a pointer variable pt is used to point to this one-dimensional array, it should be defined as follows:

int (*pt)[4];

Indicates that pt points to a one-dimensional array composed of four integer elements. The base type of this pointer variable is a one-dimensional array composed of four integer elements.

[example] output relevant data of two-dimensional array (address and element value)

#include<stdio.h>
int main()
{
	int a[3][4]={1,3,5,7,9,11,13,15,17,19,21,23};
	printf("%d ,%d\n",a,*a);                      //0 row start address and 0 row 0 column element address
	printf("%d ,%d\n",a[0],*(a+0));               //0 row 0 column element address      
	printf("%d ,%d\n",&a[0],&a[0][0]);            //0 row start address and 0 row 0 column element address      
	printf("%d ,%d\n",a[1],a+1);                  //1 row 0 column element address and 1 row start address    
	printf("%d ,%d\n",&a[1][0],*(a+1)+0);         //1 row 0 column element address          
	printf("%d ,%d\n",a[2],*(a+2));               //2 row 0 column element address      
	printf("%d ,%d\n",&a[2],a+2);                 //Line 2 start address     
	printf("%d ,%d\n",a[1][0],*(*(a+1)+0));       //Value of 1 row 0 column element              
	printf("%d ,%d\n",*a[2],*(*(a+2)+0));         //Value of 2 row 0 column element             
	return 0;
}

It is suggested to watch and think again!!!!

Operation results:

(2) Pointer variables to multidimensional array elements

1. Pointer variable pointing to array element

[example] there is a 3 * 4 two-dimensional array. It is required to output the value of each element of the two-dimensional array with the pointer variable pointing to the element

#include<stdio.h>
int main()
{
	int a[3][4]={1,3,5,7,9,11,13,15,17,1,21,23};
	int *p;
	for(p=a[0];p<a[0]+12;p++){                        //Make p point to the next element in turn 
		if((p-a[0])%4==0){
			printf("\n");                             //p move 4 line breaks 
		}
		printf("%4d",*p);                             //Output the value of the element pointed to by p 
	} 
	return 0;
}

Operation results:

If you want to output a specified numerical element, you should first calculate the relative position of the element in the array. The calculation formula for calculating the relative position of a [i] [j] in the array is: i*m+j, where m is the number of columns in the two-dimensional array.

2. Pointer variable pointing to a one-dimensional array composed of m elements

Now you can use another method to make p point to a one-dimensional array containing m elements instead of an integer variable. At this time, if p points to a [0] first, p+1 points to a [1] instead of a [0] [1]

[example] output the value of any row or column element of the two-dimensional array

#include<stdio.h>
int main()
{
	int a[3][4]={1,3,5,7,9,11,13,15,17,19,21,23};     //Define a two-dimensional array and initialize it 
	int (*p)[4],i,j;                                  //The pointer variable p points to a one-dimensional array containing four integer elements
	p = a;                                            //p points to row 0 of the two-dimensional array
	scanf("%d %d",&i,&j);                             //Enter line number
	printf("a[%d][%d]=%d\n",i,j,*(*(p+i)+j));         //output 
	return 0;
}

Operation results:

Note: (* p) [4] cannot be written as * p [4], * p [4] indicates an array of pointers. Due to the high priority of square brackets, p is combined with [4] to form an array, and then with *.

3. Use pointer array as function parameters

The one-dimensional array name can be used as a function parameter, and the multi-dimensional array name can also be used. The pointer variable is used as a formal parameter to accept the address passed from the actual parameter array name. There are two methods: 1 Use the pointer to the variable to {2 Using pointer variables pointing to one-dimensional arrays

[example] there is a class of three students, each studying four subjects. Calculate the average score and the score of the nth student

#include<stdio.h>
void average(float *p,int n);
void search(float (*p)[4],int n);
int main()
{
	float score[3][4]={{65,67,70,60},{80,87,90,81},{90,99,100,98}};
	average(*score,12);                                   //Average score
	search(score,2);                                      //Find the grade of the student with serial number 2 
	return 0;
}
void average(float *p,int n)
{
	float *p_end;
	float sum=0,aver;
	p_end=p+n-1;
	for(;p<=p_end;p++){
		sum=sum+(*p);
		aver=sum/n;
	}
	printf("averag=%d\n",aver);
}
void search(float (*p)[4],int n)
{
	int i;
	printf("The score of No.%d are \n",n);
	for(i=0;i<4;i++){
		printf("%5.2f",*(*(p+n)+i));
	} 
}

When calling the search function, the actual parameter is score (the name of the two-dimensional array, representing the starting address of the 0 line in the array) and is passed to p, so that p also points to score[0]. p+n is the starting address of score[n], and * (p+n) + I is the address of score[n][i].

[example] on the basis of the previous question, find students who have failed more than one course and output all their courses and grades

#include<stdio.h>
void search(float (*p)[4],int n);                         //Function declaration 
int main()
{
	float score[3][4]={{65,57,70,60},{80,87,90,81},{90,99,100,98}};
	search(score,3);                                      //Call function 
	return 0;
}

void search(float (*p)[4],int n)
{
	int i,flag,j;
	for(j=0;j<n;j++){
		flag=0;
		for(i=0;i<4;i++){
			if(*(*(p+j)+i)<60){
				flag=1;
			}
		
		}
		if(flag==1){
			printf("No.%d fails,his scores are:\n",j+1);
			for(i=0;i<4;i++){
				printf("%5.1f",*(*(p+j)+i));
			}
			printf("\n");
		}
	}
}

Operation results:

 

Keywords: C

Added by mhodge87 on Sat, 29 Jan 2022 03:13:50 +0200