Lesson 9: pointer (the soul of C language)
-
Definition of pointer: pointer is essentially a variable, and this variable can only store one memory address (number) forever
Therefore, the technical term corresponding to this variable is called pointer variable
Through the address saved by the pointer variable, you can access this memory area arbitrarily (read, view, write, modify)
The memory area pointed to by the pointer can hold a number, which has a data type
-
Syntax format of pointer variable definition:
a) Writing form 1:
int * variable name;
For example: int * pa// Define a pointer variable pab) Writing form 2:
int * variable name;
For example: int* pa// Define a pointer variablec) Writing form 3:
For example: int *pa// Define a pointer variableSemantics: both define a pointer variable pa, which can store the first address of a memory area in the future
That is, the pointer variable pa itself will allocate memory, but its corresponding memory is used to store the first address of other memory areas
This procedure points to a memory area
And the memory area corresponding to the first address saved by the pointer variable stores an int type data
That is, the data type is not used for pointer variables, but for the memory pointed to by pointer variablesRemember:
The memory space allocated by the pointer variable is related to the computer hardware:
In 32-bit system, an address value is 32 bits and 4 bytes, so the memory size of the corresponding pointer variable is always 4 bytes
In 64 bit system, an address value is 64 bits and 8 bytes, so the memory size of the corresponding pointer variable is always 8 bytes
So the pointer variable has no data typeFor example:
char *pa; // Define the pointer variable PA of character type. The memory corresponding to PA is 4 bytes, and the data type of memory pointed to by PA
//It is a char type. In the future, the memory it points to can only store a char type number, and the corresponding memory is 1 byteshort *pb; // The pointer variable Pb of character type is defined. The memory corresponding to Pb is 4 bytes, and the data type of memory pointed to by Pb
//It is of short type. In the future, the memory it points to can only store a number of short type, and the corresponding memory is 2 bytesQ: how much memory does the pointer variable occupy?
A: it depends on the size of the saved address, which is related to the computer hardware:
32-bit system, an address value of 32 bits, 4 bytes
64 bit system, one address value 64 bits, 8 bytesConclusion:
The memory space allocated by the pointer variable is 4 bytes or 8 bytes, so the pointer variable itself has no data type
Only the number stored in the memory area it points to has a data type, so int is not used for pointer variables
It's for the number saved in the memory area pointed to by the pointer variabled) Continuously define pointer variable form:
int *pa, *pb; // Define two pointer variables
int *pa, pb; //pa is a pointer variable, while Pb is a common int type variable
e)Remember: if the pointer variable is not initialized after it is defined,This pointer variable holds an address value that is random
That is, the pointer variable points to any memory area, which is quite dangerous because this block of memory area
This is not the memory legally allocated to you by the operating system. This pointer variable is a wild pointer!
- Pointer variable initialization is carried out by taking the address &:
int a = 250; // Allocate 4 bytes of memory space to store 250 numbers, which are of type int
int *pa = &a; // Define a pointer variable, that is, allocate a 4-byte memory space (provided that it is 32 bits)
Save the first address of the memory space corresponding to variable a
Commonly known as pa pointing to a
Be sure to have a memory map in your mind!
char b = ‘A’; // Allocate 1 byte memory space to store the ASCII code of character a
int *pb = &b; // Define the pointer variable, allocate 4 bytes of memory space, and then save the first address of variable B, Pb for short, and point to B
Note: the data type int and char specified by the pointer variables pa and pb are not for them, but for a and b!
Q:
Once the first address of the memory area pointed to is obtained through the pointer variable, how to use the pointer variable
What is the so-called desire for the memory area pointed to, that is, read, view or write modify the memory area pointed to?
Answer: through the dereference operator:*
- Dereference operator (also known as target operator):*
Function: read view or write modify the memory area pointed to through pointer variables
Syntax format: * pointer variable = fetch target
For example:
char a = 100;
char *pa = &a;
Or:
char a = 100;
char *pa = NULL;
pa = &a;
//Print the memory data that pa points to a
printf("%d\n", *pa); //100
//Modify the memory data that pa points to a
*pa = 10; // As a result, the memory of variable a changes from 100 to 10
Conclusion: sizeof (pointer variable name) = 4 (always equal to 4 bytes)
Reference code: pointer.c
/*Pointer demonstration*/ #include<stdio.h> int main(void) { //Define initialization character variables and allocate 1 byte of memory char a ='A'; //Define the initialization pointer variable PA, which points to a char *pa = &a; printf("&a = %p,pa = %p,&pa= %p\n",&a,pa,&pa); //Print the addresses of variable a, pointer variable pa and pointer variable itself printf("sizeof(a) = %d,sizeof(pa)=%d\n",sizeof(a),sizeof(pa)); //Memory occupied by print variable a and pointer variable //Get the value of a through pa printf("%hhd,%c\n",*pa,*pa); //Modify the value of a by pa *pa = 'B'; printf("%hhd,%c\n",*pa,*pa); printf("%hhd,%c\n",a,a); return 0; }
-
Special pointer:
Null pointer and wild pointera) Null pointer:
The NULL pointer variable holds a NULL address, which is represented by NULL. In fact, it is the address numbered 0
Null pointers cannot be accessed at will, otherwise the program will crash!For example:
int *pa = NULL;
printf("the data saved at the 0 address pointed to by pa is%#x\n", * pa);
*pa = 250; // Write data to 0 address 250be careful:
The global pointer variable is not initialized. Similarly, gcc assigns a null addressb) Field pointer:
Uninitialized pointer variable (local pointer variable), which holds a random address and points to an invalid memory
Because this memory area is not allocated to you by the operating system, if you illegally access the wild pointer
It will also cause the program to crash!
int *pa; //pa is the wild pointer
printf("the data saved at the 0 address pointed to by pa is%#x\n", * pa);
*pa = 250; // Write data to 0 address 250c) Remember:
Programming specification (formula) of actual development code
If you define a pointer variable, you don't know who it points to at first. You must not initialize it, otherwise it becomes a wild pointer
Therefore, it is required to initialize the NULL pointer to NULL at this time. Once it is initialized to NULL, it will be used later in the program
Always remember to make a safe judgment on the pointer variable to judge whether it is NULL. If it is NULL, let the program end
Or the function returns. If it is a valid address, the program can continue to operate through the pointer variableFor example:
int *pa; //It's not recommended. It's very dangerous //Safety practices: int *pa = NULL; //Assign to null pointer // If you forget to assign a value to pa here, pa is still null, but a good coding rule is to make a security judgment before accessing the pointer; if(NULL == pa) { printf("pa Pointer to null,Unable to continue access.\n"); return -1 perhaps exit(0); //Function return or program exit } else { printf("pa Point to a valid memory,Can continue to visit\n"); printf("%d\n", *pa); *pa = 250; } //Safety practices: int *pa = NULL; //Initialize to null pointer int a = 250; pa = &a; //Let pa point to a, and pa saves the first address (valid address) of variable a if(NULL == pa) { printf("pa Pointer to null,Unable to continue access.\n"); return -1 perhaps exit(0); //Function return or program exit } else { printf("pa Point to a valid memory,Can continue to visit\n"); printf("%d\n", *pa); *pa = 251; }
Reference code: pointer.c
/*Pointer encoding specification*/ #include<stdio.h> #include<stdlib.h> int main(void) { int *pa = NULL; //Safety practices int a =250; pa = &a; // pa points to a and saves the first address (valid address) of a variable //Safety judgment must be made if(NULL == pa){ printf("pa Null pointer,Cannot access\n"); exit(0); //End the program now }else{ printf("pa Is a valid pointer.\n"); *pa = 520; printf("a = %d\n",*pa); } //2. No direction int *pb = NULL ; //Safety practices //Safety judgment must be made if(NULL == pb){ printf("pb Null pointer,Cannot access\n"); exit(0); //End the program now }else{ printf("pb Is a valid pointer.\n"); *pb = 520; printf("a = %d\n",*pb); } return 0; }
-
Pointer operation (core and pit dad)
a) The pointer can add and subtract from an integer, which is called address operation for short
Remember: the calculation result is related to the variable data type pointed to by the pointerb) Pointer calculation formula:
- char/unsigned char pointer + 1 indicates the actual address + 1
For example:
char *pa = 0x1000; // Suppose PA points to 0x1000
pa++; //pa=0x1001- The short/unsgined short pointer + 1 indicates the actual address + 2
short *pa = 0x1000; // Suppose PA points to 0x1000
pa++; //pa=0x1002 - int/unsigned int /long/unsigned long pointer + 1, indicating the actual address + 4
long *pa = 0x1000; // Suppose PA points to 0x1000
pa++; //pa=0x1004
Reference code: pointer2.c
/*Pointer operation*/ #include<stdio.h> int main(void) { char a = 'A'; char *pa = &a; printf("pa = %p\n",pa); pa++; printf("pa = %p\n",pa); unsigned short b = 250; unsigned short *pb = &b; printf("pb = %p\n",pb); pb++; printf("pb = %p\n",pb); long c = 520; long *pc = &c; printf("pc = %p\n",pc); pc++; printf("pc = %p\n",pc); return 0; }
-
Pointers and arrays (I used to study pointers and variables)
a) Review array related content
Definition array: int a[4] = ;
Memory distribution diagram: see pointer and array.pngConclusion:
-
The array name is the first address of the array,
It is also equal to the first address of the first element, that is, a = & A [a]. The array name is also a pointer in essence, but the address saved by this pointer is
Fixed, unlike pointer variables, the saved address can be modifiedFor example:
int a[4] = {'A', 'B', 'C', 'D'};
int c = 250; // The array name cannot be modified
A = & C / / absolutely not. gcc reports an error. The array name a cannot be modified. It has a fixed address. / / the pointer variable can be modified
int pa = NULL;
int a =250;
int b = 520;
pa = &a ; // PA points to a
pa = &b; // Change PA to point to B
&a[4] - &a[1] = 3; // That is, any two element addresses are subtracted to obtain the number of separated elements, and the value of time address difference is obtained by taking the number of elements sizeof (data type) -
&A [2] is the first address of the second element
-
a+2 is also the first address of the second element
-
*&A [2] get the value of the second element
-
*(a +2) also means to obtain the value of the second element
-
&A [2] - a = a + 2 - a = 2 elements, indicating a difference of 2 elements between the 2nd element and the 0th element. The actual address difference is 8 bytes = 2 elements * int
-
Pointer and array relationship formula:
int a[5] = ;
int *pa = a; // Define a pointer variable to hold the first address of the entire array
At this moment, the memory map immediately appears in my mind!
The ith element address = & A [i] = & PA [i] = a + I = PA + I
The ith element value = a[i] = pa[i] = *(a+i) = *(pa+i)
be careful:
a++ ; // illegal
pa++; // legitimate
*a++; // illegal
pa++; // Legal, first calculate PA, then calculate PA plus 1
Remember:
Formula for finding the number of array elements:
sizeof(a) /sizeof(a[0]) = number of elements// legitimate
sizeof(pa) /sizeof(pa[0]); // Illegal because sizeof (PA) is always equal to 4
Reference code pointer_array.c
/*Pointer and Array Formula demonstration*/ #include<stdio.h> int main(void) { int a[] = ; int *pa = a; //pa points to a and saves the first address of the array int len = sizeof(a)/sizeof(a[0]); //Get the number of elements //int len = sizeof(pa)/sizeof(pa[0]); // Error: sizeof(pa)/sizeof(pa[0]) = 4/4 = 1 //Writing 1: //Print element values for(int i =0;i<len;i++){ printf("The first%d The values of the elements are:%d %d %d %d\n",i,a[i],pa[i],*(a+1),*(pa+1)); } //Modify its value and expand it by 100 times for(int i =0;i<len;i++) { pa[i] *=10; *(pa+i) *=10; } //Print element values for(int i = 0;i<len;i++){ printf("The first%d The values of the elements are:%d %d %d %d\n",i,a[i],pa[i],*(a+i),*(pa+i)); } //Writing 2: for(pa = a;pa<a+len;pa++){ printf("The element values are:%d\n",*pa); //Print each element } for(pa =a;pa<a+len;){ *pa++ *=10; //Modify element value } for(pa=a;pa<a+len;pa++){ printf("The element values are:%d\n",*pa); //Print each element value } return 0; }
- Pointer and function (I have mastered the relationship between pointer and variable, pointer and array)
The pointer is used as the formal parameter of the function (the formal parameter is a pointer variable)
result:
The function can do whatever it wants to point to the memory through the formal parameter pointer variable (arbitrarily read its value or modify its value)
Reference code: swap.c/*Pointer as formal parameter of function*/ #include<stdio.h> /*Define swap function*/ void swap(int *pa,int *pb) //pa = &a,pb =&b; { int c = *pa; *pa = *pb; *pb = c; } /*Define a function to clear a bit of a data to 0*/ void clear_bit(int *pc,int bit){ *pc &= ~(1<<bit); //Directly modify the memory of argument variable c } /*Define a bit position 1 function of a data*/ void set_bit(int *pc,int bit){ *pc |= (1<<bit); //Directly modify the memory of argument variable c } int main(void) { int a =100; int b =200; swap(&a, &b); //Call swap to realize data exchange, and pass the first address of argument variables a and b to swap function printf("a = %d,b = %d\n",a,b); int c =0x55; //01010101 clear_bit(&c,0); //Clear bit 0 of variable c to 0 printf("c = %#x\n",c); set_bit(&c,0); //Position 0 of variable c to 1 printf("c = %#x\n"); return 0; }
b) Pointer as the return value of the function
result:
It is a function that returns a pointer. This kind of function is also called pointer function
The variable corresponding to the address returned by the pointer function. Pay attention to its type,
Remember:
The address of local non static variables cannot be returned, otherwise a wild pointer will be returned, and the addresses of other three types of variables can be returned
Format of pointer function declaration and definition: pointer variable = return value data type * function name (formal parameter table)
Reference code: pointer_function.c
/*Pointer function demonstration*/ #include<stdio.h> int g_a =520; //Global non static variable static int g_b =520; //Global static variable /*Define pointer function A and return A pointer of type int in the future*/ int *A(void){ int a = 250; //Local nonstatic variable static int b = 250; //Local static variable //return &a; // Returns the address of a local non static variable. No, it will return a wild pointer in the future //return &b; // Returns the address of a local static variable. You can //return &g_ a; // Returns the address of a global non static variable. You can return &g_b; //Returns the address of a global static variable. You can } int main(void) { int *p = NULL; p = A(); //Call function A, and then use p to receive the variable address returned by function A printf("%d\n",*p); printf("%p\n",p); *p = 30000; //Modify the memory value pointed to. If you illegally access the wild pointer, it will crash directly printf("%d\n",*p); return 0; }