C Typecasting, Void Pointers, Function Pointers
C Typecasting, Void Pointers, and Function Pointers
This code demonstrates typecasting, void pointers, and function pointers in C.
Typecasting
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void typecasts()
{
int i = 107;
float f = 3.14159;
int *iptr = &i;
float *fptr = &f;
printf("No cast, correct deref: int = %d, float = %f\n", *iptr, *fptr);
printf("Wrong cast: deref int as float = %f, float as int = %d\n", *(float *)iptr, *(int *)fptr);
printf("Wrong cast: deref int as string = '%s', float as string = '%s' \n\n", (char *)iptr, (char *)fptr);
}
The typecasts function shows the effects of correct and incorrect typecasting when dereferencing pointers. Casting a pointer to a different type and then dereferencing it can lead to unexpected results, as the underlying data is interpreted differently.
Generic Count Functions
The following functions count occurrences of a key in arrays of different types:
count_int: Counts integers.count_float: Counts floats.count_char: Counts characters.count_string: Counts strings (char*).
int count_int(int arr[], int n, int key)
{
int count = 0;
for (int i = 0; i < n; i++) {
if (arr[i] == key) count++;
}
return count;
}
int count_float(float arr[], int n, float key)
{
int count = 0;
for (int i = 0; i < n; i++) {
if (arr[i] == key) count++;
}
return count;
}
int count_char(char arr[], int n, char key)
{
int count = 0;
for (int i = 0; i < n; i++) {
if (arr[i] == key) count++;
}
return count;
}
int count_string(char *arr[], int n, char *key)
{
int count = 0;
for (int i = 0; i < n; i++) {
if (strcmp(arr[i],key)==0) count++;
}
return count;
}
A generic gcount function is introduced to handle different data types using void*:
int gcount(void *arr, int n, size_t elemsz, void *key)
{
int count = 0;
for (int i = 0; i < n; i++) {
void *ith = (char *)arr + i*elemsz; // Cast to char* for pointer arithmetic
if (memcmp(ith, key, elemsz) == 0) count++;
}
return count;
}
gcount uses void* to accept any type of array. It calculates the address of each element using pointer arithmetic (casting to char* is essential for correct byte-level manipulation) and compares elements using memcmp.
Testing Count Functions
void test_contains(int nwords, char *words[])
{
int scores[] = {88, 94, 70, 92, 83, 92, 1, 92};
int nscores = sizeof(scores)/sizeof(scores[0]);
int score_key = 92;
float prices[5] = {3.99, 195, 181.50};
int nprices = sizeof(prices)/sizeof(prices[0]);
float float_key = 3.5f; //Added f to make it a float literal
char letters[] = "CS107 rocks my world!";
int nletters = strlen(letters);
int letter_key = 'o';
char *word_key = words[0];
printf("Count %d = %d\n", score_key, count_int(scores, nscores, score_key));
printf("Count %d = %d\n", score_key, gcount(scores, nscores, sizeof(scores[0]), &score_key));
printf("Count %g = %d\n", float_key, count_float(prices, nprices, float_key));
printf("Count %c = %d\n", letter_key, count_char(letters, nletters, letter_key));
printf("Count %s = %d\n", word_key, count_string(words, nwords, word_key));
}
test_contains demonstrates both the type-specific count functions and the generic gcount function.
Function Pointers and qsort
int cmp_int(const void *a, const void *b)
{
int one = *(int *)a, two = *(int *)b;
if (one < two) return -1;
if (one > two) return 1;
return 0;
}
void test_fnptr(int argc, char *argv[])
{
int nums[] = {40, 19, 23, 45, 12, 45, 23, 99, 53, 12, 78};
int count = sizeof(nums)/sizeof(nums[0]);
qsort(nums, count, sizeof(nums[0]), cmp_int);
printf("\nArray of numbers: ");
for (int i = 0; i < count; i++) {
printf("%d ", nums[i]);
}
printf("\n");
printf("\nArray of strings: ");
for (int i = 0; i < argc; i++) {
printf("%s ", argv[i]);
}
printf("\n");
}
cmp_int is a comparison function suitable for use with qsort. It takes two const void* arguments, casts them to int*, and compares the underlying integer values. test_fnptr demonstrates using qsort to sort an array of integers and prints the sorted array. It also prints the command-line arguments.
Main Function
int main(int argc, char *argv[])
{
typecasts();
test_contains(argc-1, argv+1);
test_fnptr(argc-1, argv+1);
return 0;
}
The main function calls the demonstration functions.
