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.