What is qsort_s in C?
The qsort_s function
The qsort_s function sorts an array in ascending order based on the comparison function that is passed to qsort_s. Unlike the qsort function, qsort_s requires a context to be passed to it as well. The structure of the qsort_s function is:
errno_t qsort_s (void * ptr, rsize_t count, rsize_t size, int (*comp)(const void *, const void *, void *), void *context )
Parameters
ptris the pointer to the array you want to sort.countis the number of elements in the array.sizeis the size of each element in the array in bytes.compis a comparison function that returns:- Negative integer if the left argument is less than the right argument.
- Positive integer if the left argument is greater than the right argument.
- Zero if the left argument is equal to the right argument.
int cmp(const void *a, const void *b);
contextis a pointer to any object that needs to be passed to thecompfunction.
Return value
- Zero upon success.
- Non-zero if a runtime error is encountered.
Example usage of the qsort_s function
The following code sorts an array in ascending and descending order with the qsort_s function:
#include<stdio.h>#include<stdlib.h>int compare_integers(const void * a, const void * b, void * context) {int result = 0;int intA = *(const int *)a;int intB = *(const int *)b;if (intA > intB) result = 1;if (intA < intB) result = -1;int dsc_order = *(int *)context;if (dsc_order) result *= -1;return result;}void print_array(const int * arr, const int size) {for (int i = 0; i < size; i++) {printf("%d ", arr[i]);}printf("\n");}int main() {int arr1[] = {3, -1, 5, 1, 4, 0, 2};int arr2[] = {3, -1, 5, 1, 4, 0, 2};int size = (sizeof arr1) / (sizeof * arr1);int dsc_order1 = 0;int dsc_order2 = 1;printf("arr1 Before Sorting: ");print_array(arr1, size);printf("arr2 Before Sorting: ");print_array(arr2, size);qsort_s(arr1, size, sizeof(int), compare_integers, &dsc_order1);qsort_s(arr2, size, sizeof(int), compare_integers, &dsc_order2);printf("arr1 After Sorting: ");print_array(arr1, size);printf("arr2 After Sorting: ");print_array(arr2, size);return 0;}
In the above example, two arrays, arr1 and arr2, are sorted in ascending and descending order. The qsort_s function only sorts in ascending order, but by using the context pointer, the function is able to sort in descending order as well.
Let’s take a closer look at the above code snippet:
Both arrays have the same seven elements in them: 3 -1 5 1 4 0 2. To determine the number of elements in the array on runtime, we use the following expression in line 30:
(sizeof arr1) / (sizeof * arr1).
The sizeof keyword returns the number of bytes in an array or a variable. Since an int type has 4 bytes, sizeof * arr1 evaluates to 4 (because * arr1 refers to the first element in arr1, which is an int). So, the expression in line 30 simplifies to 28 / 4, which results in 7, the number of elements in the array.
The compare_integers function takes in two constant pointers (a and b) with type void, and another pointer (context) with type void. The compare_integers function returns 1 if a>b, 0 if a==b, and -1 if a<b, provided that the value of context is 0. In the case that context is a non-zero value, the return values of a>b and a<b are swapped.
Note: Here, the value means the value of the memory location to which the pointers point.
The comparison in the function above can only take place if a and b are of comparable types (e.g., int). To ensure this, we cast a and b to const int * and then reference their value by using the * operator. Next, we store them in intA and intB respectively. Now, the comparisons are made using variables intA and intB.
Note: We also cast and reference
contextin line 12 to treat its value as an integer.
Finally, we call the qsort_s function on both arr1 and arr2 with the respective parameters in lines 40 and 41. Notice that we pass reference of the variables dsc_order1 and dsc_order2, respectively, because the qsort_s function requires a pointer, not a value. The qsort_s function uses the compare_integers function to sort the array in ascending order, but the context, which is passed by the qsort_s function to the compare_integers function, allows us to swap the return values of a>b and a<b. Therefore, it allows us to sort in descending order using the qsort_s function.
Free Resources