[statement]: This study of pointer is only the initial stage, and there will be further in-depth study in the future. Please look forward to it!
Pointer
What is the pointer?
- In computer science, a Pointer is an object in a programming language. Using an address, its value directly points to a value stored in another place in computer memory. Since the required variable unit can be found through the address, it can be said that the address points to the variable unit. Therefore, the address visualization is called "Pointer". It means that the memory unit with its address can be found through it.
- A pointer is a variable that holds the address (number) of the memory unit
Look at the picture to understand the memory unit:
The corresponding code is roughly as follows:
#include<stdio.h> int main() { int a = 10;//a takes up 4 bytes int *pa = &a;//Store the address of a in the pa variable. pa is a pointer variable. pa gets the address of the first of the four bytes of A *pa = 20;//You can change a return 0; }
Summary: pointer is a variable used to store address variables. (the values stored in the pointer are treated as addresses)
How big is a small unit?
Answer: 1 byte
How to address?
After careful calculation and trade-off, we find that it is more appropriate to give a corresponding address to a byte.
For a 32-bit machine, assuming that there are 32 address lines, it is assumed that each address line generates an electrical signal positive / negative (1 or 0) when addressing
Then the address generated by the 32 address lines will be:
00000000 00000000 00000000 00000000
00000000 00000000 00000000 00000001
...
11111111 11111111 11111111 11111111
There are 32 addresses to the power of 2.
Each address identifies a byte, then we can give
(2^32Byte== 2 ^ 32 / 1024KB
==2 ^ 32 / 1024 / 1024MB
== 2 ^ 32 / 1024 / 1024 / 1024GB
==4GB) address the idle of 4G.
In the same way, if you give 64 address lines to the 64 bit machine, you can calculate how much space it can address.
Here we understand:
On a 32-bit machine, the address is 32 zeros or 1s to form a binary sequence, so the address has to be stored in 4 bytes
The size of a pointer variable should be 4 bytes.
If there are 64 address lines on a 64 bit machine, the size of a pointer variable is 8 bytes before it can be stored in one place
Address.
Summary:
Pointers are used to store addresses, which uniquely identify an address space.
The size of the pointer is 4 bytes on 32-bit platforms and 8 bytes on 64 bit platforms.
Pointer and pointer type
#include<stdio.h> int main() { int* pa; char* pb; short* pc; long * pd; float *pe; double *pf; printf("%d\n", sizeof(pa));//4 printf("%d\n", sizeof(pb));//4 printf("%d\n", sizeof(pc));//4 printf("%d\n", sizeof(pd));//4 printf("%d\n", sizeof(pe));//4 printf("%d\n", sizeof(pf));//4 return 0; }
Question: the size is the same. No matter what type of pointer variable is, the size of the variable is 4 bytes. What does that have to do with the type?
Since the size is the same, why not create a common type pointer yourself?
A: This shows that the pointer type has specific meaning
What is the meaning of pointer type?
Integer pointer
#include<stdio.h> int main() { int a = 0x11223344;//hexadecimal, int *pa = &a;//The pointer variable pa receives the address of a *pa = 0;//Dereference the pointer variable, change the address of a to 0, and dereference accesses 4 bytes return 0; }
Character pointer
#include<stdio.h> int main() { int a = 0x11223344;//hexadecimal char * pc = &a;//Put the address of a in the pc *pc = 0;//Dereference the pointer variable and change the address of a to 0. At this time, dereference only accesses 0 bytes return 0; }
From the code and debugging of integer pointer and character pointer, it can be concluded that only the type changes, their access rights change, indicating that the pointer type is meaningful
Meaning of pointer type:
- 1. The pointer type determines the permission of pointer dereference, that is, when you want to access 4 bytes backward from this address, you can store this address in an int pointer, and the int pointer dereference can access 4 bytes. Similarly, when you want to access 1 byte backward from this address, Then you can store this address in a char pointer. Only when the char pointer is dereferenced can you access a byte
For example:
#include<stdio.h> int main() { int arr[10] = { 0 }; int *p = arr; char *pc = arr; printf("%p\n", p); printf("%p\n", p+1); printf("%p\n", pc); printf("%p\n", pc+1); return 0; }
Through the above code and debugging, the second meaning of pointer type can be obtained
- 2. The pointer type determines how far the pointer can go (step size) by one step (- backward and + forward)
#include <stdio.h> int main() { int arr[10] = { 0 }; int *p = arr;//Give the array name arr to an integer pointer int i = 0; for (i = 0; i <= 10; i++) { *(p + i)=1;//p+i: it is the address with subscript i. after dereference, each element of the integer array is changed to 1 } }
Summary:
Integer pointer + 1 skips an integer
Character pointer + 1 skips a character
Field pointer
Concept: a wild pointer means that the position pointed to by the pointer is unknown (random, incorrect, and without explicit restrictions)
Question: what causes the wild pointer? The answers are 1, 2 and 3
1. Pointer uninitialization will cause the problem of wild pointer
#include<stdio.h> int main() { //p here is a wild pointer int *p;//p is a local pointer variable. If the local variable is not initialized, it defaults to a random value *p = 20;//Illegal access to memory return 0; }
2. Cross border visits can cause problems
#include<stdio.h> int main() { int arr[10] = { 0 }; int*p = arr; int i = 0; for (i = 0; i <= 10; i++) { *p = i; p++; //When the range pointed to by the pointer exceeds the range of array arr, p is a wild pointer } return 0; }
3. The release of the space pointed to by the pointer will cause the problem of wild pointer
#include<stdio.h> int* test() { int a = 10; return &a;//a the function space will be released } int main() { int* p = test(); *p = 20; return 0; }
How to avoid wild pointer? The answers are 1, 2, 3 and 4
- Pointer initialization
eg; #include<stdio.h> int main() { int *p = NULL;//When you don't know what address p should initialize, it is directly initialized to NULL int a = 10; int *ptr = &a;//Know the initialization value clearly and initialize directly }
- Be careful that the pointer is out of bounds
The C language itself will not check the cross-border behavior of data, so we should ensure that it will not cross-border - Pointer to space release is set to NULL immediately
When the space pointed to by the pointer no longer belongs to me and can no longer be used, we should immediately set a spatial variable as a null pointer, so as to avoid the emergence of wild pointers - Check the validity of the pointer before use
When we initialize the pointer variable to a valid address, we can use it, but if we initialize a null pointer, we can't use it, or we can judge. If it is not equal to the null pointer, we can use it, otherwise we don't need it.
#include<stdio.h> int main() { int a = 10; int *ptr = &a;//Valid address int *p = NULL;//Initializes a null pointer and cannot use it if (p! = NULL)//If it is not equal to null, use it; otherwise, do not use it. *p = 10; }
Pointer operation
Pointer + - integer
Pointer pointer
Pointer relational operation: pointer comparison size
Example of pointer ± integer
#define N_VALUES 5 float values[N_VALUES]; float *vp; //Pointer + - integer; Relational operation of pointer for (vp = &values[0]; vp < &values[N_VALUES];) { *vp++ = 0; }
#include<stdio.h> int main() { int arr[10] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; //A pointer variable points to its first element int* p = arr; //A pointer variable points to its last element int *pend = arr + 9;//Arr array name, arr+9: first element address + 9, / / pend=10 while (p <= pend)//Perform pointer relation operation { printf("%d\n",*p); p++;//Perform the + - integer operation of the pointer } return 0; }
#include<stdio.h> int main() { int arr[10] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; printf("%d\n", &arr[9]-&arr[0]); return 0; }
Note: 1 Pointer - the pointer gets the number of elements between two pointers
2. Premise of pointer and pointer subtraction: two pointers point to the same space
Using the counter method to find the string length
#include<stdio.h> int my_strlen(char* str) { int count = 0; while (*str != '\0') { count++; str++; } return count; } int main() { //strlen() finds the length of the string //recursion int len=my_strlen("abc");//Pass the string parameter to this my_strlen does not pass abc, but the address of the first character a printf("%d\n", len);//3 return 0; }
Find the length of the string by subtracting the pointer from the pointer
#include<stdio.h> int my_strlen(char* str) { char* start = str;//str assignment: put str pointer into a start pointer while (*str != '\0') { str++; } return str - start;//Pointer pointer } int main() { //strlen() finds the length of the string //recursion int len = my_strlen("abc");//Pass the string parameter to this my_strlen does not pass abc, but the address of the first character a printf("%d\n", len);//3 return 0; }
Pointer relational operation: pointer comparison size
for (vp = &values[N_VALUES]; vp > &values[0];) { *--vp = 0; }
This is after simplifying the code
for (vp = &values[N_VALUES - 1]; vp >= &values[0]; vp--) { *vp = 0; }
- In fact, it can successfully complete the task on most compilers, but we should avoid it because the C language standard does not guarantee its feasibility.
- C language standard stipulates:
- A pointer to an array element is allowed to be compared with a pointer to the memory location after the last element of the array, but it is not allowed to be compared with a pointer to the memory location before the first element.
Pointers and arrays
What is the array name?
A: the array name is the address of the first element of the array. Be sure to remember!
Related example 1
#include<stdio.h> int main() { int arr[10] = { 0 }; printf("%p\n", arr);//arr: array name; The array name is the address of the first element of the array printf("%p\n", &arr[0]);//arr[0]: the first element of the array; //Print result: screenshot (5) //The print result is the same, so it can also be explained that the array name is the address of the first element of the array return 0; }
Related example 2
#include<stdio.h> int main() { int arr[10] = { 0 }; int *p = arr;//The array name is the address of the first element of the array int i = 0; for (i = 0; i < 10; i++) { printf("%p<==>%p\n", &arr[i], p + i);//Look at the screenshot (6) of the print result. It can be seen that p+i generates the address of the element with the subscript i *(p + i) = i;//p+i is the address with subscript i, and then dereference. Find the element with subscript i and put it in } for (i = 0; i < 10; i++) { printf("%d ", *(p + i));//Print out each element 0 1 2 3 4 5 6 7 8 9 } return 0; }
Further understand that the array name is the address of the first element of the array
Example:
int main() { int arr[10] = { 1,2,3,4,5,6,7,8,9,10 }; int *p = arr;//Array name printf("%d\n", 2[arr]);//3 printf("%d\n", arr[2]);//3 //arr[2]-->*(arr+2)-->*(2+arr)-->2[arr] printf("%d\n", p[2]);//3 //p[2]--->*(p+2) //[] is an operator, and 2 and arr are two operands //arr[2] is equivalent to * (arr+2) is equivalent to * (p+2) is equivalent to * (2+p) is equivalent to * (2+arr): all are the third element //2[arr] is equivalent to * (2+arr) return 0; }
Secondary pointer
int main() { int a = 10; int *pa = &a;//pa is a pointer variable, which is also a first-order pointer, * indicates that pa is a pointer, and int indicates that a pointed to by pa is an integer int* *ppa=&pa;//PA is also a variable, &pa fetches the starting address of PA in memory //The * in front of ppa indicates that ppa is a pointer, which points to pa. because the type of PA is int *, an int * is written in front of it. The two stars can be separated or put together. There is no mandatory requirement in syntax. //At this point, ppa is a secondary pointer variable int** *pppa=&ppa;//&PPA fetches the address of the secondary pointer, and PPP A is a tertiary pointer variable return 0; }
The operations of the secondary pointer are:
ppa finds pa by dereferencing the address in ppa, * ppa actually accesses PA
int b = 20;
*ppa = &b;// Equivalent to PA = & B;
**ppa first finds pa through * ppa, and then dereferences PA: PA, it finds a
**ppa = 30;
Equivalent to pa = 30;
Equivalent to a = 30;
Pointer array
Is a pointer array a pointer or an array?
A: it's an array. Is an array of pointers
int main() { int arr[10];//Integer array: an array that holds integers is an integer array char ch[5];//Character array: an array of characters is a character array //Character array: an array of characters is a character array int* parr[5];//parr is an array that holds integer pointers. It has five elements, and each element is an integer pointer. char* pch[5]; // parr is an array that stores character pointers. It has five elements, and each element is a character pointer. return 0; }