Eine kurze Einführung in Zeiger (4) Die Verwendung von Funktionszeiger-Arrays und qsort

Inhaltsverzeichnis der Serienartikel


Vorwort

Beherrschen Sie die Verwendung von Funktionszeiger-Arrays und die Implementierung der qsort-Funktion.

1. Zweck des Funktionszeiger-Arrays

Funktion: Es kann den Code prägnanter und die Logik klarer machen.

Computerimplementierung:
Einfache Additions- und Subtraktionsoperationen
Code 1

#include <stdio.h>
int add(int a, int b)//加法
{
    
    
 	return a + b;
}
int sub(int a, int b)//减法
{
    
    
 	return a - b;
}
int main()
{
    
    
 	int x, y;
 	int input = 1;
 	int ret = 0;
 do
 {
    
    
 	printf("*************************\n");
 	printf(" 1:add 			   2:sub \n");
 	printf(" 0:exit 				 \n");
 	printf("*************************\n");
 	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", ret);
 		break;
 	default:
 		printf("选择错误\n");
 		break;
 	}
 } while (input);
 return 0;
}

Fügen Sie hier eine Bildbeschreibung ein
Zu diesem Zeitpunkt können Sie das Funktionszeiger-Array verwenden,
Transformation:
Code 2

#include <stdio.h>
int add(int a, int b)
{
    
    
 	return a + b;
}
int sub(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 x, y;
 	int input = 1;
 	int ret = 0;
 	int(*p[3])(int x, int y) = {
    
     0, add, sub }; //转移表
 do
 {
    
    
  	printf("*************************\n");
 	printf(" 1:add 			   2:sub \n");
 	printf(" 0:exit 				 \n");
 	printf("*************************\n");
 	printf("请选择:");
 	scanf("%d", &input);
	if ((input <= 4 && input >= 1)){
    
    
 		printf( "输⼊操作数:" );
 		scanf( "%d %d", &x, &y);
 		ret = (*p[input])(x, y);
 		printf( "ret = %d\n", ret);
 	}
 	else if(input == 0)
 	{
    
    
 		printf("退出计算器\n");
 	}
 	else
 	{
    
    
 		printf( "输⼊有误\n" ); 
 	}
  	return 0;
}

Sieht so aus, als wäre das sehr einfach, also wie heißt es?

int(*p[3])(int x, int y) = {
    
     0, add, sub };

Wie im Bild gezeigt:
Fügen Sie hier eine Bildbeschreibung ein

2. Rückruffunktion

Eine Callback-Funktion ist eine Funktion, die über einen Funktionszeiger aufgerufen wird

Wenn Sie einen Funktionszeiger (Adresse) als Parameter an eine andere Funktion übergeben und dieser Zeiger zum Aufrufen der Funktion verwendet wird, auf die er zeigt, ist die aufgerufene Funktion die Rückruffunktion.
Die Rückruffunktion wird nicht direkt von der Implementierung der Funktion aufgerufen, sondern von einer anderen Partei aufgerufen, wenn ein bestimmtes Ereignis oder eine bestimmte Bedingung auftritt, und zur Behandlung des Ereignisses oder der Bedingung verwendet. Reagieren. Im Computerimplementierungscode, den wir oben in Code 1 geschrieben haben, erscheint der Code im roten Feld wiederholt. Obwohl die Logik der Berechnung unterschiedlich ist, sind die Eingabe- und Ausgabeoperationen redundant. Gibt es eine Möglichkeit? Wie wäre es mit einer Vereinfachung?
Aufgrund des Codes im roten Feld unterscheidet sich nur die Logik des Funktionsaufrufs. Wir können die Adresse der aufgerufenen Funktion in Form eines Parameters übergeben und den Funktionszeiger zum Empfangen verwenden it. Die Funktion, auf die der Funktionszeiger zeigt, wird aufgerufen. Was hier tatsächlich verwendet wird, ist die Funktion der Rückruffunktion.

3. qsort-Funktion

Die Funktion qsort kann alle Datentypen sortieren

Notwendige Parameter zum Übergeben von Parametern:
Fügen Sie hier eine Bildbeschreibung ein
Wie hat sie das erreicht?
Code 3:

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

Die Erklärung ist wie in der Abbildung dargestellt:Fügen Sie hier eine Bildbeschreibung ein
Die Vergleichsfunktion wird von einem Funktionszeiger empfangen. Auf die interne Implementierung werde ich später eingehen

3. 1 Verwenden Sie qsort, um Strukturdaten zu sortieren

Kann nach Name oder Alter sein
Code 4:

struct Stu //学⽣
{
    
    
 	char name[20];//名字
 	int age;//年龄
 };
//假设按照年龄来⽐较
int cmp_stu_by_age(const void* e1, const void* e2)
{
    
    
 	return ((struct Stu*)e1)->age - ((struct Stu*)e2)->age;
}
//strcmp - 是库函数,是专⻔⽤来⽐较两个字符串的⼤⼩的
//假设按照名字来⽐较
int cmp_stu_by_name(const void* e1, const void* e2)
{
    
    
 	return strcmp(((struct Stu*)e1)->name, ((struct Stu*)e2)->name);
}
//按照年龄来排序
void test2()
{
    
    
 	struct Stu s[] = {
    
     {
    
    "zhangsan", 20}, {
    
    "lisi", 30}, {
    
    "wangwu", 15} };
 	int sz = sizeof(s) / sizeof(s[0]);
 	qsort(s, sz, sizeof(s[0]), cmp_stu_by_age);
}
//按照名字来排序
void test3()
{
    
    
 	struct Stu s[] = {
    
     {
    
    "zhangsan", 20}, {
    
    "lisi", 30}, {
    
    "wangwu", 15} };
 	int sz = sizeof(s) / sizeof(s[0]);
 	qsort(s, sz, sizeof(s[0]), cmp_stu_by_name);
}
int main()
{
    
    
 	test2();
 	test3();
 return 0;
}

Die Codeerklärung ist wie in der Abbildung dargestellt:
Fügen Sie hier eine Bildbeschreibung ein

5…Simulationsimplementierung der qsort-Funktion

Verwenden Sie die Callback-Funktion, um die Implementierung von qsort zu simulieren (mithilfe der Bubbling-Methode).

Ergänzung: qsort kann alle Datentypen sortieren. Der unten geschriebene Code ist die interne Implementierung von qsort

Hinweis: Dies ist das erste Mal, dass der void*-Zeiger verwendet wird, um die Rolle von void* zu erklären.

#include<stdio.h>
int int_cmp(const void * p1, const void * p2)//比较函数跟qsort函数的比较函数一样
{
    
    
 	return (*( int *)p1 - *(int *) p2);
}
void _swap(void *p1, void * p2, int size)
{
    
    
 	int i = 0;
 	for (i = 0; i< size; i++)//因为不知道数据类型(void)所以两个元素选择一个一个字节交换
 	{
    
    
 		char tmp = *((char *)p1 + i);
 		*(( char *)p1 + i) = *((char *) p2 + i);
 		*(( char *)p2 + i) = tmp;
 	}
}
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)//cmp函数返回值是int,判断>0,如果成立,执行语句
 		{
    
    
 			_swap(( char *)base + j*size, (char *)base + (j + 1)*size, size);//size是宽度,不知道
 		}
	}
  }
 }
int main()
{
    
    
 	int arr[] = {
    
     1, 3, 5, 7, 9, 2, 4, 6, 8, 0 };
 	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;
}

Analyse: In den obigen Codekommentaren gibt es auch eine Erklärung des if-Anweisungscodes, wie in der Abbildung gezeigt:
Fügen Sie hier eine Bildbeschreibung ein
Okay, das ist der gesamte Inhalt für heute! Ihr habt das alle gesehen, gebt ihm ein „Gefällt mir“, danke, bis zum nächsten Mal.

Supongo que te gusta

Origin blog.csdn.net/chendemingxxx/article/details/134723307
Recomendado
Clasificación