qsort_s
Hızlı bir sıralama gerçekleştirir. CRT'deki Güvenlik özellikleri bölümünde açıklandığı gibi güvenlik geliştirmeleri içeren sürümüqsort
.
Sözdizimi
void qsort_s(
void *base,
size_t num,
size_t width,
int (__cdecl *compare )(void *, const void *, const void *),
void * context
);
Parametreler
base
Hedef dizinin başlangıcı.
number
Öğelerdeki dizi boyutu.
width
Bayt cinsinden öğe boyutu.
compare
Karşılaştırma işlevi. İlk bağımsız değişken işaretçidir context
. İkinci bağımsız değişken, arama için işaretçidir key
. Üçüncü bağımsız değişken, ile key
karşılaştırılacak dizi öğesinin işaretçisidir.
context
Yordamın erişmesi gereken herhangi bir nesne compare
olabilecek bir bağlam işaretçisi.
Açıklamalar
işlevi, qsort_s
baytların her width
biri olan bir öğe dizisini number
sıralamak için bir hızlı sıralama algoritması uygular. Bağımsız değişken base
, sıralanacak dizinin tabanına işaret eden bir işaretçidir. qsort_s
sıralanmış öğelerle bu dizinin üzerine yazar. Bağımsız değişken compare
, iki dizi öğesini karşılaştıran ve ilişkilerini belirten bir değer döndüren, kullanıcı tarafından sağlanan yordamın işaretçisidir. qsort_s
compare
sıralama sırasında yordamı bir veya daha fazla kez çağırır ve her çağrıda iki dizi öğesine işaretçiler geçirir:
compare( context, (void *) & elem1, (void *) & elem2 );
Yordamın öğeleri karşılaştırması ve ardından aşağıdaki değerlerden birini döndürmesi gerekir:
Dönüş değeri | Açıklama |
---|---|
< 0 | öğe 1 , öğe 2'den küçük |
0 | 2. öğeye eşdeğer öğe 1 |
> 0 | öğe 1 , öğe 2'den büyük |
Dizi, karşılaştırma işlevi tarafından tanımlandığı gibi artan düzende sıralanır. Bir diziyi azalan düzende sıralamak için karşılaştırma işlevinde "büyüktür" ve "küçüktür" hissini ters çevirin.
İşleve geçersiz parametreler geçirilirse, Parametre doğrulama bölümünde açıklandığı gibi geçersiz parametre işleyicisi çağrılır. Yürütmenin devam etmesi için izin verilirse işlev döndürülerek errno
olarak EINVAL
ayarlanır. Daha fazla bilgi için bkz. errno
, _doserrno
, _sys_errlist
ve _sys_nerr
.
Varsayılan olarak, bu işlevin genel durumunun kapsamı uygulama olarak belirlenmiştir. Bu davranışı değiştirmek için bkz. CRT'de Genel durum.
Hata koşulları
anahtar | temel | compare | Num | width | errno |
---|---|---|---|---|---|
NULL |
herhangi bir | herhangi bir | herhangi bir | herhangi bir | EINVAL |
herhangi bir | NULL |
herhangi bir | != 0 | herhangi bir | EINVAL |
herhangi bir | herhangi bir | herhangi bir | herhangi bir | <= 0 | EINVAL |
herhangi bir | herhangi bir | NULL |
herhangi bir | herhangi bir | EINVAL |
qsort_s
ile aynı davranışa qsort
sahiptir, ancak parametresine context
ve kümelerine errno
sahiptir. context
parametresi, karşılaştırma işlevlerinin nesne işlevselliğine erişmek için nesne işaretçisi kullanmasına veya öğe işaretçisi aracılığıyla erişilmeyen diğer bilgilere izin verir. Parametresinin context
eklenmesi daha güvenli hale gelir qsort_s
çünkü context
paylaşılan bilgileri işlev için kullanılabilir hale getirmek için statik değişkenler kullanılarak ortaya konulan yeniden giriş hatalarını önlemek için compare
kullanılabilir.
Gereksinimler
Yordam | Gerekli başlık |
---|---|
qsort_s |
<stdlib.h> ve <search.h> |
Daha fazla uyumluluk bilgisi için bkz . Uyumluluk.
Kitaplıklar: C çalışma zamanı kitaplıklarının tüm sürümleri.
Örnek
Aşağıdaki örnekte işlevinde parametresinin context
nasıl kullanılacağı gösterilmektedir qsort_s
. parametresi, context
iş parçacığı açısından güvenli sıralamalar gerçekleştirmeyi kolaylaştırır. İş parçacığı güvenliğini sağlamak için eşitlenmesi gereken statik değişkenleri kullanmak yerine, her sıralamada farklı context
bir parametre geçirin. Bu örnekte parametre olarak context
bir yerel ayar nesnesi kullanılır.
// 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);
}
Örnek çıktı
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