1, Pointer array
Pointer array is essentially an array, which is an array of pointer types.
The following defines a pointer array type of int type:
typedef int *PtrArray[4];
"[]" has higher priority than "*", PtrArray combines with "[]" to indicate that it is an array, and then combines with the outer "int *" to indicate that the elements in this array are pointers of type int. That is, PtrArray is an array with a size of 4. There are 4 addresses stored in the array.
After defining the pointer type in the array, we can access the data stored in the array through the pointer type of int.
int main(void) { int i = 0; int a[4] = {1, 2 ,3, 4}; PtrArray ptr_array; for(i = 0; i < 4; i++) { ptr_array[i] = &a[i]; printf("*ptr_array[%d] = %d\n", i, *ptr_array[i]); } return 0; }
The results of gcc compilation under linux are as follows:
II. Array pointer
Array pointer is essentially a pointer, which points to an array type. It can be considered that this pointer is the address of the array, which is numerically equal to the first address of the first element of the array, but in a different sense.
The following defines an array pointer type of int type:
typedef int (*ArrayPtr)[];
ArrayPtr is a pointer type. This pointer type points to an array, which means that we can define a variable with this custom type, and then we can assign a value to this variable. This value must be the address of an int type array, as follows:
int main(void) { int a[4] = {1, 2 ,3, 4}; ArrayPtr array_ptr = &a; return 0; }
At this time, the compilation does not report an error, but if we give array_ If the value assigned to PTR is not & A but a, the following warning will be reported, indicating that the type does not match. Because & A is the address of the whole array and a is the first address of the first element of the array. Although there is no difference in value, they are completely different in meaning.
We can also access the elements in the array through the array pointer:
#include <stdio.h> typedef int (*ArrayPtr)[]; int main(void) { int i = 0; int a[4] = {1, 2 ,3, 4}; ArrayPtr array_ptr = &a; for(i = 0; i < 4; i++) { printf("(*array_ptr)[%d] = %d\n", i, (*array_ptr)[i]); } return 0; }
The compilation results are as follows:
Array is passed to the function as a parameter, and the pointer to the first element of the array is passed instead of the array pointer.
I've seen similar statements in some interview questions before. It says "array is passed to function as a parameter, and the address of array is passed". In my opinion, this sentence is not rigorous. Whether it is the address of array or the address of the first element of array, the compiler will tell us that we can use the following code to test:
1 #include <stdio.h> 2 3 int *p1 = NULL; 4 int (*p2)[] = NULL; 5 6 void Fun1(int *a) 7 { 8 p1 = a; 9 p2 = a; //11:5: warning: assignment from incompatible pointer type 10 } 11 12 int main(void) 13 { 14 int a[4] = {1, 2 ,3, 4}; 15 Fun1(a); 16 return 0; 17 }
gcc compilation results under Linux are as follows:
We can see that the compiler will prompt us for type mismatch at the function definition.
p1 here is a pointer of type, and p2 is a pointer of int array type. It can be concluded that the array is passed to the function as a parameter, and the address of the first element of the array is passed, not the address of the whole array. This is also the reason why when the array is used as a function parameter, a parameter is generally added to specify the size of the incoming array, because the array parameter will only pass the address of the first element of the array. It is impossible to infer the overall size of the array from the address of the first element of the array inside the function (although the address of the array is numerically equal to the address of the first element of the array), It is also impossible to specify the size of the array when passing the array. The following is an example of specifying the size of the array when passing the array. When measuring the size of p, we will only get the size of a pointer, but not the size of the array.
1 #include <stdio.h> 2 3 void Fun1(int *p) 4 { 5 printf("sizeof(p_in_fun1) = %d\n", sizeof(p)); 6 } 7 8 void Fun2(int p[5]) 9 { 10 printf("sizeof(p_in_fun2) = %d\n", sizeof(p)); 11 } 12 13 int main(void) 14 { 15 int a[5] = {1, 2 ,3, 4, 5}; 16 Fun1(a); 17 Fun2(a); 18 return 0; 19 }
Compile and run results:
Therefore, it is generally necessary to add a parameter specifying the size of the array when passing parameters to the array, which is not easy to cause the problem of array access out of bounds. When the array access out of bounds, random results will appear, and even segment errors will occur at run time (Segment Error: accessing the memory area that should not be accessed).
1 #include <stdio.h> 2 3 void Fun1(int *p) 4 { 5 printf("sizeof(p_in_fun1) = %d\n", sizeof(p)); 6 printf("*(p_in_fun1+5) = %d\n", *(p+5)); //Generate random number 7 } 8 9 void Fun2(int p[5]) 10 { 11 printf("sizeof(p_in_fun2) = %d\n", sizeof(p)); 12 } 13 14 int main(void) 15 { 16 int a[5] = {1, 2 ,3, 4, 5}; 17 Fun1(a); 18 Fun2(a); 19 return 0; 20 }
Random number generated:
However, when passing the array pointer, you can specify the size of the array at the same time, or you can get the size of the array inside the function. The test code is as follows:
#include <stdio.h> void Fun1(int *p) { printf("sizeof(p_in_fun1) = %d\n", sizeof(p)); } void Fun2(int p[5]) { printf("sizeof(p_in_fun2) = %d\n", sizeof(p)); } void Fun3(int (*p)[5]) { printf("sizeof(p_in_fun3) = %d\n", sizeof(*p)); } int main(void) { int a[5] = {1, 2 ,3, 4, 5}; Fun1(a); Fun2(a); Fun3(&a); return 0; }
Compile and run results:
Summary:
When an array is passed to a function as a parameter, it is generally necessary to pass the array size at the same time, because what is passed is only the address of the first element of the array. The array size cannot be obtained through the address of the first element of the array. Passing the array size can avoid the array access out of bounds.
New talents are not familiar with learning. Please correct any mistakes!!