执行快速排序。Performs a quick sort. 这是 qsort 版本,具有 CRT 中的安全性功能中所述的安全性增强功能。A version of qsort with security enhancements as described in Security Features in the CRT.


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


目标数组的开头。Start of target array.

元素中的数组大小。Array size in elements.

元素大小(字节)。Element size in bytes.

比较函数。Comparison function. 第一个参数是 context 指针。The first argument is the context pointer. 第二个参数是一个指向用于搜索的 key 的指针。The second argument is a pointer to the key for the search. 第三个参数是指向要与 key进行比较的数组元素的指针。The third argument is a pointer to the array element to be compared with key.

指向上下文的指针,可以是 compare 例程需要访问的任何对象。A pointer to a context, which can be any object that the compare routine needs to access.


qsort_s 函数实现了一种快速排序算法,对数组中的 num 元素(每个元素大小为 width 字节)进行排序。The qsort_s function implements a quick-sort algorithm to sort an array of num elements, each of width bytes. 参数 base 是指向待排序数组的基项的指针。The argument base is a pointer to the base of the array to be sorted. qsort_s 使用已排序元素覆盖此数组。qsort_s overwrites this array with the sorted elements. 参数 compare 是指向用户提供的例程的指针,它比较两个数组元素,并返回指定它们关系的值。The argument compare is a pointer to a user-supplied routine that compares two array elements and returns a value specifying their relationship. qsort_s 在排序过程中会一次或多次调用 compare 例程,将指针传递给每个调用中的两个数组元素:qsort_s calls the compare routine one or more times during the sort, passing pointers to two array elements on each call:

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

该例程必须比较这些元素,然后返回下列值之一:The routine must compare the elements and then return one of the following values:

返回值Return value 描述Description
< 0< 0 elem1 小于 elem2elem1 less than elem2
00 elem1 等效于 elem2elem1 equivalent to elem2
> 0> 0 elem1 大于 elem2elem1 greater than elem2

数组按比较函数中定义的升序进行排序。The array is sorted in increasing order, as defined by the comparison function. 若要以降序对数组进行排序,请反转比较函数中的“大于”和“小于”的意义。To sort an array in decreasing order, reverse the sense of "greater than" and "less than" in the comparison function.

如果传递给此函数的参数无效,则将调用无效的参数处理程序,如参数验证中所述。If invalid parameters are passed to the function, the invalid parameter handler is invoked, as described in Parameter Validation. 如果允许执行继续,则返回函数并将 errno 设置为 EINVALIf execution is allowed to continue, then the function returns and errno is set to EINVAL. 有关详细信息,请参阅 errno、_doserrno、_sys_errlist 和 _sys_nerrFor more information, see errno, _doserrno, _sys_errlist, and _sys_nerr.

错误条件Error Conditions

密钥key basebase comparecompare numnum 宽度width errnoerrno
NULL 任何any 任何any 任何any 任何any EINVAL
任何any NULL 任何any != 0!= 0 任何any EINVAL
任何any 任何any 任何any 任何any <= 0<= 0 EINVAL
任何any 任何any NULL 任何any 任何any EINVAL

qsort_s 具有与 qsort 相同的行为,但其具有 context 参数并设置了 errnoqsort_s has the same behavior as qsort but has the context parameter and sets errno. 通过传递 context 参数,比较函数可以使用对象指针来访问对象功能或通过元素指针无法访问的其他信息。By passing a context parameter, comparison functions can use an object pointer to access object functionality or other information not accessible through an element pointer. 添加context参数将使得qsort_s更为安全,因为context可用于避免重新进入 bug 引入使用静态变量要共享的信息提供给compare函数。The addition of the context parameter makes qsort_s more secure because context can be used to avoid reentrancy bugs introduced by using static variables to make shared information available to the compare function.


例程Routine 必需的标头Required header
qsort_s <stdlib.h> 和 <search.h><stdlib.h> and <search.h>

有关其他兼容性信息,请参见“简介”中的 兼容性For additional compatibility information, see Compatibility in the Introduction.

库: CRT 库功能的所有版本。Libraries: All versions of the CRT Library Features.


下面的示例演示如何使用context中的参数qsort_s函数。The following example demonstrates how to use the context parameter in the qsort_s function. context 参数更易于执行线程安全排序。The context parameter makes it easier to perform thread-safe sorts. 请在每个排序中传递不同的 context 参数(不要使用必须同步的静态变量)来确保线程安全。Instead of using static variables that must be synchronized to ensure thread safety, pass a different context parameter in each sort. 在此示例中,区域设置对象被用作 context 参数。In this example, a locale object is used as the context parameter.

// 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"  


#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"  


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


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");  

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


示例输出Sample Output

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  

请参阅See Also

搜索和排序 Searching and Sorting
bsearch_s bsearch_s
_lsearch_s _lsearch_s