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.   ## 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    