Trusted answers to developer questions
Trusted Answers to Developer Questions

Related Tags

c

What is qsort_s in C?

Hammad Nasir

Grokking Modern System Design Interview for Engineers & Managers

Ace your System Design Interview and take your career to the next level. Learn to handle the design of applications like Netflix, Quora, Facebook, Uber, and many more in a 45-min interview. Learn the RESHADED framework for architecting web-scale applications by determining requirements, constraints, and assumptions before diving into a step-by-step design process.

Answers Code

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

  • ptr is the pointer to the array you want to sort.
  • count is the number of elements in the array.
  • size is the size of each element in the array in bytes.
  • comp is 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);
  • context is a pointer to any object that needs to be passed to the comp function.

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 context in 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.

RELATED TAGS

c

CONTRIBUTOR

Hammad Nasir
Copyright ©2022 Educative, Inc. All rights reserved

Grokking Modern System Design Interview for Engineers & Managers

Ace your System Design Interview and take your career to the next level. Learn to handle the design of applications like Netflix, Quora, Facebook, Uber, and many more in a 45-min interview. Learn the RESHADED framework for architecting web-scale applications by determining requirements, constraints, and assumptions before diving into a step-by-step design process.

Answers Code
Keep Exploring