Compartir a través de


qsort_s

Realiza una ordenación rápida. Una versión de qsort con mejoras de seguridad, como se describe en Características de seguridad en CRT.

Sintaxis

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

Parámetros

base
Inicio de la matriz de destino.

number
Tamaño de la matriz en elementos.

width
Tamaño del elemento en bytes.

compare
Función de comparación. El primer argumento es el puntero de context . El segundo argumento es un puntero a la key de la búsqueda. El tercer argumento es un puntero al elemento de matriz que va a comparar con key.

context
Puntero a un contexto, que puede ser cualquier objeto al que la rutina compare deba obtener acceso.

Comentarios

La función qsort_s implementa un algoritmo de ordenación rápida para ordenar una matriz de number elementos, cada uno de width bytes. El argumento base es un puntero a la base de la matriz que se va a ordenar. qsort_s sobrescribe esta matriz con los elementos ordenados. El argumento compare es un puntero a una rutina proporcionada por el usuario que compara dos elementos de la matriz y devuelve un valor que especifica su relación. qsort_s llama a la rutina compare una o varias veces durante la ordenación y pasa los punteros a dos elementos de la matriz en cada llamada:

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

La rutina debe comparar los elementos y luego devolver uno de los siguientes valores:

Valor devuelto Descripción
< 0 elemento 1 menor que el elemento 2
0 elemento 1 equivalente al elemento 2
> 0 elemento 1 mayor que el elemento 2

La matriz se clasifica en orden ascendente, de acuerdo con la función de comparación. Para clasificar una matriz en orden decreciente, invierta el sentido de "mayor que" y "menor que" en la función de comparación.

Si se pasan parámetros no válidos a la función, se invoca el controlador de parámetros no válidos, como se describe en Validación de parámetros. Si la ejecución puede continuar, la función devuelve y errno se establece en EINVAL. Para obtener más información, veaerrno, _doserrno, _sys_errlisty _sys_nerr.

De manera predeterminada, el estado global de esta función está limitado a la aplicación. Para cambiar este comportamiento, consulte Estado global en CRT.

Condiciones del error

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

qsort_s tiene el mismo comportamiento que qsort, pero tiene el parámetro context y establece errno. El context parámetro permite que las funciones de comparación usen un puntero de objeto para tener acceso a la funcionalidad del objeto u otra información no accesible a través de un puntero de elemento. La adición del context parámetro hace qsort_s más segura porque context se puede usar para evitar errores de reentrada introducidos mediante variables estáticas para que la información compartida esté disponible para la compare función.

Requisitos

Routine Encabezado necesario
qsort_s <stdlib.h> y <search.h>

Para obtener más información sobre compatibilidad, consulte Compatibilidad.

Bibliotecas: todas las versiones de las bibliotecas en tiempo de ejecución de C.

Ejemplo

En el ejemplo siguiente se muestra cómo usar el context parámetro en la qsort_s función . El parámetro context facilita la ejecución de ordenaciones seguras para los subprocesos. En lugar de usar variables estáticas que deben estar sincronizadas para garantizar la seguridad de los subprocesos, pase otro parámetro context en cada ordenación. En este ejemplo, se usa un objeto de configuración regional como parámetro 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);
}

Salida de ejemplo

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

Consulte también

Búsqueda y ordenación
bsearch_s
_lsearch_s
qsort