Review the concept of pointer
- A pointer is a variable used to store an address, which identifies a space
Memory is divided into small memory units. Each memory unit has a number, which is called address. We usually call the "container" containing address as pointer
Memory number = address = pointer
Pointer or address, to be stored, can be stored in pointer variable - The size of the pointer is 4 / 8 bytes, 4 bytes in 32-bit system and 8 bytes in 64 bit system
- Pointers are typed. The pointer determines the step size of the pointer, that is, the type of pointer determines how many bytes the pointer can jump at a time
- Pointer operation
Pointer ± integer
Pointer pointer
Relational operation of pointer
1. Character pointer
1.1 modify the content of the element pointed to by the character pointer
Let's take a look at the following code first
int main() { char ch = 'w'; //Create a variable of char type to store the character 'w' char *pc = &ch;//Create a character pointer variable to store *pc = 'a';//Store the character 'a' in the character pointed to by the pc address, that is, change the character pointed to by the pc to the character 'a' return 0; }
The meaning of this code is that we find the variable stored in this address through the pointer. We can change the value stored in this address only by dereferencing, obtaining the variable stored in the address and performing the assignment operation.
1.2 pointer to the first element of the string
Let's look at the case where pointers store strings
int main() { char *p="abcdef";//Store the address of the first element a of the string in the pointer variable p }
The first element of the string is the character 'a'. Here we assume that the address of the character 'a' is 0x001155f2. When the pointer variable p points to the string, it actually points to the address of the first element of the character, that is, the address of the character 'a'. It is not difficult to understand that 0x001155f2 is stored in the pointer variable P
Let's dereference the pointer p. you will find that the output is the character 'a', and you can see that the address of the first element of the string is stored in the pointer variable p
1.3 use character pointer to output string
be careful:
When printing a string, we do not need to dereference the address. Given the address of the first element,% s can print the whole string along the first element
1.4 what happens when you change a constant string
If we want to change this string
You will find that the running result is wrong, because the string "abcdef" is a constant string. Once it is changed, an error will occur. The computer is not allowed to change the constant string. The constant string will be stored in the constant area that can only be read, so it cannot be changed
1.5 what is the difference between constant string and character array in memory
Let's take a look at the following interview questions
#include <stdio.h> int main() { char str1[] = "hello bit."; char str2[] = "hello bit."; const char *str3 = "hello bit."; const char *str4 = "hello bit."; if(str1 ==str2) printf("str1 and str2 are same\n"); else printf("str1 and str2 are not same\n"); if(str3 ==str4) printf("str3 and str4 are same\n"); else printf("str3 and str4 are not same\n"); return 0; }
The answer here is:
You may be surprised that str3 and str4 are the same string. That's true
When you create two identical constant strings, because they are the same constant string, the compiler will only create one string in the constant area, so when you query their address, you will find that they are the same address
Since str1 and str2 are placed in the stack area and two different arrays are created, the addresses taken out are also different
2. Pointer array
2.1 what is a pointer array
Let's see by analogy what a pointer array is
Shaping array: an array that holds shaping
int arr[10]
Character array: an array of characters
char arr[10]
Therefore, we can deduce that pointer array is the array storing pointers, that is, each element of the array is a pointer
The reason here is int*arr[3], where 3 is the number of elements stored in the array, that is, 3 pointers are stored in the pointer array
Traversal method:
int main() { int a = 10; int b = 20; int c = 30; int* arr[3] = { &a,&b,&c }; for (int i = 0; i < 3; i++) { printf("%d", *(arr[i])); } return 0; }
2.2 pointer array storage array
int main() { int arr1[5]={1,2,3,4,5}; int arr2[5]={2,3,4,5,6}; int arr3[5]={3,4,5,6,7}; int *parr[3]={arr1,arr2,arr3}; return 0; }
Because the array name stores the address of the first element, we write arr into the pointer array, that is, the parr pointer array is an array that stores the address of the first element of three different arrays
2.3 pointer array traversal
int main() { int arr1[5]={1,2,3,4,5}; int arr2[5]={2,3,4,5,6}; int arr3[5]={3,4,5,6,7}; int *parr[3]={arr1,arr2,arr3}; for(int i=0;i<3;i++) { for(int j=0;j<5;j++) { printf("%d",parr[i][j]); //Or written as printf("%d",*(*(parr+i)+j)); } } return 0; }
For the first dereference of parr, we find the first element of the array, and the second dereference determines which element in the array
3. Array pointer
3.1 is an array pointer a pointer or an array
The answer is array pointers
Let's look at what array pointers are by analogy
Shaping pointer: pointer to shaping
intp
Type: int
Floating point pointer: a pointer to a floating point
floatp
Type: float
Character pointer: pointer to a character
charp
Type: char
The array pointer should be a pointer to the array
3.2 distinction between pointer array and array pointer
int *p1[10]; int (*p2)[10];
Explanation: p2 is first combined with * to indicate that p2 is a pointer variable, and then points to an array of 10 integers. So p2 is a pointer to an array, called array pointer.
p1 is a pointer array that stores three integer pointers
Note here that the priority of [] is higher than that of * sign, so () must be added to ensure that p is combined with * first.
3.3 array name and & array name
What are arr and & arr respectively?
We know that arr is the array name, which indicates the address of the first element of the array.
What is the &arr array name?
Let's look at the following code
#include <stdio.h> int main() { int arr[10] = {0}; printf("%p\n", arr); printf("%p\n", &arr); return 0; }
It can be seen that the address printed by the array name and & array name is the same.
Are the two the same?
Let's look at another piece of code:
#include <stdio.h> int main() { int arr[10] = { 0 }; printf("arr = %p\n", arr); printf("&arr= %p\n", &arr); printf("arr+1 = %p\n", arr+1); printf("&arr+1= %p\n", &arr+1); return 0; }
You will find that & arr + 1 skips the address of 40 bytes, that is, it skips an entire array at one time
While arr+1 still skips only one shaping at a time and only one element at a time
So &arr although the address is the same as the address of the first element, it represents an entire array
arr represents only the address of the first element of the array
The & arr here can be used
Int (* P) [10] = & arr to receive
10 here refers to 10 elements in the array pointed to by the array pointer
Usually, we say that the array name represents the address of the first element of the array
But there are two exceptions
1. Sizeof (array name), where the array name represents the whole array, and sizeof (array name) calculates the size of the whole array
2. & array name, where the array name represents the whole array, and the & array name takes out the address of the whole array
3.4 array pointer to pointer array
char *arr[5] is an array
What is the ty p e of ARP = &
Should be char*(*)[5]
in other words
The array pointer p points to a pointer array with 5 pointers
3.5 array pointer looks for elements in the array
Now we can pass arr or & arr to print the elements in the array
void printf3(int(*parr)[10],int sz) { for(int i=0;i<sz;i++) { printf("%d",*(*parr+i)); //parr=&arr; //*parr=arr; //(*parr+i)=(arr+i) //*(*parr+i)=*(arr+i)=arr[i] } } void pirntf2(int *arr,int sz) { for(int i=0;i<sz;i++) { printf("%d ",*(arr+i)); } } void printf1(int arr[],int sz) { for(int i=0;i<sz;i++) { printf("%d ",arr[i]); } } int main() { int arr[10]={1,2,3,4,5,6,7,8,9,10}; int sz=sizeof(arr)/sizeof(arr[0]); printf1(arr,sz); printf2(arr,sz); printf3(&arr,sz);
Take a closer look at the way the printf3 function outputs
We use an array pointer to receive an array
int(*parr)[10]
parr=&arr;
At this time, parr is the whole array
When parr is dereferenced, it represents the array name, that is, the address of the first element of the array
*parr=arr
When * (* parr+i)
*(parr+i)=(arr+i)=arr[i]
This method has limitations. When creating a formal parameter array pointer, you also need to know how many elements are in the array
3.6 array pointer to find elements in two-dimensional array
void printf2(int(*p)[5],int row,int col) { for(int i=0;i<r;i++) { for(int j=0;j<c;j++) { printf("%d",*(*(p+i)+j));//Why do you write that? } printf("\n"); } } void printf1(int arr[3][5],int row,int col) { for(int i=0;i<r;i++) { for(int j=0;j<c;j++) { printf("%d",arr[i][j]); } printf("\n"); } } int main() { int arr[3][5]={{1,2,3,4,5},{2,3,4,5,6},{3,4,5,6,7}} printf1(arr,3,5); printf2(arr,3,5); return 0;
The reason why printf2 transmits arr here is because the receiving method is int(*p)[5], that is, the receiver can receive an integer array with 5 elements, and arr refers to the address of the first element. Here is a two-dimensional array, and the first element should be the array of the first row
We use the array pointer to receive the first element of the two-dimensional array, and the first element of the two-dimensional array is the first row of the array, so the array pointer is the first row of the entire two-dimensional array
p+i can change the row array
Dereference p+i * (p+i) to get the first address of the array in the line array
Then go to * (p+i)+j to get the element address you want to find
The element * (* (p+i)+j)s can be obtained by dereferencing, so it can be written as p[i][j]