Observação
O acesso a essa página exige autorização. Você pode tentar entrar ou alterar diretórios.
O acesso a essa página exige autorização. Você pode tentar alterar os diretórios.
Executa uma classificação rápida. Uma versão de qsort com aprimoramentos de segurança, conforme descrito em Recursos de segurança no CRT.
Sintaxe
void qsort_s(
void *base,
size_t num,
size_t width,
int (__cdecl *compare )(void *, const void *, const void *),
void * context
);
Parâmetros
base
Início da matriz de destino.
number
Tamanho da matriz nos elementos.
width
Tamanho do elemento em bytes.
compare
Função de comparação. O primeiro argumento é o ponteiro context. O segundo argumento é um ponteiro para o key para a pesquisa. O terceiro argumento é um ponteiro para o elemento de matriz a ser comparado com key.
context
Um ponteiro para um contexto, que pode ser qualquer objeto que a rotina compare precisa acessar.
Comentários
A função qsort_s implementa um algoritmo de classificação rápida para classificar uma matriz de elementos number, cada uma de bytes width. O argumento base é um ponteiro para a base da matriz a ser classificada. qsort_s substitui essa matriz pelos elementos classificados. O argumento compare é um ponteiro para uma rotina fornecida pelo usuário que compara dois elementos de matriz e retorna um valor que especifica seu relacionamento. qsort_s chama a rotina compare uma ou mais vezes durante a classificação, passando ponteiros para dois elementos de matriz em cada chamada:
compare( context, (void *) & elem1, (void *) & elem2 );
A rotina deve comparar os elementos e, em seguida, retornar um dos seguintes valores:
| Valor retornado | Descrição |
|---|---|
| < 0 | elemento 1 menor que o elemento 2 |
| 0 | elemento 1 equivalente ao elemento 2 |
| > 0 | elemento 1 maior que o elemento 2 |
A matriz é classificada em ordem crescente, conforme definido pela função de comparação. Para classificar uma matriz em ordem decrescente, inverta o sentido de “maior que” e “menor que” na função de comparação.
Se parâmetros inválidos forem passados para a função, o manipulador de parâmetro inválido será invocado, conforme descrito em Validação de parâmetro. Se a execução tiver permissão para continuar, a função retornará e errno será definida como EINVAL. Para obter mais informações, consulte errno, _doserrno, _sys_errlist e _sys_nerr.
Por padrão, o estado global dessa função tem como escopo o aplicativo. Para alterar esse comportamento, confira Estado global no CRT.
Condições de erro
| chave | base | compare | num | width | errno |
|---|---|---|---|---|---|
NULL |
any | qualquer | qualquer | qualquer | EINVAL |
| qualquer | NULL |
any | != 0 | any | EINVAL |
| qualquer | qualquer | qualquer | any | <= 0 | EINVAL |
| any | qualquer | NULL |
qualquer | any | EINVAL |
qsort_s tem o mesmo comportamento que qsort, mas tem o parâmetro context e define errno. O context parâmetro permite que as funções de comparação usem um ponteiro de objeto para acessar a funcionalidade do objeto ou outras informações não acessíveis por meio de um ponteiro de elemento. A adição do context parâmetro torna qsort_s mais seguro porque context pode ser usado para evitar bugs de reentrância introduzidos usando variáveis estáticas para disponibilizar informações compartilhadas para a compare função.
Requisitos
| Rotina | Cabeçalho necessário |
|---|---|
qsort_s |
<stdlib.h> e <search.h> |
Para obter informações sobre compatibilidade, consulte Compatibilidade.
Bibliotecas: todas as versões das bibliotecas de runtime C.
Exemplo
O exemplo a seguir demonstra como usar o context parâmetro na qsort_s função. O parâmetro context facilita a execução de classificações thread-safe. Em vez de usar variáveis estáticas que devem ser sincronizadas para garantir o acesso thread-safe, passe um parâmetro context diferente em cada classificação. Neste exemplo, um objeto de localidade é usado como o 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);
}
Saída de exemplo
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