C language has an in-depth understanding of pointers (very detailed) (5)

Callback

A callback function is a function called through a function pointer

If you pass a function pointer (address) as a parameter to another function, and when the pointer is used to call the function it points to, the
called function is the callback function.
The callback function is not called directly by the implementer of the function, but is called by another party when a specific event or condition

occurs to respond to the event or condition . For example:

//使⽤回调函数改造前
#include <stdio.h>
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;
do
{
    
    
printf("******************)
printf(" 1:add,2:sub\n)
printf(" 3:mul,4:div\n)
printf("******************)
printf("请选择:");
scanf("%d", &input);
switch (input)
{
    
    
case 1:
printf("输⼊操作数:");
scanf("%d %d", &x, &y)
ret = add(x, y);
printf("ret = %d\n", ret)
break;
case 2:
printf("输⼊操作数:");
scanf("%d %d", &x, &y)
ret = sub(x, y);
printf("ret = %d\n", r
break;
case 3:
printf("输⼊操作数:");
scanf("%d %d", &x, &y)
ret = mul(x, y);
printf("ret = %d\n", ret)
break;
case 4:
printf("输⼊操作数:");
scanf("%d %d", &x, &y)
ret = div(x, y);
printf("ret = %d\n", ret)
break;
case 0:
printf("退出程序\n");
break;
default:
printf("选择错误\n");
break;
}
} while (input);
return 0;
}
//使⽤回到函数改造后
#include <stdio.h>
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;
}
void calc(int(*pf)(int, int))
{
    
    
int ret = 0;
int x, y;
printf("输⼊操作数:");
scanf("%d %d", &x, &y);
ret = pf(x, y);
printf("ret = %d\n", ret);
}
int main()
{
    
    
int input = 1;
do
{
    
    
printf("******************)
printf(" 1:add,2:sub\n)
printf(" 3:mul,4:div\n)
printf("******************)
printf("请选择:");
scanf("%d", &input);
switch (input)
{
    
    
case 1:
calc(add);
break;
case 2:
calc(sub);
break;
case 3:
calc(mul);
break;
case 4:
calc(div);
break;
case 0:
printf("退出程序\n");
break;
default:
printf("选择错误\n");
break;
}
} while (input);
return 0;
}

qsort usage example

#include <stdio.h>
//qosrt函数的使⽤者得实现⼀个⽐较函数
int int_cmp(const void * p1, const void * p2)
/*void*p为任意类型的指针,
因为创造这个函数的人不知道使用者会传入什么类型的指针,
因此用viod类型的指针就可以解决这个问题*/
{
    
    
return (*( int *)p1 - *(int *) p2);
/*返回值是用两个指针变量进行相减,其中int*为强制类型转换,将p1和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);
/*qsort函数需要数组的首元素地址,还有多少个元素,一个数组元素有多少字节,比较大小的函数*/
/*因为需要比较两元素的大小,然后进行排序,所以需要一个比较大小的元素*/
for (i = 0; i< sizeof(arr) / sizeof(arr[0]); i++)
{
    
    
printf( "%d ", arr[i]);
}
printf("\n");
return 0;
}

Simulation implementation of qsort function

Use the callback function to simulate the implementation of qsort (using bubbling method)

#include <stdio.h>
//比较大小的函数
int int_cmp(const void* p1, const void* p2)
{
    
    
	return (*(int*)p1 - *(int*)p2);
}
//交换的函数
void _swap(void* p1, void* p2, int size)
{
    
    
	int i = 0;
	for (i = 0; i < size; i++)
	{
    
    
		char tmp = *((char*)p1 + i);
		*((char*)p1 + i) = *((char*)p2 + i);
		*((char*)p2 + i) = tmp;
		//*((char*)p1 + i)就是数组的元素一点i个字节,因为是强制类型转换为char*类型的指针,又由于char*类型的指针大小为一个字节,所以移动i个字节就是移动i个数组元素
	}
}
//模拟实现的qsort函数
void bubble(void* base, int count, int size, int(*cmp)(void*, void*))
{
    
    
	int i = 0;
	int j = 0;
	for (i = 0; i < count - 1; i++)
	{
    
    
		for (j = 0; j < count - i - 1; j++)
		{
    
    
			if (cmp((char*)base + j * size, (char*)base + (j + 1) * size) > 0)
			//判断指针大小是否大于0,如果大于0就会交换
			{
    
    
				_swap((char*)base + j * size, (char*)base + (j + 1) * size, size);
			}
		}
	}
}

int main()
{
    
    
	int arr[] = {
    
     1, 3, 5, 7, 9, 2, 4, 6, 8, 0 };
	//char *arr[] = {"aaaa","dddd","cccc","bbbb"};
	int i = 0;
	bubble(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;
}

Comparison of sizeof and strlen

sizeof

When learning operators, we learned about sizeof. Sizeof calculates the size of the memory space occupied by a variable in bytes. If the operand is a type, it calculates the size of the memory space occupied by the variable created using the type .
sizeof only focuses on the size of the memory space occupied, and does not care what data is stored in the memory. For example:

#inculde <stdio.h>
int main()
{
    
    
int a = 10;
printf("%d\n", sizeof(a));
printf("%d\n", sizeof a);
printf("%d\n", sizeof(int));
return 0;
}

strlen

strlen is a C language library function whose function is to find the length of a string. The function prototype is as follows:

size_t strlen ( const char * str );
这里随便说一下size_t是无符号整形类型

The statistics are the number of characters in the string starting from the address in the parameter str of the strlen function and going backwards until \0 .
The strlen function will keep searching for the \0 character until it is found, so there may be an out-of-bounds search (\0 cannot be found)

#include <stdio.h>
int main()
{
    
    
char arr1[3] = {
    
    'a', 'b', 'c'};
char arr2[] = "abc";
printf("%d\n", strlen(arr1));
/*strlen(arr1)就是越界查找的典型例子
因为数组里都是字符,并没找到\0
因此就会越界查找,甚至找不到*/
printf("%d\n", strlen(arr2));
/*每个字符串末尾都有\0,
因此strlen的大小就是abc中有多少个字符*/
printf("%d\n", sizeof(arr1));
printf("%d\n", sizeof(arr1));
return 0;
}

Comparison of sizeof and strlen

sizeof

  1. sizeof is the operator
  2. sizeof calculates the size of
    the memory , the unit is bytes
  3. Don’t pay attention to what
    data is stored in the memory

strlen

  1. strlen is a library function. To use it, you need to include the header string.h
  2. srtlen is used to find the length of a string, counting the number of characters before \0
  3. Pay attention to whether there is \0 in the memory. If there is no \0, it will continue to search backward and may
    cross the boundary.

A question about sizeof

#include<stdop.h>
int main()
{
    
    
short s=10;
in**加粗样式**t i=2;
int n=sizeof(s=i+4);
printf("%d\n",s);
printf("%d\n",n);
return 0;
}

As a short integer, s occupies two bytes, while i is an integer and occupies 4 bytes. In int n=sizeof(s=i+4), many people think that i+4 will be assigned to s, but We should note that the two types are different. One is a short integer and the other is an integer, so truncation will occur. Since s is always a short integer, sizeof(s) is the memory size of s, which is why 2 is for n
. is equal to 10. In fact, if the operand of sizeof is an expression, the expression will not participate in the calculation, because we already know that s is a short integer, so there is no need to calculate it again, so the value assigned to s Still 10.
The expression has two attributes:
1: type attribute
2: value attribute
. So in the future we only need to judge the expression type in sizeof to know the size.

Insert image description here

Guess you like

Origin blog.csdn.net/2301_79178723/article/details/132744195