Freigeben über


qsort_s

Führt eine schnelle Sortierung aus. Eine Version mit qsort Sicherheitsverbesserungen, wie in den Sicherheitsfeatures in der CRT beschrieben.

Syntax

void qsort_s(
   void *base,
   size_t num,
   size_t width,
   int (__cdecl *compare )(void *, const void *, const void *),
   void * context
);

Parameter

base
Start des Zielarrays.

number
Arraygröße in Elementen.

width
Elementgröße in Bytes.

compare
Vergleichsfunktion. Das erste Argument ist der context -Zeiger. Das zweite Argument ist ein Zeiger auf den key für die Suche. Das dritte Argument ist ein Zeiger auf das Arrayelement, das mit keyverglichen werden soll.

context
Ein Zeiger auf einen Kontext, d.h. alle möglichen Objekte, auf die die compare-Routine zugreifen muss.

Hinweise

Die qsort_s-Funktion implementiert einen Schnellsortierungsalgorithmus, um ein Array von number-Elementen zu sortieren, die jeweils aus width-Bytes bestehen. Das base-Argument ist ein Zeiger auf die Basis des Arrays, das sortiert werden soll. qsort_s überschreibt dieses Array mit den sortierten Elementen. Das compare-Argument ist ein Zeiger auf eine vom Benutzer angegebene Routine, die zwei Elemente des Arrays vergleicht und einen Wert zurückgibt, der ihre Beziehung angibt. qsort_s ruft die compare-Routine einmal oder mehrere Male während der Sortierung auf, wodurch bei jedem Aufruf Zeiger auf zwei Arrayelemente übergeben werden:

compare( context, (void *) & elem1, (void *) & elem2 );

Die Routine muss die Elemente vergleichen und einen der folgenden Werte zurückgeben:

Rückgabewert Beschreibung
< 0 Element 1 kleiner als Element 2
0 Element 1 entspricht Element 2
> 0 Element 1 größer als Element 2

Das Array wird in aufsteigender Reihenfolge sortiert, wie von der Vergleichsfunktion definiert. Kehren Sie die Richtung „größer als“ und „kleiner als“ in der Vergleichsfunktion um, um ein Array in absteigender Reihenfolge zu sortieren.

Wenn ungültige Parameter an die Funktion übergeben werden, wird der ungültige Parameterhandler aufgerufen, wie in der Parameterüberprüfung beschrieben. Wenn die Ausführung fortgesetzt werden darf, wird die Funktion zurückgegeben und errno auf EINVAL. Weitere Informationen finden Sie untererrno, _doserrno, _sys_errlistund _sys_nerr.

Standardmäßig gilt der globale Zustand dieser Funktion für die Anwendung. Wie Sie dieses Verhalten ändern, erfahren Sie unter Globaler Status in der CRT.

Fehlerbedingungen

Schlüssel base compare num width errno
NULL any Beliebig Beliebig Beliebig EINVAL
Beliebig NULL any != 0 any EINVAL
Beliebig Beliebig Beliebig any <= 0 EINVAL
any Beliebig NULL Beliebig any EINVAL

qsort_s verhält sich identisch wie qsort, verfügt jedoch über die context-Parameter und legt errno fest. Mit dem context Parameter können Vergleichsfunktionen einen Objektzeiger verwenden, um auf Objektfunktionen oder andere Informationen zuzugreifen, auf die über einen Elementzeiger nicht zugegriffen werden kann. Das Hinzufügen des context Parameters macht qsort_s sicherer, da context reentrancy Bugs vermieden werden können, die mithilfe statischer Variablen eingeführt werden, um freigegebene Informationen für die compare Funktion verfügbar zu machen.

Anforderungen

Routine Erforderlicher Header
qsort_s <stdlib.h> und <search.h>

Weitere Informationen zur Kompatibilität finden Sie unter Kompatibilität.

Bibliotheken: Alle Versionen der C-Laufzeitbibliotheken.

Beispiel

Im folgenden Beispiel wird die Verwendung des context Parameters in der qsort_s Funktion veranschaulicht. Der context-Parameter erleichtert die Ausführung von threadsicheren Sortiervorgängen. Anstelle von statischen Variablen, die synchronisiert werden müssen, um Threadsicherheit zu gewährleisten, übergeben Sie einen anderen context-Parameter in jeder Sortierung. In diesem Beispiel wird ein Gebietsschemaobjekt als context-Parameter verwendet.

// crt_qsort_s.cpp
// compile with: /EHsc /MT
#include <stdlib.h>
#include <stdio.h>
#include <search.h>
#include <process.h>
#include <locale.h>
#include <locale>
#include <windows.h>
using namespace std;

// The sort order is dependent on the code page.  Use 'chcp' at the
// command line to change the codepage.  When executing this application,
// the command prompt codepage must match the codepage used here:

#define CODEPAGE_850

#ifdef CODEPAGE_850
// Codepage 850 is the OEM codepage used by the command line,
// so \x00e1 is the German Sharp S in that codepage and \x00a4
// is the n tilde.

char *array1[] = { "wei\x00e1", "weis", "annehmen", "weizen", "Zeit",
                   "weit" };
char *array2[] = { "Espa\x00a4ol", "Espa\x00a4" "a", "espantado" };
char *array3[] = { "table", "tableux", "tablet" };

#define GERMAN_LOCALE "German_Germany.850"
#define SPANISH_LOCALE "Spanish_Spain.850"
#define ENGLISH_LOCALE "English_US.850"

#endif

#ifdef CODEPAGE_1252
   // If using codepage 1252 (ISO 8859-1, Latin-1), use \x00df
   // for the German Sharp S and \x001f for the n tilde.
char *array1[] = { "wei\x00df", "weis", "annehmen", "weizen", "Zeit",
                   "weit" };
char *array2[] = { "Espa\x00f1ol", "Espa\x00f1" "a", "espantado" };
char *array3[] = { "table", "tableux", "tablet" };

#define GERMAN_LOCALE "German_Germany.1252"
#define SPANISH_LOCALE "Spanish_Spain.1252"
#define ENGLISH_LOCALE "English_US.1252"

#endif

// The context parameter lets you create a more generic compare.
// Without this parameter, you would have stored the locale in a
// static variable, thus making sort_array vulnerable to thread
// conflicts.

int compare( void *pvlocale, const void *str1, const void *str2)
{
    char s1[256];
    char s2[256];
    strcpy_s(s1, 256, *(char**)str1);
    strcpy_s(s2, 256, *(char**)str2);
    _strlwr_s( s1, sizeof(s1) );
    _strlwr_s( s2, sizeof(s2) );

    locale& loc = *( reinterpret_cast< locale * > ( pvlocale));

    return use_facet< collate<char> >(loc).compare(s1,
       &s1[strlen(s1)], s2, &s2[strlen(s2)]);

}

void sort_array(char *array[], int num, locale &loc)
{
    qsort_s(array, num, sizeof(char*), compare, &loc);
}

void print_array(char *a[], int c)
{
   for (int i = 0; i < c; i++)
      printf("%s ", a[i]);
   printf("\n");

}

void sort_german(void * Dummy)
{
   sort_array(array1, 6, locale(GERMAN_LOCALE));
}

void sort_spanish(void * Dummy)
{
   sort_array(array2, 3, locale(SPANISH_LOCALE));
}

void sort_english(void * Dummy)
{
   sort_array(array3, 3, locale(ENGLISH_LOCALE));
}

int main( )
{
   int i;
   HANDLE threads[3];

   printf("Unsorted input:\n");
   print_array(array1, 6);
   print_array(array2, 3);
   print_array(array3, 3);

   // Create several threads that perform sorts in different
   // languages at the same time.

   threads[0] = reinterpret_cast<HANDLE>(
                 _beginthread( sort_german , 0, NULL));
   threads[1] = reinterpret_cast<HANDLE>(
                 _beginthread( sort_spanish, 0, NULL));
   threads[2] = reinterpret_cast<HANDLE>(
                 _beginthread( sort_english, 0, NULL));

   for (i = 0; i < 3; i++)
   {
      if (threads[i] == reinterpret_cast<HANDLE>(-1))
      {
         printf("Error creating threads.\n");
         exit(1);
      }
   }

   // Wait until all threads have terminated.
   WaitForMultipleObjects(3, threads, true, INFINITE);

   printf("Sorted output: \n");

   print_array(array1, 6);
   print_array(array2, 3);
   print_array(array3, 3);
}

Beispielausgabe

Unsorted input:
weiß weis annehmen weizen Zeit weit
Español España espantado
table tableux tablet
Sorted output:
annehmen weiß weis weit weizen Zeit
España Español espantado
table tablet tableux

Siehe auch

Suchen und Sortieren
bsearch_s
_lsearch_s
qsort