qsort_s

Esegue un ordinamento rapido. Versione di con miglioramenti della qsort sicurezza, come descritto in Funzionalità di sicurezza in CRT.

Sintassi

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

Parametri

base
Inizio della matrice di destinazione.

number
Dimensione della matrice in elementi.

width
Dimensione dell'elemento in byte.

compare
Funzione di confronto. Il primo argomento è il puntatore context . Il secondo argomento è un puntatore a key per la ricerca. Il terzo argomento è un puntatore all'elemento della matrice da confrontare con key.

context
Un puntatore a un contesto che può essere un qualsiasi oggetto a cui la routine compare deve accedere.

Osservazioni:

La funzione qsort_s implementa un algoritmo di ordinamento rapido per ordinare una matrice di number elementi, di width byte ciascuno. L'argomento base è un puntatore alla base della matrice da ordinare. qsort_s sovrascrive questa matrice con gli elementi ordinati. L'argomento compare è un puntatore a una routine fornita dall'utente che confronta due elementi di matrice e restituisce un valore che specifica la relazione. qsort_s chiama la routine compare una o più volte durante l'ordinamento, passando i puntatori a due elementi di matrice per ogni chiamata:

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

La routine deve confrontare gli elementi e quindi restituire uno dei seguenti valori:

Valore restituito Descrizione
< 0 elemento 1 minore dell'elemento 2
0 elemento 1 equivalente all'elemento 2
> 0 elemento 1 maggiore dell'elemento 2

La matrice viene ordinata in ordine crescente, come definito dalla funzione di confronto. Per ordinare una matrice in ordine decrescente, invertire il senso di "maggiore di" e "minore di" nella funzione di confronto.

Se alla funzione vengono passati parametri non validi, viene richiamato il gestore di parametri non validi, come descritto in Convalida dei parametri. Se l'esecuzione può continuare, la funzione restituisce e errno viene impostata su EINVAL. Per altre informazioni, vedereerrno, _doserrno, _sys_errliste _sys_nerr.

Per impostazione predefinita, lo stato globale di questa funzione è limitato all'applicazione. Per modificare questo comportamento, vedere Stato globale in CRT.

Condizioni di errore

key base compare num width errno
NULL qualsiasi qualsiasi qualsiasi qualsiasi EINVAL
qualsiasi NULL qualsiasi != 0 qualsiasi EINVAL
qualsiasi qualsiasi qualsiasi qualsiasi <=0 EINVAL
qualsiasi qualsiasi NULL qualsiasi qualsiasi EINVAL

qsort_s ha lo stesso comportamento di qsort ma dispone del parametro context e imposta errno. Il context parametro consente alle funzioni di confronto di usare un puntatore a oggetti per accedere alle funzionalità degli oggetti o ad altre informazioni non accessibili tramite un puntatore di elemento. L'aggiunta context del parametro rende qsort_s più sicura perché context può essere usata per evitare bug di reentrancy introdotti usando variabili statiche per rendere disponibili le informazioni condivise per la compare funzione.

Requisiti

Ciclo Intestazione obbligatoria
qsort_s <stdlib.h> e <search.h>

Per altre informazioni sulla compatibilità, vedere Compatibility (Compatibilità).

Librerie: tutte le versioni delle librerie di runtime C.

Esempio

Nell'esempio seguente viene illustrato come usare il context parametro nella qsort_s funzione . Il parametro context rende più facile eseguire ordinamenti thread-safe. Anziché utilizzare variabili statiche che devono essere sincronizzate per garantire la thread safety, passare un parametro context diverso in ogni ordinamento. In questo esempio, un oggetto delle impostazioni locali viene utilizzato come parametro context.

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

Output di esempio

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

Vedi anche

Ricerca e ordinamento
bsearch_s
_lsearch_s
qsort