Pointer array and array pointer - not twins of twins

Posted by jovankau on Sat, 22 Jan 2022 00:21:45 +0100

catalogue

1, Pointer array

1.1 basic knowledge of pointer array

1.2 practical case analysis of pointer array

Second, array pointer

1.1 basic knowledge of array pointer

2.2 application examples of array pointers

2.2.1 negative examples

2.2.2 correct examples

As the title shows, today we will know a pair of twins, but not twins.

1, Pointer array

1.1 basic knowledge of pointer array

We know integer arrays and character arrays. Is the pointer array similar to them? The answer is yes. The pointer array is the array that stores pointers. Each element of the array is a pointer. The following code is shown:

	int a[10];//integer array 
	char a1[10];//Character array
	int* arr1[10];//(integer) pointer array

Of course, it is indispensable, because array elements also need to have data types. Here is an integer pointer array.

Note here that the priority of operators. We know that the priority of [] is higher than *, so here, the array name is combined with the array to indicate that it is an array of ten elements, and then we see that the front is an integer pointer, so arr1 is an integer pointer array.

1.2 practical case analysis of pointer array

Let's learn the basic usage of pointer array through an example.

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

As shown in the figure above, pa is an integer pointer array with three elements, and the three elements are the array names of the three arrays respectively. We know that the pointer array must store pointers; We also know that in general, the array name represents the address of the first element of the array, so this is feasible.

Then we want to print all the elements of the three arrays. We need to find all the elements of each row. Our method is to find each group of data through the pointer array, and then traverse each group one by one.

Note that the print statement can be written in multiple ways. The analysis of the writing method of the above code is as follows: pa [i] finds an element of the pa array, where pa [i] is equivalent to the array name arr, and then {Arr1 [J], isn't it equivalent to finding an element in another array? So we can traverse all the elements of all arrays together. It should also be noted that although this print looks like a two-dimensional array, it has nothing to do with the two-dimensional array!!!  

Of course, there are more than one method to realize printing, which will be covered one by one later.

Second, array pointer

1.1 basic knowledge of array pointer

You may have questions about what array pointers are. After all, you've seen character pointers and integer pointers, but you haven't seen array pointers. Don't worry. The following code will solve your doubts:

//Array pointer
int main()
{
	int a = 2;
	int* pa = &a;//Integer pointer
	char b = 'v';
	char* pb = &b;//Character pointer
	int arr[10] = {0};
	int(*pc)[10] = &arr;//Array pointer. Here, because the [] operator takes precedence over the * operator,
	                   //So we need to add () to force pc and * to match, otherwise it will become the following pointer array
	int* arr[10] = arr;//Pointer array
}

Integer pointer and character pointer are easy to understand, that is, the content pointed to by the pointer is integer and character. Similarly, the content pointed to is array pointer, which is called array pointer.

Then, as shown in the above code, the format of the array pointer is to first determine that it is a pointer, so enclose * and pointer variables to indicate that this is a pointer, and then add [10], indicating that this pointer points to an array with ten elements. Finally, it should be noted that the int here is not the data type of the array pointer, but the data type of each element in the array is int. Then, the array pointer pc type is int (*) [10], so & arr can be equal to the array pointer.

2.2 application examples of array pointers

2.2.1 negative examples

Next, let's learn a negative example of array pointers:

//Negative example
//Print with array pointer, that is, pass the address of the whole array to the pointer variable
#include<stdio.h>
void print2(int (*pb)[8],int b)
{
	int i = 0;
	for (i = 0; i < b; i++)
	{
		//printf("%d ",(*pb+0)[i]);//(*pb+0) represents the first element of the array, [i] represents the element in the first element.
		                           //So it's awkward and unnecessary to write like this
		                           //What really uses this situation is: two-dimensional arrays
		//printf("%d ",pb[0][i]);
		printf("%d ", *((*pb)+i));//What you can see here is that the + operator takes precedence over the*
	}
}
int main()
{
	int arr[] = {1,2,3,4,5,6,7,8};
	int sz = sizeof(arr) / sizeof(arr[0]);
	//print1(arr,sz);
	print2(&arr,sz);
	return 0;
}

The goal we want to achieve here is to print all the elements in a one-dimensional array with functions. You can see the above code. Pass the addresses of all elements of a one-dimensional array to the array pointer, and then print with the array pointer. You can see that the printing of the array pointer is cumbersome. Although it can be said that there are three ways to print, these three methods are far more complex than passing only the array name, which is the general habit of passing parameters. The following code is the way to pass only the array name:

void print1(int *pa,int a)
{
	int i = 0;
	for (i = 0; i < a; i++)
	{
		printf("%d ",*(pa+i));
	}
}
//void print1(int pa[], int a)
//{
//	int i = 0;
//	for (i = 0; i < a; i++)
//	{
//		printf("%d ", pa[i]);
//	}
//}

When we have simpler and faster methods, we naturally will not replace them with very complex ways. Just like here, only passing the array name, then receiving it with the array or first level pointer, and finally accessing all the elements of the array with the array or pointer is obviously more convenient and faster than using the array pointer. Therefore, we should know that some things are not necessarily more complex and more efficient.

Of course, because the three prints here are a little difficult to understand, we put the correct examples to help you understand yo!  

2.2.2 correct examples

OK, as mentioned earlier, array pointers cannot be used indiscriminately, otherwise the opposite effect may be achieved. So where can it be used in practice? What we know is that the array pointer is first a pointer, and then an array whose elements are of a certain type. If we point the pointer to a two-dimensional array, isn't each line in the two-dimensional array the number in the array pointer? Yes, the code is as follows:

#include<stdio.h>
void print(int (*pa)[4],int r,int c)//Receive two-dimensional array parameters. Because they belong to array pointers, you need to give the number of elements with the first address ()
{
	int i = 0;
	for (i = 0; i < r; i++)
	{
		int j = 0;
		for (j = 0; j < c; j++)
		{
			//printf("%d ", *(*(pa+i)+j));
			//printf("%d ", pa[i][j]);
			printf("%d ",(*(pa+i))[j]) ;
         //Summary: there are three printing methods for printing array pointers.
		}
		printf("\n");
	}
}
int main()
{
	int arr[3][4] = { {1,2,3,4},{5,6,7,8},{9,10,11,12} };
	//int(*pa)[3][4] = &arr;// This kind of writing generally does not exist, which can be called wrong writing
	print(arr,3,4);//When a two-dimensional array passes parameters, the first element passed is actually the address of the first line element
	return 0;
}

In this code, the two-dimensional array passes the array name, which means that the address of the first line element is passed, so the formal parameter needs to be received with the array pointer when it is received, and when it is a one-dimensional array, the number of elements in this line is indispensable.

Then the more important thing is three printing. First, it is easy to understand that PA [i] [j], PA [i] represents the first line of elements, and then add [j], which represents a specific element in each line. This is reflected in the form of array.

Secondly, because pa [i] represents the first line of elements, you can also find * (pa+i) by pointing to dereference. pa represents the address of the first line of elements, adding the line number, dereferencing, you can get all the elements of each line, and then adding [j] to determine each element.  

The third method is based on the second method. When the exact position of each element is determined after dereferencing all the elements in each line, since all the addresses of each line are passed, it can also be accessed by pointers. Therefore, each element can be found by dereferencing it, i.e. * (* (pa+i)+j).

Seeing this, do you also think that the pointer array and array pointer are what they said at the beginning, not twins of twins?

That's all for the pointer array and array pointer. If there are errors or deficiencies in the article, please leave a message and comment!

Topics: C C++