Online Book Reader

Home Category

Mastering Algorithms With C - Kyle Loudon [15]

By Root 1609 0
to data, point to executable code or to blocks of information needed to invoke executable code. They are used to store and manage functions as if they were pieces of data. Function pointers have a type that is described in terms of a return value and parameters that the function accepts. Declarations for function pointers look much like declarations for functions, except that an asterisk ( * ) appears before the function name, and the asterisk and name are surrounded by parentheses for reasons of associativity. For example, in the following code, match is declared as a pointer to a function that accepts two void pointers and returns an integer:

int (*match)(void *key1, void *key2);

This declaration means that we can set match to point to any function that accepts two void pointers and returns an integer. For example, suppose match_int is a function that accepts two void pointers to integers and returns 1 if the integers match, or otherwise. Assuming the previous declaration, we could set match to point to this function by executing the following statement:

match = match_int;

To execute a function referenced by a function pointer, we simply use the function pointer wherever we would normally use the function itself. For example, to invoke the function referenced by match earlier, we execute the following statement, assuming x, y, and retval have been declared as integers:

retval = match(&x, &y);

One important use of function pointers in this book is to encapsulate functions into data structures. For example, in the implementation of chained hash tables (see Chapter 8), the data structure has a match member similar to the function pointer just described. This pointer is used to invoke a function whenever we need to determine whether an element we are searching for matches an element in the table. We assign a function to this pointer when the table is initialized. The function we assign has the same prototype as match but internally compares two elements of the appropriate type, depending on the type of data in the table for which the table has been defined. Using a pointer to store a function as part of a data structure is nice because it is yet another way to keep an implementation generic.

Questions and Answers


Q: One of the difficulties with pointers is that often when we misuse them, our errors are not caught by the compiler at compile time; they occur at runtime. Which of the following result in compile-time errors? Which of the following result in runtime errors? Why?

a)

char *sptr = "abc",*tptr;

*tptr = sptr;

b)

char *sptr = "abc",*tptr;

tptr = sptr;

c)

char *sptr = "abc",*tptr;

*tptr = *sptr;

d)

int *iptr = (int *)10;

*iptr = 11;

e)

int *iptr = 10;

*iptr = 11;

f )

int *iptr = (int *)10;

iptr = NULL;

A: a) A compile-time error occurs because when we dereference tptr, we get a character, whereas sptr is a pointer to a character. Thus, the code is trying to assign a character pointer to a character, which is a type conflict. b) No error occurs because both tptr and sptr are character pointers. c) A runtime error is likely to occur because no storage has been allocated for tptr. When we dereference tptr, we cannot be sure where it points. d) A runtime error is likely to occur because assigning an integer pointer a fixed address is dangerous. When dereferencing iptr, we try to write 11 at address 10, which is probably invalid. e) A compile-time error or warning occurs because the code is trying to initialize an integer pointer to an integer, which is a type conflict. f ) No error occurs because although the code first performs the dangerous step of initializing iptr to a fixed address, it is then immediately reset to NULL, which is valid.

Q: Recall that calculations with pointers are performed using pointer arithmetic. If p contains the address 0x10000000, what address does the following expression access? How many bytes are accessed at this address?

*(p + 5)

A: The answer to this question depends on the type of p. Recall that when we add an integer i to a pointer p, the result

Return Main Page Previous Page Next Page

®Online Book Reader