This article is only published in the blog Park, and other websites are stolen. Please consciously support the genuine version: https://www.cnblogs.com/jisuanjizhishizatan/p/15732439.html
preface
Recently, I saw someone write a wrong code in the school, as follows:
void dfs(int graph[][],int used[][],int x,int y);
Such code is bound to make mistakes (from the perspective of grammar). Feel it and write down this content.
I haven't written about dry goods for a long time recently. I'll write more dry goods this time.
1. Pointer as function parameter
1.1. One dimensional array (review)
#include<bits/stdc++.h> using namespace std; void f(int a[]){ cout<<sizeof(a)<<endl; } int main(){ int a[]={1,2,3}; cout<<sizeof(a)<<endl; f(a); }
Outputs 12.8 on 64 bit machines and 12.4 on 32-bit machines
Through this experiment, we come to the conclusion that: * when a one-dimensional array is passed as a parameter of a function, it will be used as a pointer to the first element of the array.
1.2. Pointer to array
Our experiment in the previous section is only a pointer to the first element of the array, not a pointer to the array.
The real pointer to the array is this:
#include<bits/stdc++.h> using namespace std; int main(){ int a[]={1,2,3}; int (*p)[3]=&a; cout<<sizeof(*p)<<endl; }
The output is 12, that is, three sizeof(int).
As you can see, * p is the array a. if you use the drawing method of memory diagram, it should be as follows:
So, some people will ask, what's the difference between this and the pointer to the first element of the array? Of course, there is a big difference.
We assume that the pointer to the first element of the array is Q, then when p++;q++; When,
The array will look like the above, that is, q increases sizeof(int), and p increases sizeof(a), that is, three int bits.
1.3. Addressing mode of two-dimensional array
In our human understanding, array a[2][3] is arranged as follows:
But in the understanding of the machine, it is actually arranged as follows:
Let's do an experiment:
#include<bits/stdc++.h> using namespace std; int main(){ int a[2][3]={1,2,3,4,5,6}; for(int i=0;i<2;i++){ for(int j=0;j<3;j++){ printf("%p ",&a[i][j]); } printf("\n"); } }
The results are as follows:
00000000006ffe00 00000000006ffe04 00000000006ffe08 00000000006ffe0c 00000000006ffe10 00000000006ffe14
Yes, it's arranged linearly.
a[i][j], as we are familiar with, is actually addressed as follows:
*(*(a+i)+j)
We see the following figure:
At this time, a[0] is the pointer to the array, which points to the array {1,2,3}, and a[1] points to the array {4,5,6}.
Then, a[0]+1 is the pointer to element 2, and then dereference * to get the value 2
Namely: * (a[0]+1)=a[0][1]
It can be generalized to the expansion of the above two-dimensional array: a[i][j]=*(*(a+i)+j)
1.4. Two dimensional array as function parameters
Following the experiment in Section 1.1, we are doing a similar experiment.
#include<bits/stdc++.h> using namespace std; int f(int a[2][3]){ cout<<sizeof(a)<<endl; } int main(){ int a[2][3]={1,2,3,4,5,6}; cout<<sizeof(a)<<endl; f(a); }
Output: 24 8 (64 bit) or 24 4 (32 bit)
Therefore, we find that when a two-dimensional array is used as a function parameter, it also passes a pointer.
It is worth noting here that for the same model, we generally need to test the 32-bit and 64 bit output results at the same time in order to make a better judgment. If an output value has twice the relationship between 32-bit and 64 bit, it is generally a pointer.
For some debugging environments (such as DEV C + +), 32-bit and 64 bit debugging modes can be selected,
Our conclusion is that the two-dimensional array is passed as the parameter of the function, and the pointer to the array is passed.
That is, this function is synonymous with the following functions.
int f(int (*a)[3]){ for(int i=0;i<2;i++){ for(int j=0;j<3;j++){ cout<<a[i][j]<<" "; } cout<<endl; } }
Back to the question at the beginning of the chapter, why can't used [] [] be written in the declaration of function parameters?
The answer is very simple. a[i][j] is equivalent to * (* (a+i)+j), where,
According to the principle of pointer operation, * (a+i), i*sizeof(a[0]) is actually added instead of i
In this way, because the size of a[0] is unknown in the function parameter, the width of the array must be specified manually
Otherwise, the array cannot be interpreted due to different widths
If the declaration is written as (* a)[4], the interpretation of two-dimensional arrays will be completely different.
Will be explained to do so.
If the width of the array is specified, the size of a[0] is also determined, and the addressing can be carried out smoothly.
2. Secondary pointer
2.1. concept
#include<bits/stdc++.h> using namespace std; int main(){ int a=10; int *p=&a; int **pp=&p; printf("%d %d %d",a,*p,**pp); }
Output: 10
The * * pp with two asterisks is the secondary pointer.
Type comparison list:
2.2. application
In function parameters, if you want to modify the value, you must use a pointer (or reference).
Then, in the function parameters, if you want to modify the value of the pointer, you need the pointer of the pointer, that is, multi-level pointer.
#include<bits/stdc++.h> using namespace std; void f1(char *s){ s="abcd"; } void f2(char **s){ *s="abcd"; } int main(){ char *s="first"; f1(s);puts(s); f2(&s);puts(s); }
Note that secondary pointers and two-dimensional arrays, and pointers to arrays are three completely different things.
End.