当前位置:网站首页>Deep analysis of C language pointer
Deep analysis of C language pointer
2022-07-06 08:32:00 【Finally - null】
Make a little progress every day , Persistence makes a big difference !!!
Catalog
4. Array parameters , The pointer passes the parameter
7. A pointer to an array of function pointers
9. Pointer and array written test exercises
Preface :
We have learned some simple knowledge about pointers before :
1. The pointer is the address , Is the number that identifies the memory space .
2. Pointer variable is the address used to store the variable , Variables can be found through pointers and stored in memory .
3. The size of the pointer accounts for 4/8 Bytes (32/64).
4. The type of pointer determines how many bytes are skipped when the pointer adds or subtracts integers , Several bytes can be accessed when dereferencing .
5. The operation of the pointer : The number of intermediate elements is obtained by subtracting the pointer from the pointer .
Next, let's continue to explore more about pointers , thorough C Language pointer related content .
1. Character pointer
char*
First use :
Memory layout :
Second use :
Memory layout :
An interview question about character pointer :
#include<stdio.h> int main() { char* p1 = "abcdef"; char* p2 = "abcdef"; char arr1[] = "abcdef"; char arr2[] = "abcdef"; if (p1 == p2) printf("p1 == p2\n"); else printf("p1 != p2\n"); if (arr1 == arr2) printf("arr1 == arr2\n"); else printf("arr1 != arr2\n"); return 0; }
Explanation of the reason : because "abcdef" Is a constant string , Put it in the character constant area , Cannot be modified , So there is only one copy in memory , therefore p1 and p2 Are stored first characters a The address of , and arr1 and arr2 Open up two different spaces in the memory to store "abcdef", So the address is different .
2. Pointer array
Concept : reasoning from analogy
Shape array , Used to store shaping numbers , The type of each element is int
A character array , An array used to store characters , The type of each element is charPointer array , An array of pointers , The type of each element is data type *
application : Print a two-dimensional array
#include<stdio.h> int main() { int arr1[] = { 1,2,3,4,5 }; int arr2[] = { 2,3,4,5,6 }; int arr3[] = { 3,4,5,6,7 }; int* parr[3] = { arr1,arr2,arr3 }; //parr Is an array of integer pointers , The type of each element is int* int i = 0; for (i = 0; i < 3; i++) { int j = 0; for (j = 0; j < 5; j++) { printf("%d ", *(*(parr + i) + j)); } printf("\n"); } return 0; }
Memory layout :
3. Array pointer
Concept : reasoning from analogy :
Shaping the pointer , Address used to store shaping elements int*p;
Character pointer , Address used to store character elements char*p;Array pointer , The address used to store the array data type (*p)[X];
int main() { int arr[10] = { 1,2,3,4,5,6,7,8,9,10 }; int(*p)[10] = &arr; //p The first and * Combined description p Is a pointer variable , Then point to a size of 10 Array of elements return 0; }
notes :& The array name represents the address of the array
The use of array pointers : Improper use
#include<stdio.h> int main() { int arr[10] = { 1,2,3,4,5,6,7,8,9,10 }; int(*p)[10] = &arr; int i = 0; for (i = 0; i < 10; i++) { printf("%d ", *(*p + i));// Equivalent to arr[i] //*p Get the address of the first element of the array +i Get the address of the next element ,* Get this value } return 0; }
Print one-dimensional arrays using array pointers , More trouble , Not recommended .
Print 2D array
#include<stdio.h> void print(int(*p)[5], int row, int col) { int i = 0; for (i = 0; i < 3; i++) { int j = 0; for (j = 0; j < 5; j++) { printf("%d ", *(*(p + i) + j)); //*(p+i) Get the address of the first element of each line of the two-dimensional array +j Dereference to get every element . // Equivalence and p[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} }; print(arr, 3, 5); // The array name represents the address of the first element of the array , The first element of a two-dimensional array is a one-dimensional array // So use the array pointer to accept , The address where the array is stored . return 0; }
summary :
int arr[5]; int *parr1[10]; int (*parr2)[10]; int (*parr3[10])[5];
int arr[5] : It's an array of integers , The array has five elements , The type of each element is int;
int* parr1[10]: It's an array of Pointers , Array has 10 Elements , The type of each element is int*;
int(*parr2)[10]: It's an array pointer , The array pointed to by this pointer is 10 Elements , The type of each element is int
The type of this pointer variable is int(*)[10];
int(*parr3[10])[5]:parr3 The first and [] The combination shows that this is an array , The array has 10 Elements , The type of each element is int(*)[5]( Array pointer );
4. Array parameters , The pointer passes the parameter
1. Array parameters
One dimensional array parameters :
void test1(int arr[])//ok {} void test1(int arr[10])//ok {} void test1(int*arr)//ok {} void test2(int*arr[20])//ok {} void test2(int**arr)//ok arr2 Is a pointer accepted with a secondary pointer {} int main() { int arr1[10] = { 0 }; int* arr2[20] = { 0 }; test1(arr1); test2(arr2); return 0; }
Two dimensional array parameters :
void test(int arr[3][5])//ok {} void test(int arr[][])//err Two dimensional array parameter lines can be omitted , Columns cannot be omitted {} void test(int arr[][5])//ok {} void test(int(*arr)[5])//ok The array name represents the address of the first element , The first element of a two-dimensional array represents the first row of the array , // Therefore, you can use array pointers to accept {} void test(int**arr)//err The secondary pointer variable is the address where the primary pointer variable is stored {} void test(int*arr[5])//err Pointer array is used to accept pointers , Cannot accept the address of an array {} int main() { int arr[3][5] = { 0 }; test(arr); return 0; }
2. The pointer passes the parameter :
First level pointer parameter transfer
void test(int* p)//ok {} int main() { int a = 10; int* p = &a; test(p); return 0; }
The secondary pointer transmits parameters :
void test(int** pp) {} int main() { int a = 10; int* p = &a; int** pp = &p; test(pp);//ok test(&p);//ok return 0; }
5. A function pointer
The address used to store the function
#include<stdio.h> int Add(int a, int b) { return a + b; } int main() { int a = 10; int b = 20; int ret = Add(a, b); printf("%p\n", Add); printf("%p\n", &Add); return 0; }
How to save the address of a function ?
#include<stdio.h> int Add(int a, int b) { return a + b; } int main() { int (*pf)(int, int) = &Add;//Add; //pf It's a function pointer (int,int) The type of function argument int ret = (*pf)(2, 3); // Equivalence and (pf)(2,3); printf("%d\n", ret); return 0; }
Let's have a deep understanding of function pointers through two pieces of code :
The second piece of code is complex , But there is the same code , A function pointer , So you can use typedef Rename simplified code
typedef void(*pf_t)(int); int main() { void (*signal(int, void(*)(int)))(int); pf_t signal(int pf_t); return 0; }
The purpose of the function pointer :
Simulate the implementation of a calculator :
#include<stdio.h> void menu() { printf("*************************\n"); printf("***1.Add 2.Sub ***\n"); printf("***3.Mul 4.Div ***\n"); printf("****** 0.exit ********\n"); printf("*************************\n"); } int Add(int x, int y) { return x + y; } int Sub(int x, int y) { return x - y; } int Mul(int x, int y) { return x * y; } int Div(int x, int y) { return x / y; } int main() { int a = 0; int b = 0; int ret = 0; int input = 0; do { menu(); printf(" Please select :"); scanf("%d",&input); switch (input) { case 0: printf(" Exit calculator \n"); break; case 1: printf(" Please enter two operands :"); scanf("%d%d", &a, &b); ret = Add(a, b); printf("%d\n", ret); break; case 2: printf(" Please enter two operands :"); scanf("%d%d", &a, &b); ret = Sub(a, b); printf("%d\n", ret); break; case 3: printf(" Please enter two operands :"); scanf("%d%d", &a, &b); ret = Mul(a, b); printf("%d\n", ret); break; case 4: printf(" Please enter two operands :"); scanf("%d%d", &a, &b); ret = Div(a, b); printf("%d\n", ret); break; default: printf(" Incorrect input , Please re-enter :\n"); break; } } while (input); return 0; }
When we implement calculators , There are many redundant codes in the code , How to avoid these problems ?
Next, solve the problem of repetition in the code by using function pointers :
Improved code :
#include<stdio.h> void menu() { printf("*************************\n"); printf("***1.Add 2.Sub ***\n"); printf("***3.Mul 4.Div ***\n"); printf("****** 0.exit ********\n"); printf("*************************\n"); } int Add(int x, int y) { return x + y; } int Sub(int x, int y) { return x - y; } int Mul(int x, int y) { return x * y; } int Div(int x, int y) { return x / y; } void Calc(int(*pf)(int, int)) { int a = 0; int b = 0; int ret = 0; printf(" Please enter two operands :"); scanf("%d%d", &a, &b); ret = pf(a, b); printf("%d\n", ret); } int main() { int input = 0; do { menu(); printf(" Please select :"); scanf("%d", &input); switch (input) { case 0: printf(" Exit calculator \n"); break; case 1: Calc(Add); break; case 2: Calc(Sub); break; case 3: Calc(Mul); break; case 4: Calc(Div); break; default: printf(" Incorrect input , Please re-enter :\n"); break; } } while (input); return 0; }
Pass the address of the function , Parameters are accepted with function pointers , Then call this function through the function pointer .
6. Function pointer array
Is an array , An array used to store function addresses
int Add(int x, int y) { return x + y; } int Sub(int x, int y) { return x - y; } int Mul(int x, int y) { return x * y; } int Div(int x, int y) { return x / y; } int main() { // How to store the addresses of the above four functions into a function pointer array ? int(*pf[4])(int, int) = { Add,Sub,Mul,Div }; //pf The first and [] The combination shows that this is an array , Array has 4 Elements , The type of each element is //int(*)(int,int) A function pointer return 0; }
Since you can store the address of the function through the function pointer array , So how to use function pointer array to realize calculator ?
#include<stdio.h> void menu() { printf("*************************\n"); printf("***1.Add 2.Sub ***\n"); printf("***3.Mul 4.Div ***\n"); printf("****** 0.exit ********\n"); printf("*************************\n"); } int Add(int x, int y) { return x + y; } int Sub(int x, int y) { return x - y; } int Mul(int x, int y) { return x * y; } int Div(int x, int y) { return x / y; } int main() { int input = 0; int a = 0; int b = 0; int ret = 0; int(*parr[5])(int,int) = { 0,Add,Sub,Mul,Div }; do { menu(); printf(" Please select :"); scanf("%d", &input); if (input == 0) { printf(" Exit calculator \n"); } else if (input >= 1 && input < 5) { printf(" Please enter two operands :"); scanf("%d%d", &a, &b); ret = parr[input](a, b); printf("%d\n", ret); } else { printf(" Input error , Please re-enter \n"); } } while (input); return 0; }
When using function pointer array, it simplifies the code , And it provides great convenience when modifying the code later
7. A pointer to an array of function pointers
It's a pointer , The address used to store the function pointer array :
int Add(int x, int y) { return x + y; } int Sub(int x, int y) { return x - y; } int Mul(int x, int y) { return x * y; } int Div(int x, int y) { return x / y; } int main() { // Function pointer array int(*pfarr[4]) = {Add,Sub,Mul,Div }; //ppfArr Is a pointer to an array of function pointers //ppfArr The first and * combination , explain ppfArr It's a pointer ,[4] Indicating the pointer // The array pointed to has 4 Elements , The type of each element is int(*)(int,int) int(*(*ppfArr)[4])(int, int) = &pfarr; return 0; }
8. Callback function
Above, when we use function pointer to realize calculator , Wrote a Calc Function of , Actually Calc It's a callback function , How to understand callback function ?
A callback function is a function called through a function pointer . If you put a pointer to a function ( Address ) Pass as a parameter to another function , When this pointer is used to call the function it points to , Let's just say this is a callback function . The callback function is not called directly by the function's implementer , It's called by another party when a particular event or condition occurs , Used to respond to the event or condition .
#include<stdio.h> void bubble_sort(int arr[], int sz) { int i = 0; for (i = 0; i < sz - 1; i++) { int j = 0; int flag = 1;// If the array to be sorted is already ordered , And then jump out of the loop for (j = 0; j < sz - 1 - i; j++) { if (arr[j] < arr[j + 1]) { int tmp = arr[j]; arr[j] = arr[j + 1]; arr[j + 1] = tmp; flag = 0; } } if (flag == 1) { break; } } } int main() { int arr[10] = { 1,2,3,4,5,6,7,8,9,10 }; int sz = sizeof(arr) / sizeof(arr[0]); bubble_sort(arr, sz); int i = 0; for (i = 0; i < sz; i++) { printf("%d ", arr[i]); } return 0; }
Sort in descending order :
When we want to sort a complex object , Obviously, bubble sorting is not applicable , So how to sort a complex object ?
Let's introduce a library function qsort()
#include<stdlib.h>// Include header file int main() { void qsort(void* base, // Start position to be sorted size_t num, // Number to be sorted size_t width, // The size of the element to be sorted , Unit is byte int( * cmp)(const void* e1, const void* e2)); // Is a function pointer , The function pointed to by this function pointer has two parameters ,e1,e2, The function return type is int. return 0; } //int cmp(const void* e1, const void* e2) //Return Value Description //< 0 e1 less than e2 //0 e1 equivalent to e2 //> 0 e1 greater than e2
Use library functions qsort Sort integer array :
#include<stdlib.h> #include<stdlib.h> int cmp_int(const void* e1, const void* e2) { return *(int*)e1 - *(int*)e2; } int main() { int arr[10] = { 9,8,7,6,5,4,3,2,1,0}; int sz = sizeof(arr) / sizeof(arr[0]); qsort(arr, sz, sizeof(arr[0]), cmp_int); int i = 0; for (i = 0; i < sz; i++) { printf("%d ", arr[i]); } return 0; }
The default is ascending :
Use library functions to sort complex objects :
Sort according to one's age :
#include<stdio.h> #include<stdlib.h> struct stu { int age; char name[20]; }; int by_cmp_age(const void* e1, const void* e2) { return ((struct stu*)e1)->age - ((struct stu*)e2)->age; } int main() { struct stu s[3] = { {18,"zhangsan"},{20,"lisi"},{19,"wangwu"} }; int sz = sizeof(s) / sizeof(s[0]); qsort(s, sz, sizeof(s[0]), by_cmp_age); int i = 0; for (i = 0; i < sz; i++) { printf("%s %d ", s[i].name, s[i].age); printf("\n"); } return 0; }
Sort by a person's name
#include<stdio.h> #include<stdlib.h> #include<string.h> struct stu { int age; char name[20]; }; int by_cmp_name(const void* e1, const void* e2) { return strcmp(((struct stu*)e1)->name, ((struct stu*)e2)->name); } int main() { struct stu s[3] = { {18,"zhangsan"},{20,"lisi"},{19,"wangwu"} }; int sz = sizeof(s) / sizeof(s[0]); qsort(s, sz, sizeof(s[0]), by_cmp_name); int i = 0; for (i = 0; i < sz; i++) { printf("%s %d ", s[i].name, s[i].age); printf("\n"); } return 0; }
Simulate the implementation of library functions qsort:
Implement library functions qsort One of the arguments to is the function pointer , The function parameter pointed to by the function pointer is void* Pointer to type .
Why are they used void* Pointer to type ?
So let's talk about that void* The function of pointer
Simulation Implementation qsort
#include<stdio.h> #include<string.h> struct stu { int age; char name[20]; }; int by_cmp_name(const void* e1, const void* e2) { return strcmp(((struct stu*)e1)->name, ((struct stu*)e2)->name); } void Swap(char* buf1, char* buf2, int width) { int i = 0; for (i = 0; i < width; i++) { char tmp = *buf1; *buf1 = *buf2; *buf2 = tmp; buf1++; buf2++; } } void bubble_qsort(void* base, int sz, int width, int(*cmp)(const void* e1, const void* e2)) { int i = 0; for (i = 0; i < sz - 1; i++) { int j = 0; int flag = 1; for (j = 0; j < sz - 1 - i; j++) { // Strongly convert the incoming data type to char* Pointer types , Then compare byte by byte if (cmp((char*)base + j * width, (char*)base + (j + 1) * width) > 0) { Swap((char*)base + j * width, (char*)base + (j + 1) * width, width); flag = 0; } } if (flag == 1) { break; } } } int main() { struct stu s[3] = { {18,"zhangsan"},{20,"lisi"},{19,"wangwu"} }; int sz = sizeof(s) / sizeof(s[0]); bubble_qsort(s, sz, sizeof(s[0]), by_cmp_name); int i = 0; for (i = 0; i < sz; i++) { printf("%s %d ", s[i].name, s[i].age); printf("\n"); } return 0; }
9. Pointer and array written test exercises
One dimensional shaping array :
One dimensional character array : Array does not contain '\0'
szieof
strlen:
The array contains '\0'
sizeof:
strlen:
Character pointer :
sizeof:
strlen:
Two dimensional array :
summary :sizeof( Array name ), The array name represents the size of the entire array , Calculate the size of the entire array
& Array name , The array name represents the address of the entire array , besides , All array names represent the address of the first element of the array .
10. Pointer written test exercises
Test question 1 :
Question 2 :
Question 3 :
Question 4 :
Question five :
Question 6 :
Question 7 :
Question 8 :
11. summary :
The above is about right C A detailed anatomy of language pointer knowledge points , It contains all the knowledge points about the pointer and the written test questions related to the pointer , I hope I can help each other on the way to study , Common progress , Welcome to comment !!!
边栏推荐
- Deep learning: derivation of shallow neural networks and deep neural networks
- sublime text中conda环境中plt.show无法弹出显示图片的问题
- Upgrade tidb with tiup
- 【MySQL】锁
- vulnhub hackme: 1
- Let the bullets fly for a while
- Yyds dry goods inventory three JS source code interpretation eventdispatcher
- LDAP應用篇(4)Jenkins接入
- Leetcode skimming (5.29) hash table
- Use Alibaba icon in uniapp
猜你喜欢
C language - bit segment
sublime text没关闭其他运行就使用CTRL+b运行另外的程序问题
个人电脑好用必备软件(使用过)
Restful API design specification
ESP series pin description diagram summary
堆排序详解
Unified ordering background interface product description Chinese garbled
查看局域网中电脑设备
egg. JS getting started navigation: installation, use and learning
[cloud native] teach you how to build ferry open source work order system
随机推荐
Tidb backup and recovery introduction
C language custom type: struct
个人电脑好用必备软件(使用过)
Char to leading 0
JVM 快速入门
Upgrade tidb operator
【Nvidia开发板】常见问题集 (不定时更新)
Résumé des diagrammes de description des broches de la série ESP
String to leading 0
从表中名称映射关系修改视频名称
leetcode刷题 (5.31) 字符串
[research materials] 2021 Research Report on China's smart medical industry - Download attached
Chrome浏览器的crash问题
Restful API design specification
ESP系列引脚说明图汇总
[2022 Guangdong saim] Lagrange interpolation (multivariate function extreme value divide and conquer NTT)
Precise query of tree tree
Golang force buckle leetcode 1020 Number of enclaves
The mysqlbinlog command uses
【MySQL】鎖