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 do qsort com aprimoramentos de segurança, conforme descrito em Recursos de segurança no CRT.
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.num
Tamanho da matriz nos elementos.width
Tamanho do elemento em bytes.compare
Função de comparação.O primeiro argumento é o context ponteiro.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, o que pode ser qualquer objeto que o compare rotina precisa acessar.
Comentários
O qsort_s função implementa um algoritmo de classificação de rápida para classificar uma matriz de num elementos, cada um dos width bytes.O argumento base é um ponteiro para a base da matriz a ser classificado.qsort_ssubstitui essa matriz com os elementos classificados.O argumento compare é um ponteiro para uma rotina fornecido pelo usuário que compara dois elementos de matriz e retorna um valor especificando seu relacionamento.qsort_schamadas de compare rotina um ou mais vezes durante a classificação, passando os 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 de Retorno |
Descrição |
|---|---|
< 0 |
elem1menor queelem2 |
0 |
elem1equivalente aelem2 |
> 0 |
elem1maior queelem2 |
A matriz é classificada em ordem, crescente, conforme definido pela função de comparação.Para classificar uma matriz em ordem decrescente, reverta o sentido de "maior que" e "less than" na função de comparação.
Se os parâmetros inválidos são passados para a função, o manipulador de parâmetro inválido é invocado, conforme descrito em Validação de parâmetro.Se a execução terá permissão para continuar, então a função retornará e errno for definido como EINVAL.Para obter mais informações, consulte errno, _doserrno, _sys_errlist e _sys_nerr.
Condições de erro
key |
Base |
Comparar |
num |
largura |
errno |
|---|---|---|---|---|---|
NULL |
any |
any |
any |
any |
EINVAL |
any |
NULL |
any |
!= 0 |
any |
EINVAL |
any |
any |
any |
any |
< = 0 |
EINVAL |
any |
any |
NULL |
any |
any |
EINVAL |
qsort_stem o mesmo comportamento como qsort , mas tem o context parâmetro e conjuntos de errno.Passando um context parâmetro, funções de comparação podem usar um ponteiro de objeto para acessar a funcionalidade do objeto ou outras informações não pode ser acessadas por meio de um ponteiro de elemento.A adição da context parâmetro torna qsort_smais segura porque context pode ser usado para evitar bugs de reentrância introduzidos pelo uso de variáveis estáticas para disponibilizar informações compartilhadas para o compare função.
Requisitos
Rotina |
Cabeçalho necessário |
|---|---|
qsort_s |
<stdlib.h> e <search.h> |
Para obter informações adicionais de compatibilidade, consulte Compatibilidade na introdução.
Bibliotecas: todas as versões da Recursos da biblioteca CRT.
Exemplo
O exemplo a seguir demonstra como usar o context parâmetro na qsort_sfunção.O context parâmetro torna mais fácil realizar classificações de thread-safe.Em vez de usar variáveis estáticas que devem ser sincronizadas para garantir a segurança do thread, passar uma diferente context parâmetro em cada classificação.Neste exemplo, um objeto de localidade é usado como o context parâmetro.
// 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