<C Language> Pointer (below)

1. Character pointer

Character Pointer (Character Pointer) char*is a pointer variable pointing to character data.

Example of use:

int main() {
    
    
    char ch = 'w';    // 声明一个字符变量ch并赋值为 'w'
    char *pc = &ch;   // 声明一个字符指针pc并将其指向ch的地址
    *pc = 'w';        // 通过指针pc修改ch的值为 'w'
    
    char arr[] = "abcdef";  // 声明一个字符数组arr并初始化为字符串 "abcdef"
    char* p = arr;         // 声明一个字符指针p,将其指向数组arr的首地址
    
    return 0;
}

Another way to use it is as follows:

#include <stdio.h>
int main() {
    
    
    const char *pstr = "hello world.";   // 声明一个指向常量字符的指针pstr,并将其指向字符串常量"hello wrold."
    printf("%s\n", pstr);  // 输出字符串"hello world."
    *pstr = 'w';  // 尝试修改常量字符串,会导致编译错误,因为常量字符串不可修改

    printf("%c\n", *pstr);  // 尝试访问常量字符串的第一个字符,不会发生修改,输出仍为原始字符'h'

    return 0;
}

Modifying a constant string through a pointer is illegal and will result in a compilation error. Constant strings should be treated as read-only data. If you need to modify the string content, you should use a character array instead of a pointer to a constant character.

the codeconst char* pstr = "hello world.";

It is especially easy for students to think that the string is hello worldput in the character pointer pstr, but the essence of / is to put hello world.the address of the first character of the string pstrin .

What is the result below?

#include <stdio.h>
int main() {
    
    
    char str1[] = "hello world.";
    char str2[] = "hello world.";
    const char *str3 = "hello world.";
    const char *str4 = "hello world.";
    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;
}
//str1 and str2 are not same
//str3 and str4 are same
  • str1and str2are character arrays that contain the same string "hello world.".
  • str3and str4are pointers to constant characters, which also point to the same string "hello world.".

Then, the program compares the pointer values ​​of these four variables using a conditional statement, and outputs the comparison result:

  • By str1 == str2comparison, they are two different character arrays, so output "str1 and str2 are not same".
  • By str3 == str4comparison, they point to the same constant character, so output "str3 and str4 are same".

Although str1and str2have the same content, they are two different arrays, so they have different addresses in memory. Whereas str3and str4are pointers to the same string constant, they point to the same address.

If you want to compare the contents of strings rather than addresses, you should use string comparison functions strcmp(), eg strcmp(str1, str2).

2. Array of pointers

In the C language, an array of pointers refers to an array whose elements are variables of pointer type. An array of pointers can store pointers to objects of different types.

So is an array of pointers a pointer or an array?

is an array. is an array of pointers.

For example:

int main() {
    
    
    //整型数组-存放整型的数组
    int arr[10];
    //字符数组-存放字符的数组
    char arr2[5];
    //指针数组-存放指针的数组
    int *arr3[5]; //存放整型指针的数组
    char *arr4[6];//存放字符指针的数组

    return 0;
}

For example:

#include <stdio.h>
int main() {
    
    
    int a = 10;
    int b = 20;
    int c = 30;
    int d = 40;
    int e = 50;

    int *arr3[5] = {
    
    &a, &b, &c, &d, &e};//存放整型指针的数组
    int i = 0;
    for (i = 0; i < 5; i++) {
    
    
        printf("%d ", *(arr3[i]));
    }

    return 0;
}

Pointer array usage scenario: use a one-dimensional array to simulate 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 arr4[] = {
    
    4, 5, 6, 7, 8};

    int *arr[4] = {
    
    arr1, arr2, arr3, arr4};
    int i = 0;
    for (i = 0; i < 4; i++) {
    
    
        int j = 0;
        for (j = 0; j < 5; j++) {
    
    
            printf("%d ", *(*(arr + i) + j));
        }
        printf("\n");
    }

    //int i = 0;
    //for (i = 0; i < 4; i++)
    //{
    
    
    //	int j = 0;
    //	for (j = 0; j < 5; j++)
    //	{
    
    
    //		printf("%d ", arr[i][j]);
    //	}
    //	printf("\n");
    //}

    return 0;
}

Output result:

1 2 3 4 5 
2 3 4 5 6 
3 4 5 6 7 
4 5 6 7 8 

3. Array pointer

3.1 Definition of array pointer

Array pointers are pointers? Or an array?

The answer is: pointers.

We are already familiar with: Integer pointer: int * pint; A pointer that can point to integer data.

Floating-point pointer: float * pf; A pointer that can point to floating-point data. The array pointer should be: a pointer that can point to an array .

Which of the following codes is an array pointer?

int *p1[10];
int (*p2)[10];
//p1, p2分别是什么?

explain:

int (*p)[10];

p is first combined with *, indicating that p is a pointer variable, and then it points to an array of 10 integers. So p is a pointer pointing to an array, called an array pointer.

Note here: The priority of [] is higher than that of number, so () must be added to ensure that p is combined first.

int main(){
    
    
    int arr[10] = {
    
    1,2,3,4,5};
	int (* pa)[10] = &arr;//取出的是数组的地址存放到pa中,pa是数组指针变量
	char arr[5];
	char (*p1)[5] = &arr;
}

3.2 & array name VS array name

For the following arrays:

int arr[10];

arrWhat are and &arrrespectively?

We know that arr is the name of the array, and the array name represents the address of the first element of the array.

What is the &arr array name? Let's look at a piece of code:

#include <stdio.h>
int main() {
    
    
    int arr[10] = {
    
    0};
    printf("%p\n", arr);
    printf("%p\n", &arr);
    return 0;
}

The result of the operation is as follows:

000000000061FDF0
000000000061FDF0

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;
}

The output is as follows:

arr = 000000000061FDF0
&arr= 000000000061FDF0
arr+1 = 000000000061FDF4
&arr+1= 000000000061FE18

According to the above code, we found that, in fact, &arr and arr have the same value, but the meaning should be different.

In fact: &arr it represents the address of the array , not the address of the first element of the array . (experience carefully)

The type in this example &arris: int(*)[10], which is an array pointer type. The address of the array + 1, skipping the size of the entire array , so the &arr+1relative &arrdifference is 40.

3.3 Use of array pointers

How is the array pointer used?

Since the array pointer points to an array, the address of the array should be stored in the array pointer.

Example:

#include <stdio.h>
int main() {
    
    
    int arr[10] = {
    
    1, 2, 3, 4, 5, 6, 7, 8, 9, 0};
    int(*p)[10] = &arr;//把数组arr的地址赋值给数组指针变量p
    //但是我们一般很少这样写代码
    return 0;
}

Use of an array pointer:

#include <stdio.h>
void print1(int *arr, int sz) {
    
    
    int i = 0;
    for (i = 0; i < sz; i++) {
    
    
        //*(arr + i) 表示指针arr偏移i个元素后所指向的值。
        printf("%d ", *(arr + i));
    }
    printf("\n");
}

void print2(int (*p)[10], int sz) {
    
    
    int i = 0;
    for (i = 0; i < sz; i++) {
    
    
        //int (*p)[10]是数组指针,(*p)[i] 表示指针p所指向的数组的第i个元素的值。
        printf("%d ", (*p)[i]);   //*p = arr;
    }
    printf("\n");
}

int main() {
    
    
    int arr[10] = {
    
    1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
    int sz = sizeof(arr) / sizeof(arr[0]);

    print1(arr, sz);  //1 2 3 4 5 6 7 8 9 10
    print2(&arr, sz);  //1 2 3 4 5 6 7 8 9 10
    return 0;
}

print1The parameter of the function is an integer pointer, and an integer array of any size can be passed to it for printing. And print2the parameter of the function is a pointer to an array containing 10 integers, so it can only pass an integer array of size 10 to it for printing.

These two ways of writing can be used to print the elements of integer arrays, which way to choose depends on your needs and the type and size of the array you are operating on.

continue:

void print3(int arr[3][5], int r, int c) {
    
    
    int i = 0;
    for (i = 0; i < r; i++) {
    
    
        int j = 0;
        for (j = 0; j < c; j++) {
    
    
            //arr[i][j] 表示二维数组arr的第i行、第j列的元素的值。
            printf("%d ", arr[i][j]);
        }
        printf("\n");
    }
}

void print4(int (*p)[5], int r, int c) {
    
    
    //函数接受一个指向包含5个整数的数组指针p
    int i = 0;
    for (i = 0; i < r; i++) {
    
    
        int j = 0;
        for (j = 0; j < c; j++) {
    
    
            //*(*(p + i) + j) 表示指针p所指向的二维数组的第i行、第j列的元素的值。
            //p为指针 p+i表示一维数组
            printf("%d ", *(*(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}};
    print3(arr, 3, 5);  
    print4(arr, 3, 5);
    return 0;
}

Parse *(*(p + i) + j):

  1. (p + i): First, pa pointer to an array of 5 integers. Through p + ithe operation, the pointer pis offset by ibytes of integer size, that is, it points to the row of the two-dimensional array i.
  2. *(p + i): In the previous step, rows pwere offset i, so *(p + i)represents the first element of the row-th prow of the two-dimensional array pointed to by the pointer . iThis is a pointer to an integer.
  3. (*(p + i) + j): Based on the previous step, jit is the index used to offset the column. *(p + i) + jIndicates *(p + i)that in the one-dimensional array pointed to by the pointer , the byte of integer size is offset j, that is, it points to the element in the irow and column of the two-dimensional array.j
  4. *(*(p + i) + j): Finally, *(*(p + i) + j)use the pointer dereference operator *to get (*(p + i) + j)the integer value pointed to by the pointer. iThis is the value of the element at row and column in the two-dimensional array j.

After learning pointer array and array pointer, let's review and see the meaning of the following code:

int arr[5];
int *parr1[10];
int (*parr2)[10];
int (*parr3[10])[5];
  • int arr[5];This is an array of 5 integers named arr.
  • int *parr1[10];This is an array of 10 pointers to integers named parr1. It can store addresses of 10 integers.
  • int (*parr2)[10];This is a pointer to an array of 10 integers named parr2. It points to an array with 10 integers.
  • int (*parr3[10])[5];This is an array of 10 pointers to an array of 5 integers called parr3. It can store 10 pointers to an array with 5 integers.

Let's break it down int (*parr3[10])[5]and explain what it means:

  1. From the variable name parr3, we know this is an array.
  2. Continuing to the right, we see [10]that the representation parr3is an array of 10 elements.
  3. Continuing to the right, we see *that the elements representing the array are pointers.
  4. Continuing to the right, we see [5]that the pointer points to an array containing 5 integers.
  5. Finally, we have int, representing integer types in arrays.

Therefore, int (*parr3[10])[5]it can be read as: parr3is an array containing 10 elements, each element is a pointer to an array containing 5 integers.

4. Array parameters, pointer parameters

When writing code, it is inevitable to pass [array] or [pointer] to the function. How should the parameters of the function be designed?

4.1 One-dimensional array parameter passing

#include <stdio.h>
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);
}

All of the above codes are OK. arr[10]Equivalently *arr, the value in [] can be omitted. *arr[20]Equivalent to**arr

4.2 Two-dimensional array parameter passing

void test(int arr[3][5])//ok?
{
    
    }

void test(int arr[][])//ok?  err
{
    
    }

void test(int arr[][5])//ok?
{
    
    }

int main() {
    
    
    int arr[3][5] = {
    
    0};
    test(arr);
}

Summarize:

For two-dimensional array parameter passing, the design of the function parameter can only omit the first [] number. Because for a two-dimensional array, you don't need to know how many rows there are, but you must know how many elements are in one row. This is convenient for operation.

void test(int *arr)//ok?
{
    
    }

void test(int *arr[5])//ok?  err
{
    
    }

void test(int (*arr)[5])//ok?
{
    
    }

void test(int **arr)//ok? err
{
    
    }

int main() {
    
    
    int arr[3][5] = {
    
    0};
    test(arr);
}

The function test(int *arr[5])is wrong because it declares an array of 5 pointers to integers instead of one pointer to integers. function test(int **arr)is also wrong because it declares a pointer to a pointer, not a pointer to an integer or array of integers. In the main function, int *arrthe correct function declaration for the parameter should be test(int (*arr)[5])because it is a pointer to an array of 5 integers.

4.3 First-level pointer parameter passing

#include <stdio.h>
void print(int *p, int sz) {
    
    
    int i = 0;
    for (i = 0; i < sz; i++) {
    
    
        printf("%d ", *(p + i));//1 2 3 4 5 6 7 8 9 10
    }
}
int main() {
    
    
    int arr[10] = {
    
    1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
    int *p = arr;
    int sz = sizeof(arr) / sizeof(arr[0]);
    //一级指针p,传给函数
    print(p, sz);
    return 0;
}

think:

When the parameter part of a function is a first-level pointer, what parameters can the function receive?

for example:

void test1(int *p)
{
    
    }
//test1函数能接收什么参数?  int型一维数组,和int型变量的地址
void test2(char* p)
{
    
    }
//test2函数能接收什么参数?  char型一维数组,和char型变量的地址

4.4 Second-level pointer parameter passing

#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);//num = 10
    test(&p);//num = 10
    return 0;
}

think:

When the parameter of the function is a secondary pointer, what parameters can it receive?

void test(char **p) {
    
    
}

int main() {
    
    
    char c = 'b';
    char *pc = &c;
    char **ppc = &pc;
    char *arr[10];
    test(&pc);  //pc是一个一级指针,&pc即二级指针
    test(ppc);  //ppc是一个二级指针
    test(arr);//Ok?  
    return 0;
}

The array name itself can also be interpreted as a pointer to the first element of the array. For an char*array of a type arr[10], arrit can be interpreted as arr[0]a pointer arr[0]to char*a pointer to a type.

So when called test(arr), a pointer to is actually arr[0]passed to testthe function. Inside testthe function, the type of the parameter pis char**, which can receive char*a pointer to the type. Therefore, test(arr)it is legal.

5. Function pointer

First look at a piece of code:

#include <stdio.h>
void test() {
    
    
    printf("hehe\n");
}

int main() {
    
    
    printf("%p\n", test);
    printf("%p\n", &test);
    return 0;
}

Output result:

0000000000401550
0000000000401550

The output is two addresses, which are the addresses of the test function.

So how do we save the address of our function if we want to save it?

Let's look at the code below:

void test() {
    
    
    printf("hehe\n");
}

//下面pfun1和pfun2哪个有能力存放test函数的地址?
void (*pfun1)();
void *pfun2();

pfun1 can be stored. pfun1 is first combined with *, indicating that pfun1 is a pointer, and the pointer points to a function, the pointed function has no parameters, and the return value type is void.

What are function pointers?

A function pointer is a pointer variable that points to a function. It can be used to dynamically choose to call different functions when the program is running, or to pass functions as parameters to other functions.

Declaration of function pointer:

return_type (*pointer_name)(parameter_list);

where return_typeis the return type of the function, pointer_nameis the name of the pointer variable, and parameter_listis the parameter list of the function. For example, the following is a declaration of a pointer to a function that returns an integer type and accepts two integer parameters:

int (*sum_ptr)(int, int);

Assignment of function pointers:

A function pointer can be initialized by assigning the name of the function to the pointer variable. For example, suppose you have the following function definition:

int sum(int a, int b) {
    
    
    return a + b;
}

This function can be assigned to a function pointer:

sum_ptr = sum;

Calling a function using a function pointer: The syntax of calling a function using a function pointer is similar to that of calling a function directly, just add the parameter list after the pointer variable. For example:

int result = sum_ptr(3, 4);

Example 1:

#include <stdio.h>
int Add(int x, int y) {
    
    
    return x + y;
}

int main() {
    
    
    //pf就是函数指针变量
    int (*pf)(int x, int y) = Add;  //Add和&Add都是函数的地址,没有区别,类似于数组名和&数组名
    int sum = (*pf)(3, 5);  //等价于int sum = Add(3, 5);
    
    printf("%d\n", sum);  //8
    return 0;
}

Example 2:

#include <stdio.h>
int test(const char *str, double d) {
    
    
}

int main() {
    
    
    int (*pt1)(const char *, double) = &test;
    int (*pt2)(const char *str, double d) = &test;

    return 0;
}

Read two interesting pieces of code:

//代码1
(*(void (*)())0)();
//代码2
void (*signal(int , void(*)(int)))(int);

(*(void (*)())0)();Convert 0 directly to a function pointer of void (*)(), and then call the function at address 0, the parameter of the function is no parameter

void (*signal(int , void(*)(int)))(int);is a function declaration

The declared function is called: signal

The first parameter of the signal function is of type int

The second parameter of the signal function is a function pointer type, the function parameter pointed to by the function pointer is int, and the return type is void

The return type of the signal function is also a function pointer type, the function parameter pointed to by the function pointer is int, and the return type is void

Code 2 is too complicated, how to simplify:

typedef void(*pfun_t)(int);  //pfun_t 是一个函数指针,参数是int,返回类型是void
pfun_t signal(int, pfun_t);

6. Array of function pointers

An array is a storage space that stores the same type of data, so we have already learned about arrays of pointers

for example:

int *arr[10];
//数组的每个元素是int*

Each element in the array of function pointers is a function pointer . A function pointer is a pointer variable to a function that can be used to call that function.

Then store the address of the function in an array, then this array is called an array of function pointers , how to define the array of function pointers?

int (*parr1[10])();   //函数指针数组,指向一个无参函数,返回值为int
int *parr2[10]();	 
int (*)() parr3[10];  

the answer is:parr1

parr1First []combine with to show that parr1it is an array. What is the content of the array?

is a function pointerint (*)() of type .

Purpose of array of function pointers: transfer table

Example: (calculator)

#include <stdio.h>

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 menu() {
    
    
    printf("***************************\n");
    printf("***** 1.add    2. sub  ****\n");
    printf("***** 3.mul    4. div  ****\n");
    printf("***** 0.exit           ****\n");
    printf("***************************\n");
}

int main() {
    
    
    int input = 0;
    int x = 0;
    int y = 0;
    int ret = 0;
    do {
    
    
        menu();
        printf("请选择:>");
        scanf("%d", &input);

        switch (input) {
    
    
            case 1:
                printf("请输入2个操作数:>");
                scanf("%d %d", &x, &y);
                ret = Add(x, y);
                printf("%d\n", ret);
                break;
            case 2:
                printf("请输入2个操作数:>");
                scanf("%d %d", &x, &y);
                ret = Sub(x, y);
                printf("%d\n", ret);
                break;
            case 3:
                printf("请输入2个操作数:>");
                scanf("%d %d", &x, &y);
                ret = Mul(x, y);
                printf("%d\n", ret);
                break;
            case 4:
                printf("请输入2个操作数:>");
                scanf("%d %d", &x, &y);
                ret = Div(x, y);
                printf("%d\n", ret);
                break;
            case 0:
                printf("退出计算器\n");
                break;
            default:
                printf("选择错误\n");
                break;
        }
    } while (input);
}

Simplify your code with an array of function pointers:

#include <stdio.h>

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 menu() {
    
    
    printf("***************************\n");
    printf("***** 1.add    2. sub  ****\n");
    printf("***** 3.mul    4. div  ****\n");
    printf("***** 0.exit           ****\n");
    printf("***************************\n");
}

int main() {
    
    
    int input = 0;
    int x = 0;
    int y = 0;
    int ret = 0;

    //函数指针数组   - 转移表
    int (*pfArr[])(int, int) = {
    
    0, Add, Sub, Mul, Div};

    do {
    
    
        menu();
        printf("请选择:>");
        scanf("%d", &input);
        if (input == 0) {
    
    
            printf("退出计算器\n");
            break;
        }

        if (input >= 1 && input <= 4) {
    
    
            printf("请输入2个操作数:>");
            scanf("%d %d", &x, &y);
            ret = pfArr[input](x, y);
            printf("%d\n", ret);
        } else {
    
    
            printf("选择错误\n");
        }
    } while (input);
}

7. Pointer to array of function pointers

A pointer to an array of function pointers is a pointer to the starting address of the array of function pointers . You can use this pointer to access the elements in the function pointer array, and call the corresponding function through the function pointer.

Here is a simple example showing how to declare and use a pointer to an array of function pointers:

#include <stdio.h>

void test(const char* str){
    
    
	printf("%s\n", str);
}

int main(){
    
    
 	//函数指针pfun
	void (*pfun)(const char*) = test;
 	//函数指针的数组pfunArr
	void (*pfunArr[5])(const char* str);
 	pfunArr[0] = test;
 	//指向函数指针数组pfunArr的指针ppfunArr
 	void (*(*ppfunArr)[5])(const char*) = &pfunArr;
 	return 0;
}


// 函数指针的声明
typedef void (*FuncPtr)(int);

// 函数定义
void func1(int num) {
    
    
    printf("func1: %d\n", num);
}

void func2(int num) {
    
    
    printf("func2: %d\n", num);
}

void func3(int num) {
    
    
    printf("func3: %d\n", num);
}

int main() {
    
    
    // 函数指针数组的定义和初始化
    FuncPtr funcs[] = {
    
     func1, func2, func3 };

    // 指向函数指针数组的指针
    FuncPtr (*ptrToFuncArray)[3] = &funcs;

    // 通过指针访问函数指针数组的元素,并调用相应的函数
    (*ptrToFuncArray)[0](10);  // 调用 func1
    (*ptrToFuncArray)[1](20);  // 调用 func2
    (*ptrToFuncArray)[2](30);  // 调用 func3

    return 0;
}

8. Callback function

A callback function is a way of using function pointers that allows passing a function as a parameter to another function and calling that function when needed. Callback functions provide a flexible mechanism that enables code to perform different actions based on certain conditions or events.

#include <stdio.h>

// 回调函数类型的定义
typedef void (*CallbackFunc)(int);

// 执行回调函数的函数
void performCallback(CallbackFunc callback, int value) {
    
    
    // 调用传递进来的回调函数
    callback(value);
}

// 回调函数1
void callback1(int value) {
    
    
    printf("Callback 1: %d\n", value);
}

// 回调函数2
void callback2(int value) {
    
    
    printf("Callback 2: %d\n", value);
}

int main() {
    
    
    int data = 10;

    // 使用回调函数1进行操作
    performCallback(callback1, data);

    // 使用回调函数2进行操作
    performCallback(callback2, data);

    return 0;
}

The output is as follows:

Callback 1: 10
Callback 2: 10

We first define a callback function type CallbackFunc, which is a function pointer type that can point to a function with one intparameter and voidreturn type.

Then, we define a performCallbackfunction called that takes a callback function as an argument and calls that function when needed, passing it a value.

Next, we define two callback functions callback1and callback2, which both conform to CallbackFuncthe function signature of type .

In mainthe function, we define an integer variable data, and then use performCallbackthe function twice, passing different callback functions and datavalues. In this way, the function of executing different callback functions in different situations is realized.

When the program is running, the functions will be called sequentially performCallback, and the corresponding information will be printed according to the passed callback function.

qsort function

The qsort function in C language is also implemented through the function pointer callback function

#include <stdio.h>
//qosrt函数的使用者得实现一个比较函数
int int_cmp(const void *p1, const void *p2) {
    
    
    return (*(int *) p1 - *(int *) p2);
}

int main() {
    
    
    int arr[] = {
    
    1, 3, 5, 7, 9, 2, 4, 6, 8, 0};
    int i = 0;

    qsort(arr, sizeof(arr) / sizeof(arr[0]), sizeof(int), int_cmp);
    for (i = 0; i < sizeof(arr) / sizeof(arr[0]); i++) {
    
    
        printf("%d ", arr[i]);
    }
    printf("\n");
    return 0;
}

Use bubble sorting simulation to implement the callback function method:

#include <stdio.h>

int cmp_int(const void *e1, const void *e2) {
    
    
    return (*(int *) e1 - *(int *) e2);
}

//char类型1字节,适用于任何类型
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_sort(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;
        for (j = 0; j < sz - 1 - i; j++) {
    
    
            if (cmp((char *) base + j * width, (char *) base + (j + 1) * width) > 0) {
    
    
                //交换
                Swap((char *) base + j * width, (char *) base + (j + 1) * width, width);
            }
        }
    }
}

int main() {
    
    
    int arr[] = {
    
    1, 3, 5, 7, 9, 2, 4, 6, 8, 0};
    //char *arr[] = {"aaaa","dddd","cccc","bbbb"};
    int i = 0;
    bubble_sort(arr, sizeof(arr) / sizeof(arr[0]), sizeof(int), cmp_int);
    for (i = 0; i < sizeof(arr) / sizeof(arr[0]); i++) {
    
    
        printf("%d ", arr[i]);
    }
    printf("\n");
    return 0;
}

Guess you like

Origin blog.csdn.net/ikun66666/article/details/131710906