If this lab is confusing right now, we’ll be talking more about this stuff on Monday.

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. Rename it properly, and upload to thoth.

Open it and read the comments. All of them.


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 function

The less_than_50 function should interpret its parameter as a pointer to a float, and as the name implies, return a “true” (nonzero) value 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 comparison function in the qsort.c example to get an idea of how to write this.

Hint: in C, comparison operators give an integer value. They give 1 if they’re true, and 0 if they’re false.


Writing the filter function

You didn’t read the comments, did you. 😤

Have a look at the 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

memset is used to fill in a blob of bytes with a value. 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.

But there’s a catch: you can’t do pointer arithmetic on void pointers either!!

So if you want to move a void* over by n bytes, you have to:

All this can be done on one line. Don’t overcomplicate things.

Good luck, but some likely mistakes:

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

there are 10 numbers 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 numbers 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 numbers less than 50:
	19.60
	0.00
	...etc...

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

there are 0 numbers 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.