1, Array parameter, pointer parameter
When writing code, it is inevitable to pass [array] or [pointer] to the function. How to design the parameters of the function?
1. One dimensional array parameter transfer
void test(int arr[])//ok {} void test(int arr[10])//ok {} void test(int* arr)//ok {} void test2(int* arr[20])//ok {} void test2(int** arr)//ok {} int main() { int arr[10] = { 0 }; int* arr2[20] = { 0 }; test(arr); test2(arr2); return 0; }
2. Two dimensional array parameter transfer
void test(int arr[3][5])//ok {} void test(int arr[][])//no {} void test(int arr[][5])//ok {} //Summary: for the design of two-dimensional array parameters and function parameters, only the first [] number can be omitted. //Because for a two-dimensional array, you can't know how many rows there are, but you must know how many elements there are in a row. //This is convenient for calculation. void test(int *arr)//no {} void test(int* arr[5])//no {} void test(int (*arr)[5])//ok {} void test(int **arr)//no {} int main() { int arr[3][5] = {0}; test(arr); }
3. Primary pointer transfer parameter
#include <stdio.h> void print(int *p, int sz) { int i = 0; for(i=0; i<sz; i++) { printf("%d\n", *(p+i)); } } int main() { int arr[10] = {1,2,3,4,5,6,7,8,9}; int *p = arr; int sz = sizeof(arr)/sizeof(arr[0]); //First level pointer p, passed to function print(p, sz); return 0; }
4. Secondary pointer transfer parameter
#include <stdio.h> void test(int** ptr) { printf("num = %d\n", **ptr); } int main() { int n = 10; int* p = &n; int** pp = &p; test(pp); test(&p); return 0; }
2, Function pointer
Let's start with a piece of code:
void test() { printf("hehe\n"); } int main() { printf("%p\n", test); printf("%p\n", &test); return 0; }
The output is two addresses, which are the addresses of the test function.
Save function address: void (*pfun1)();
Pfun1 is first combined with * to explain that pfun1 is a pointer, the pointer points to a function, the pointed function has no parameters, and the return value type is void.
Read two interesting pieces of code:
//Code 1 (*(void (*)())0)(); //Code 2 void (*signal(int , void(*)(int)))(int);
Code 1: is a function call. The address of a function in the code that converts the 0 cast type to void(*) (). Then dereference the address of 0, that is, go to the function at the address of 0. The called function has no parameters and the return type is void
Code 2: is a function declaration. The declared function name is signal. Signal has two parameters. The first is the type of int, the second is the function pointer type of void (*) (int), and the return type of signal function is still the function pointer type of void (*) (int).
Simplified code 2:
typedef void(*pfun_t)(int); pfun_t signal(int, pfun_t);
3, Function pointer array
1. Definitions
The address of the function is stored in an array, which is called the function pointer array
int (*parr1[10])();
Parr1 is first combined with [], indicating that parr1 is an array, and the contents of the array are function pointers of type int (*) ().
2. Purpose
Purpose of function pointer array: transfer table
Example: (calculator)
int add(int a, int b) { return a + b; } int sub(int a, int b) { return a - b; } int mul(int a, int b) { return a * b; } int div(int a, int b) { return a / b; } int main() { int x, y; int input = 1; int ret = 0; int(*p[5])(int x, int y) = { 0, add, sub, mul, div }; //Transfer table while (input) { printf("*************************\n"); printf(" 1:add 2:sub \n"); printf(" 3:mul 4:div \n"); printf("*************************\n"); printf("Please select:"); scanf("%d", &input); if ((input <= 4 && input >= 1)) { printf("Input operand:"); scanf("%d %d", &x, &y); ret = (*p[input])(x, y); } else printf("Incorrect input\n"); printf("ret = %d\n", ret); } return 0; }
4, Pointer to array of function pointers
The pointer to the array of function pointers is a pointer, the pointer points to an array, and the elements of the array are function pointers.
How to define?
#include<stdio.h> void test(const char* str) { printf("%s\n", str); } int main() { //Function pointer pfun void (*pfun)(const char*) = test; //Array of function pointers pfunArr void (*pfunArr[5])(const char* str); pfunArr[0] = test; //Pointer to function pointer array pfunArr ppfunArr void (*(*ppfunArr)[10])(const char*) = &pfunArr; return 0; }
5, Callback function
A callback function is a function called through a function pointer. If you pass the pointer (address) of a function as a parameter to another function, when the pointer is used to call the function it points to, we say it is a callback function. The callback function is not called directly by the implementer of the function, but by another party when a specific event or condition occurs, which is used to respond to the event or condition.
Note: void * - there is no specific type of pointer and can receive any type of address. Disadvantages: no operation, no ± integer, no dereference
First, demonstrate the use of the qsort function:
qsort:
strcmp:
//The user of the qosrt function has to implement a comparison function //Compare two integer functions int cmp_int(const void* e1, const void* e2) { return (*(int*)e1 - *(int*)e2); } //Compare structure data struct Stu { char name[20]; int age; }; int cmp_by_name(const void* e1, const void* e2) { return strcmp(((struct Stu*)e1)->name, ((struct Stu*)e2)->name); } void print_arr(int arr[], int sz) { int i = 0; for(i = 0; i < sz; i++) { printf("%d ", arr[i]); } } int main() { struct Stu s[3] = {{"Zhang San",15}, {"Li Si",30},{"Wang Wu",10}}; int arr[] = { 9,8,7,6,5,4,3,2,1,0}; int sz = sizeof(s)/sizeof(s[0]); int sz = sizeof(arr) / sizeof(arr[0]); //By name qsort(s,sz,sizeof(s[0],cmp_by_name); //in years qsort(s,sz,sizeof(s[0],cmp_by_age); qsort(arr, sz, sizeof(arr[0]), cmp_int); return 0; }
Use the callback function to simulate the implementation of qsort (bubbling)
#include <stdio.h> #include<stdlib.h> #include <string.h> void print_arr(int arr[], int sz) { int i = 0; for (i = 0; i < sz; i++) { printf("%d ", arr[i]); } } int cmp_int(const void* p1, const void* p2) { return (*(int*)p1 - *(int*)p2); } 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 BubbleSort(void* base, size_t num, size_t width, int (*cmp)(const void*e1, const void*e2)) { int i = 0; //Number of trips for (i = 0; i < num - 1; i++) { //Logarithm of comparison int j = 0; for (j = 0; j < num - i - 1; j++) { //base[j] ==> *(base+j) if (cmp((char*)base + j * width, (char*)base + (j + 1) * width) > 0) { //exchange Swap((char*)base + j * width, (char*)base + (j + 1) * width, width); } } } } void test() { int arr[] = { 9,8,7,6,5,4,3,2,1,0 }; int sz = sizeof(arr) / sizeof(arr[0]); BubbleSort(arr, sz, sizeof(arr[0]), cmp_int); print_arr(arr, sz); } int main() { test(); return 0; }