执行快速排序。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


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

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

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

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

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


Qsort_s函数可实现快速排序算法进行排序的数组元素,每个宽度字节。The qsort_s function implements a quick-sort algorithm to sort an array of number elements, each of width bytes. 自变量是指向要进行排序的数组的基类的指针。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. 自变量比较是指向用户提供比较两个数组元素并返回一个值,指定其关系的例程的指针。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调用比较排序,将指针传递给两个数组元素,在每次调用例程的一个或多个期间: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
NULLNULL 任何any 任何any 任何any 任何any EINVALEINVAL
任何any NULLNULL 任何any != 0!= 0 任何any EINVALEINVAL
任何any 任何any 任何any 任何any <= 0<= 0 EINVALEINVAL
任何any 任何any NULLNULL 任何any 任何any EINVALEINVAL

qsort_s具有相同的行为qsort但具有上下文参数和集errnoqsort_s has the same behavior as qsort but has the context parameter and sets errno. 通过将传递上下文参数,比较函数可用于的对象指针访问对象功能或无法访问其他信息通过一个元素的指针。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. 添加上下文参数将使得qsort_s更为安全,因为上下文可用于避免引起使用静态变量进行的重新进入 bug共享信息供比较函数。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_sqsort_s <stdlib.h> 和 <search.h><stdlib.h> and <search.h>

有关其他兼容性信息,请参阅 兼容性For additional compatibility information, see Compatibility.

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


下面的示例演示如何使用上下文中的参数qsort_s函数。The following example demonstrates how to use the context parameter in the qsort_s function. 上下文参数,更便于进行线程安全的排序。The context parameter makes it easier to perform thread-safe sorts. 而不是使用必须进行同步以确保线程安全的静态变量,将传递一个不同上下文中每个排序的参数。Instead of using static variables that must be synchronized to ensure thread safety, pass a different context parameter in each sort. 在此示例中,用作区域设置对象上下文参数。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