![]() |
![]() |
![]() |
![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() |
![]() |
![]() |
[an error occurred while processing this directive]
How It Works Lets look at MAIN.CPP first. The first source line includes the declarations and definitions of the C Standard Library. The function qsort is also declared in it. The second source line includes the prototype of the function printf() that is used in this program. The third line includes the prototype of compare, which is discussed in detail soon. #include <stdlib.h> #include <stdio.h> #include compare.h The first source line inside the body of main() defines an array of 10 integers. The array is initialized with 10 random values. The value 9 appears twice, and a negative value appears to test the robustness of qsort. int iarr[10] = {9, 83, 100, 1, 645, -7645, 4, 23, 543, 9}; Next, a loop control variable is defined and initialized to 0. int j = 0; /* loop counter */ The following for statement displays the elements of iarr before sorting. for(; j < 10; j++) /* display array before sorting */ printf (element %d of iarr is: %d\n, j, iarr[j]); After the elements of iarr are displayed, they are sorted using qsort: qsort( iarr, 10, sizeof (int), compare); qsort takes four arguments. Lets examine the role of each one of them. The first argument is the address of the array to be sorted. As you probably know, the name of an array in C/C++ is equivalent to its address. In other words, the argument iarr is equivalent to the expression &iarr[0]. The second argument is the number of elements in the array. The third argument is the size of a single element in the array. Because the size of an int is implementation dependent, an expression that returns the correct size of an int is always used. The fourth argument is the most interesting one. It will be discussed when the two other source files are analyzed. For now, suffice it to say the fourth argument is the address of a comparison function called by qsort. Having sorted iarr, the program displays the sorted array. But before that is done, it resets the loop counter j. j = 0; /* reset loop counter */ Now the sorted array can display. Again, use a for loop to traverse the elements of iarr and display each one of them. for(; j < 10; j++) /* display sorted array */ printf (element %d of iarr is: %d\n, j, iarr[j]); In this example, qsort is applied to a built-in data type. However, qsort is a generic function. It can be applied to any data type. What makes this genericity work? The short answera callback function. Callback Functions A callback function is one not invoked explicitly by the programmer; rather, the responsibility for its invocation is delegated to another function that receives the address of the callback function. Before a demonstration of how it is done in this particular example, some basic facts are necessary about the way functions are stored in memory. Data Pointers Versus Code Pointers C and C++ make a clear-cut distinction between two types of pointersdata pointers and code pointers. The memory layout of a function is very different from the memory layout of a variable. Without delving too deeply into low-level machine architecture, a function consists of several components such as a list of arguments, a return-to address, and machine instructions. A data pointer, on the other hand, only holds the address of the first byte of a variable. The substantial difference between data pointers and code pointers led the C standardization committee to prohibit the use of data pointers to represent function pointers and vice versa. In C++ this restriction was relaxed, yet the results of coercing a function pointer to a void pointer are implementation dependent. Conversion of data pointers to function pointers is, of course, a recipe for a core dump. Recall also that unlike a data pointer, a function pointer cannot be dereferenced, and that you cannot pass a function by value. Platforms have a different underlying representation for code pointers and data pointers. In some architectures, a 16-bit address can be used to hold the address of a data variable, whereas a larger unit will hold a function address. A data pointer declaration contains a specific data type to which the pointer can point. Thus, a pointer to char can only point to a variable of type char. Similarly, a function pointer declaration contains a specific signature to which the pointer can be assigned. For example, a pointer to a function that takes no arguments and returns an int can only be assigned to a function that has the same signature. It is illegal to assign an address of a function with a different signature to such a pointer. As you saw earlier, the fourth argument of qsort is a pointer to a callback function. However, you are free to pass an argument with the address of any function you want to, as long as that function conforms to an agreed-upon signature. The expected signature is specified in the prototype of qsort. Lets have a look at it: void qsort(void *, size_t, size_t, int (cmp*)(const void *, const void *)); The highlighted part in the prototype is the signature of the expected function pointer. Unfortunately, function pointers have a most intricate syntax, for both humans and compilers. Still, they are a very capable feature in C/C++they are the basis for dynamic binding. Dynamic binding, also termed late binding, is a delayed resolution of which function is invoked. The resolution is delayed until runtime, as opposed to compile-time resolution. The most prominent manifestation of dynamic binding is virtual member functions in C++. The syntax of a function pointer is very similar to the prototype of a function. To see that, lets examine the following statement: void f (); This statement declares a function named f that takes no arguments and does not return a value. A pointer to such a function has the following type: void (*) ();
|
![]() |
Products | Contact Us | About Us | Privacy | Ad Info | Home
Use of this site is subject to certain Terms & Conditions, Copyright © 1996-1999 EarthWeb Inc. All rights reserved. Reproduction whole or in part in any form or medium without express written permision of EarthWeb is prohibited.
|