Pointers are super important when writing low-level programs! GET COMFORTABLE WITH EM!

In this lab, you’ll be writing a generic array-filtering function. This will make use of pointer arithmetic, function pointers, and pointer casting. This is an actually useful function! Filtering values out of an array is a very common operation.

Starting off

Get the starting file here.

Open it and read the comments.


Predicates

“Predicate” is a common programming term which means “something that gives a yes-or-no answer.”

The filter function’s predicate must be a function which:


Writing the predicate functions

The less_than_50 function should interpret its parameter as a pointer to a float, and as the name implies, return true if it is less than 50.

Since the parameter is a const void*, you’ll have to cast the parameter to a different pointer type.

Have a look at how I wrote the compare_ints function in the qsort.c example to get an idea of how to write this.

Then implement the others:

Hint: comparison operators give you a bool. You can write e.g. return x == 10;. This is valid in C and Java.


Writing the filter function

Have a look at the first piece of code in main:

float filtered[NUM_VALUES];
int filtered_len = filter(filtered, float_values, NUM_VALUES, sizeof(float), &less_than_50);

printf("there are %d numbers less than 50:\n", filtered_len);

for(int i = 0; i < filtered_len; i++)
    printf("\t%.2f\n", filtered[i]);

Look at the float_values array and think about what the output should look like. (There are 6 numbers less than 50, right?)

The filter function should work like this:

In addition it should:

memcpy

memcpy is used to copy blobs of bytes from one place to another. It’s a very common function.

memcpy(dest, src, length);

This will copy length bytes from the memory pointed to by src into the memory pointed to by dest.

“Walking pointers”

You’re used to using [] to access values from arrays. But you can’t use [] on a void*. Instead, an easier technique is to use a “walking pointer.”

Instead of keeping a pointer to the beginning of an arrays, we move the pointer along, item by item, to access the array. Like this.

When you do pointer arithmetic on a void*, it will add or subtract a number of bytes to its address. So, you can move the pointer(s) along by adding the size of one item to them.

The correct output

Done right, the output should be:

there are 6 floats less than 50:
	31.94
	36.10
	1.00
	6.35
	20.76
	19.60
there are 3 floats that have an even whole part:
	36.10
	6.35
	20.76
there are 6 bytes less than 50:
	31
	36
	1
	6
	20
	19

Some likely mistakes:

If you don’t move the pointer along the input array, you’ll get something like:

there are 10 floats less than 50:
	31.94
	31.94
	31.94
	...etc...

If you don’t move the pointers by the right number of bytes, you might get something like:

there are 6 floats less than 50:
	127.76
	36.10
	0.00
	...etc...

If you moved the input pointer right, but forgot to move the output pointer along:

there are 6 floats less than 50:
	19.60
	0.00
	0.00
	...etc...

If you moved BOTH pointers every iteration:

there are 6 floats less than 50:
	31.94
	0.00
	36.10
	...etc...

If you didn’t count properly, or maybe you didn’t respond to the predicate properly:

there are 0 floats less than 50:

Submission

Please make sure the driver (the main function) is the default one I gave you before you submit.

Then submit as usual.