qsort_s

Melakukan pengurutan cepat. Versi qsort dengan peningkatan keamanan seperti yang dijelaskan dalam Fitur keamanan di CRT.

Sintaks

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

Parameter

base
Awal array target.

number
Ukuran array dalam elemen.

width
Ukuran elemen dalam byte.

compare
Fungsi perbandingan. Argumen pertama adalah penunjuk context . Argumen kedua adalah penunjuk ke key untuk pencarian. Argumen ketiga adalah penunjuk ke elemen array yang akan dibandingkan dengan key.

context
Penunjuk ke konteks, yang dapat menjadi objek apa pun yang compare perlu diakses oleh rutinitas.

Keterangan

Fungsi ini qsort_s mengimplementasikan algoritma pengurutan number cepat untuk mengurutkan array elemen, masing-masing width byte. Argumen base adalah penunjuk ke dasar array yang akan diurutkan. qsort_s menimpa array ini dengan elemen yang diurutkan. Argumen compare adalah penunjuk ke rutinitas yang disediakan pengguna yang membandingkan dua elemen array dan mengembalikan nilai yang menentukan hubungan mereka. qsort_scompare memanggil rutinitas satu atau beberapa kali selama pengurutan, meneruskan penunjuk ke dua elemen array pada setiap panggilan:

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

Rutinitas harus membandingkan elemen lalu mengembalikan salah satu nilai berikut:

Nilai hasil Deskripsi
< 0 elemen 1 kurang dari elemen 2
0 elemen 1 setara dengan elemen 2
> 0 elemen 1 lebih besar dari elemen 2

Array diurutkan dalam urutan yang meningkat, seperti yang didefinisikan oleh fungsi perbandingan. Untuk mengurutkan array dalam urutan yang menurun, balikkan rasa "lebih besar dari" dan "kurang dari" dalam fungsi perbandingan.

Jika parameter yang tidak valid diteruskan ke fungsi, handler parameter yang tidak valid dipanggil, seperti yang dijelaskan dalam Validasi parameter. Jika eksekusi diizinkan untuk melanjutkan, maka fungsi akan kembali, dan errno diatur ke EINVAL. Untuk informasi selengkapnya, lihat errno, _doserrno, _sys_errlist, dan _sys_nerr.

Secara default, status global fungsi ini dicakup ke aplikasi. Untuk mengubah perilaku ini, lihat Status global di CRT.

Kondisi kesalahan

kunci dasar compare num lebar 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_s memiliki perilaku yang sama seperti qsort tetapi memiliki context parameter dan set errno. Parameter context memungkinkan fungsi perbandingan menggunakan penunjuk objek untuk mengakses fungsionalitas objek atau informasi lain yang tidak dapat diakses melalui penunjuk elemen. Penambahan context parameter menjadi qsort_s lebih aman karena context dapat digunakan untuk menghindari bug reentransi yang diperkenalkan dengan menggunakan variabel statis untuk membuat informasi bersama tersedia untuk fungsi.compare

Persyaratan

Rutin Header yang diperlukan
qsort_s <stdlib.h> dan <search.h>

Untuk informasi kompatibilitas selengkapnya, lihat Kompatibilitas.

Pustaka: Semua versi pustaka runtime C.

Contoh

Contoh berikut menunjukkan cara menggunakan context parameter dalam qsort_s fungsi . Parameter context memudahkan untuk melakukan pengurutan utas yang aman. Alih-alih menggunakan variabel statis yang harus disinkronkan untuk memastikan keamanan utas, berikan parameter yang berbeda context di setiap jenis. Dalam contoh ini, objek lokal digunakan sebagai 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"

#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);
}

Sampel 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

Baca juga

Mencari dan mengurutkan
bsearch_s
_lsearch_s
qsort