C-Sprache – Zeiger für Fortgeschrittene 3

Vorwort

        Im vorherigen Artikel haben wir den klassischen Fall der Callback-Funktion qsort kennengelernt. Heute werden wir versuchen, die Implementierung von qsort zu simulieren

1. Simulieren Sie die Implementierung der qsort-Funktion

        qsort ist eine Bibliotheksfunktion in der Sprache C. Es handelt sich um eine Sortierfunktion, die auf dem Schnellsortierungsalgorithmus basiert. Das größte Merkmal der qsort-Funktion ist Das heißt, es kann jede Art von Daten sortieren.

So verwenden Sie es:

#include <stdlib.h>
void qsort(void* base, //待排序数组的第一个元素的地址
	       size_t num, //待排序数组的元素个数
	       size_t size,//待排序数组中一个元素的大小
	       int (* cmp)(const void* e1, const void* e2)//函数指针-cmp指向了一个函数,这个函数是用来比较两个元素的
         //e1和e2中存放的是需要比较的两个元素的地址
          );

Jetzt implementieren wir die qsort-Funktion basierend aufBlasensortierungsalgorithmus:

Code (aufsteigende Reihenfolge):

#include<stdio.h>
#include <string.h>
void print_arr(int arr[], int sz)
{
	int i = 0;
	for (i = 0; i < sz; i++)
	{
		printf("%d ", arr[i]);
	}
	printf("\n");
}
int cmp(const void* e1, const void* e2)
{
	return *(int*)e1 - *(int*)e2;
}
void temp(char* a1, char* a2, size_t size)
{
	for (int i = 0; i < size; i++)
	{
		char temp1 = *a1;
		*a1 = *a2;
		*a2 = temp1;
		a1++;
		a2++;
	}
}
void bubble_sort(void* base, size_t num, size_t size,int (*cmp)(const void*e1,const void*e2))
{
	for (int i = 0; i < num - 1; i++)
	{
		for (int j = 0; j < num - 1 - i; j++)
		{
			if (cmp((char*)base +j*size,(char*)base +(j+1)*size)>0)
			{
				temp((char*)base + j * size, (char*)base + (j + 1) * size, size);
			}
		}
	}
}
void test1()
{
	int arr[] = { 9,8,7,6,5,4,3,2,1,0 };
	int sz = sizeof(arr) / sizeof(arr[0]);
	bubble_sort(arr, sz, sizeof(arr[0]),cmp);
	print_arr(arr, sz);
}
int main()
{
	test1();
	test2();
	return 0;

}

 Operationsergebnis:

Code-Analyse: 

        Sie können sehen, dass ich den Typ „base“ in den Typ „char*“ umgewandelt habe. Warum mache ich das?

Wenn Sie in der Lage sein möchten, beliebige Datentypen wie qsort zu sortieren, müssen Sie einen Weg finden, jeden Typ zu empfangen. Dann ist der Zeiger vom Typ char* perfekt. Char* überspringt bei jeder Bewegung ein Byte, also The Der empfangene Typ muss nur ein paar Bytes überspringen, zum Beispiel int (4 Bytes), dann müssen wir nur 4 Bytes überspringen.

        Es kann also als (char*)base +j*size geschrieben werden.

 Ebenso sehen wir, dass die temporäre Funktion beim Austausch von Array-Mitgliedern diese auch einzeln austauscht.

2.Zeigerbezogene Probleme bei sizeof und strlen

Diese Art von Fragen kommt in Interviewfragen vor und ist eine sehr wichtige Kategorie. Wenn Sie diese Art von Frage stellen, müssen Sie zwei Voraussetzungen kennen.

Was das Verständnis des Array-Namens betrifft, ist der Array-Name die Adresse des ersten Elements des Arrays, es gibt jedoch zwei Ausnahmen:

        ​​​​ 1.sizeof (Array-Name), der Array-Name stellt hier das gesamte Array dar, sizeof (Array-Name) berechnet die Größe des gesamten Arrays, die Einheit ist Bytes.

        ​ ​ 2.&Array-Name, der Array-Name stellt hier das gesamte Array dar, &Array-Name nimmt die Adresse des Arrays heraus.

Beispielgröße:

int main()
{
	//一维数组
	int a[] = { 1,2,3,4 };
	printf("%d\n", sizeof(a));
	printf("%d\n", sizeof(a + 0));
	printf("%d\n", sizeof(*a));
	printf("%d\n", sizeof(a + 1));
	printf("%d\n", sizeof(a[1]));
	printf("%d\n", sizeof(&a));
	printf("%d\n", sizeof(*&a));
	printf("%d\n", sizeof(&a + 1));
	printf("%d\n", sizeof(&a[0]));
	printf("%d\n", sizeof(&a[0] + 1));
	
	return 0;
}

erklären:

    //Eindimensionales Array
    int a[] = {1,2,3,4};//4 Elemente, jedes Element ist vom Typ int (Abschnitt mit 4 Wörtern)

    printf("%d\n", sizeof(a));//16, der Array-Name a wird allein in sizeof platziert. Der Array-Name repräsentiert das gesamte Array und die Größeneinheit des Ganzen Array wird in Worten berechnet. Abschnitt, ist 16 Bytes
    printf("%d\n", sizeof(a + 0));//a wird nicht allein innerhalb von sizeof platziert, und dort ist kein &, also ist das Array Der Name a ist die Adresse des ersten Elements des Arrays, a+0 ist auch die Adresse des ersten Elements
    //Die Adressgröße beträgt 4/ 8 Byte

    printf("%d\n", sizeof(*a));//a wird nicht allein in sizeof platziert und es gibt kein &, daher ist der Array-Name a die Adresse des ersten Element des Arrays
    //*a ist das erste Element, die Größe beträgt 4Byte //*a == *(a+0) == a[0]

    printf("%d\n", sizeof(a + 1));//a wird nicht allein in sizeof platziert und es gibt kein &, daher ist der Array-Name a die Adresse des erstes Element des Arrays, a +1 ist die Adresse des zweiten Elements
    //a+1 == &a[1] ist die Adresse des zweiten Elements, die Adresse ist 4 /8 Bytes

    Printf("%d\n", sizeof(a[1]));//a[1] ist das zweite Element des Arrays, was hier berechnet wird, ist die Größe des zweiten Elements, die Einheit ist Bytes - 4

    printf("%d\n", sizeof(&a));//&a - ist die Adresse des Arrays, aber die Adresse des Arrays ist auch eine Adresse und die Adresse ist 4/8 Byte
    //Der wesentliche Unterschied zwischen der Adresse des Arrays und der Adresse des ersten Elements des Arrays ist der Unterschied im Typ, nicht in der Größe.< a i=2> //a -- int* int * p = a;     //&a -- int (*)[4] int (*p)[4] = & ;a;     printf ("%d\n", sizeof(*&a));//16 Dereferenzieren Sie den Array-Zeiger, um auf die Größe eines Arrays zuzugreifen. Die Einheit ist Bytes     //sizeof(* &a) --- sizeof(a) //16


    

    printf("%d\n", sizeof(&a + 1));//&Die Adresse des Arrays, &a+1 bedeutet, dass das gesamte Array übersprungen wird, aber es ist immer noch die Adresse, die vorhanden ist 4/8 Byte


    printf("%d\n", sizeof(&a[0]));//&a[0] ist die Adresse des ersten Elements und die berechnete Größe beträgt 4/8 der Adresse Bytes
    printf("%d\n", sizeof(&a[0] + 1));//&a[0] ist die Adresse des ersten Element, & a[0]+1 ist die Adresse des zweiten Elements, die Größe beträgt 4/8 Bytes

strlen-Beispiel:

int main()
{
	char arr[] = { 'a','b','c','d','e','f' };
	printf("%d\n", strlen(arr));
	printf("%d\n", strlen(arr + 0));
	printf("%d\n", strlen(*arr));
	printf("%d\n", strlen(arr[1]));
	printf("%d\n", strlen(&arr));
	printf("%d\n", strlen(&arr + 1));
	printf("%d\n", strlen(&arr[0] + 1));
	return 0;
}

erklären:

    char arr[] = { 'a','b','c','d',' ;e','f'};//6
    //strlen sucht nach '\0', falls nicht gefunden, ein Zufall Wert wird generiert< /span>     //Standing at strlen Aus diesem Blickwinkel wird angenommen, dass das übergebene „a“-97 die Adresse ist und 97 als Adresse verwendet wird. Direkter Zugriff ist illegaler Zugriff     printf ("%d\n", strlen(&arr[0 ] + 1));//Zufälliger Wert     printf("%d\n", strlen(&arr + 1));//Zufälliger Wert     //const char*     //&arr -- char (*)[6]     printf( "%d\n", strlen(&arr)); //Zufälliger Wert     printf("%d\n", strlen(arr[1]));//err, 'b' - 98     printf("%d\n" , strlen(*arr));//err, arr ist die Adresse des ersten Elements, *arr ist das erste Element - 'a' - 97     printf("%d \n", strlen(arr + 0));//Zufälliger Wert, arr ist die Adresse des ersten Elements, arr+0 ist immer noch die Adresse des ersten Elements
    printf("%d\n", strlen(arr));//Zufälliger Wert, arr ist die Adresse des ersten Elements








        

Supongo que te gusta

Origin blog.csdn.net/2301_76618602/article/details/132882357
Recomendado
Clasificación