Super detailed explanation of advanced pointer knowledge (C language) (Part 2)

Foreword
After waiting so hard, we finally have the second issue of our pointer explanation. If there are friends who haven’t read the previous issue, please click on this link to learn. Let’s read this blog again later. Link: Super detailed explanation of pointer basics (C language) (Part 1)
If you are interested in learning C language, don’t forget to follow this column. O(∩_∩)O (Also follow the blogger!): C language learning column

Insert image description here


In the last blog, we learned the basic pointer types, pointer addition and subtraction operations, as well as the causes of wild pointers and methods to avoid wild pointers. In today’s blog we will learn more about pointers. So long let’s get started!

1. Multi-level pointers

First let us write a simple pointer variable.
int a = 10;
int* pa =&a;< /span> pppa is the same. Then if we want to remove a from ppa, we must dereference * ( * ppa ) = * pa = a We know that to remove a from pa, we need to dereference * pa=a Same as above, ppa It is a three-level pointer. Pointers with more than two levels are called multi-level pointers. pppa = ppa; * * * int Then we define another pointer. This is the secondary pointer. . Then defining ppa in this way means that ppa is a pointer that stores the address of a variable with data type int * means that the data type of the variable pointed to by the address stored in ppa is int * type, and then The * means that ppa is a pointer. to define ppa, int * * type to define pa. If we want to store the address of pa in a pointer variable, then we should use int We know that the address of pa will be Points to the integer variable a, so we use the intppa = pa;* * int
The int* here represents that the data type of pa is an integer pointer. What about this one?









2. The essence of one-dimensional array parameter transfer and the meaning of the array name

If there is a function here and its parameter is an array, how do we pass this parameter? You can take a look at the demonstration below.

#include<stdio.h>
viod test(int arr[])
{
    
    
;
}
int main()
{
    
    
int arr[10] = {
    
    1,2,3,4,5,6,7,8,9,10};
test(arr);
return 0;
}

I can see that we pass the array name directly to the function. What is the principle of this? Next, let me introduce to you the essence of array names.
When arr exists alone, it represents the address of the first element of the array. When we pass arr as a parameter, we actually pass the first address of the arr array. So will everyone be confused at this time? Since I passed the address, why should I set the parameter to int arr[]? In fact, int arr[] is equivalent to int * arr. That is to say, we can also write the parameter format as int * arr.
But there are special cases, such as when we want to print the size of an array, we will write such a piece of code.
printf(“%zd”,sizeof(arr));
At this time, arr also exists alone, but this is not the address of the first element of the array. , but represents the entire array. Except for this case, the array name appearing alone represents the address of the first element of the array.
In this case, what does &arr represent? We might as well write down such a piece of code and test it.

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

Insert image description here

We will find that the addresses of the two are the same. Does &arr represent the address of the first element? Then let’s +1 each address and print it out.

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

Insert image description here
It can be seen that the results are different. Compared with arr, arr+1 has 4 more than arr, which is exactly the size of an integer, while &arr+1 has 40 more than arr, which is exactly the size of the entire array. size. The entire array size is skipped for &arr+1. Description &arr is the address of the entire array.
Since arr appears alone, it represents the address of the first element of the array, then if we dereference arr, we will get the first element of the array. * arr = 1
The dereference to arr+1 is naturally the second element of the array *arr+1 = 2
Then we will find* arr is equivalent to arr[0] and * arr+0, and * arr+1 is equivalent to arr[1]. When we want to print the entire array through a loop we can write like this.

for(int i = 0;i <= 9 ;i++)
{
    
    
printf("%d",*arr+i);
}

3. Pointer array

The pointer array, as the name suggests, is an array. The integer array contains integers, and the character array contains characters, so the pointer array contains pointers. The most basic integer pointer array is defined like this (the elements in the array are integer pointers).
int* arr[10] ;(arr is the array name, array There are ten elements in it)
We can store integer pointers in it.

4. Array pointer

Digital pointer, obviously it is a pointer. It stores the address of an array. Let's first define an integer array pointer (which stores the address of an integer array) as a demonstration.
int arr[2]={1,2};
int (*parr)[2] = &arr;([ ] has a higher priority than *, so *parr should be enclosed in parentheses () to indicate that parr is a pointer, [2] means that the array pointed to by the array pointer has two elements)
So what are the results of array pointer addition and subtraction operations?

int main()
{
    
    
	int arr[4] = {
    
     1,2,3,4 };
	int(*parr)[4] = &arr;
	printf("%p %p", parr, parr + 1);
	return 0;
}

Insert image description here

We will find that it is +16, which is exactly the size of the arr array. It can be seen that parr+1 will skip the entire array size.
If parr is dereferenced, then we will get the address of the array arr, which is the address of the first element of arr.

5. The essence of passing parameters through two-dimensional arrays

First of all, we can understand a two-dimensional array as a one-dimensional array, and each element in this one-dimensional array is a one-dimensional array, that is, each row of the two-dimensional array is one of its elements. Dereferencing arr will get the address of its first element, which is the one-dimensional array of the first row. Dereferencing arr+1 will get the address of the one-dimensional array in the second row.
Insert image description here

We can write two-dimensional array parameters in two ways.

void test(int(*parr)[2])
void test (int arr[][2])//行数可以不写但是列数必须写

These two writing methods are completely equivalent, because * parr = arr [ 0 ]= * arr+0 **parr = arr[0][0]=**arr.
When passing parameters to a two-dimensional array, what is actually passed is the address of the first row of the two-dimensional array.
*((*parr+1)+1) is equivalent to arr[1][1].

6. Epilogue

After reading this blog, everyone must have a deeper understanding of arrays and pointers. If you think the blogger’s writing is good, don’t forget to follow the blogger and wait for the explanation of pointers (Part 2). I hope everyone can learn from it. Pointers (pointers are very important), think about your goals and take further steps!
Last issue link, rush!

Guess you like

Origin blog.csdn.net/Tokai___Teio/article/details/134740895