Failure to use pointer array in C

Viewed 179

I'm trying to create an array of pointers which is to be used as an array of different data types.

Here, I've created the array arr to hold 5 pointers, each of which points to a different variable. a is an int, b is a float, c is a char, d is a string, fun is a function.

#include <stdio.h>
#include <float.h>
#include <string.h>

void fun(){
    printf("this is a test function");
}

int main() {
    int *arr[5];
    int a = 10;
    float b = 3.14;
    char c = 'z';
    char d[] = "hello";
    arr[0] = &a;
    arr[1] = &b;
    arr[2] = &c;
    arr[3] = &d;
    arr[4] = &fun;

    printf("a : %d\n", *arr[0]);
    printf("b : %d\n", *arr[1]);
    printf("c : %d\n", *arr[2]);
    printf("d : %d\n", *arr[3]);
    *arr[4];

    return 0;
}

I'm trying to get it to print out the values of a, b, c, and d, then execute the function fun. However, I'm getting errors like:

warning: assignment from incompatible pointer type [-Wincompatible-pointer-types]
     arr[1] = &b;

for arr[1], arr[2], arr[3], and arr[4].

Clarification: I'm trying to make an array (or, after all the comments and answers so far, an object type like struct or union) able to hold objects of different data types, including variables, functions, structs, etc. The data types are assumed to be known. I simply want to store different data types and use them in 1 object, like an array.

4 Answers

This is what you need to do:

#include <stdio.h>
#include <float.h>
#include <string.h>

void fun(){
    printf("this is a test function");
}

int main() {
    void *arr[5];
    int a = 10;
    float b = 3.14;
    char c = 'z';
    char d[] = "hello";
    arr[0] = &a;
    arr[1] = &b;
    arr[2] = &c;
    arr[3] = &d;
    arr[4] = fun;

    printf("a : %d\n", *((int *) arr[0]));
    printf("b : %f\n", *((float *) arr[1]));
    printf("c : %c\n", *((char *) arr[2]));
    printf("d : %s\n", (char *) arr[3]);

    void (*f)() = arr[4];
    f();

    return 0;
}

arr is an array of 5 pointers to void (or anything). While printing the elements, you have to cast them to the types that they actually are. For example, arr[3] is a pointer to an array (since you are taking the address of d). Since, the address of the first element is same as the start of the array, we can cast it to a pointer to a char before printing.

For the function (note that just using fun will give you the address of the function), I have assigned the address to f which is a pointer to a function accepting an unspecified arg list and returning void. Then you can invoke f().

That's the gist. Read a good book for more information.

This could be a possible use-case for a union, which would allow you to store pointers to different types:

#include <stdio.h>
#include <float.h>
#include <string.h>

void fun(){
    printf("this is a test function");
}

union u {
    int *i;
    float *f;
    char *c;
    char *s;
    void (*fn)();
};

int main() {
    union u arr[5];
    int a = 10;
    float b = 3.14;
    char c = 'z';
    char d[] = "hello";
    arr[0].i = &a;
    arr[1].f = &b;
    arr[2].c = &c;
    arr[3].s = &d;
    arr[4].fn = &fun;

    printf("a : %d\n", *arr[0].i);
    printf("b : %f\n", *arr[1].f);
    printf("c : %c\n", *arr[2].c);
    printf("d : %s\n", arr[3].s);
    (*arr[4].fn)();

    return 0;
}

You still need to keep track of which element contains what actual type, but at least the casting is not necessary, the type is actually guaranteed to be able to hold anything you want to put in it, and the fields help keep track of what you're doing.

You can change int *arr[] to void *arr[], It will work at the time of assignment level, but when you are printing you cannot cast void to int, it will throw error.

You cannot assign an integer pointer to the address of a variable which is other than an integer data type.

You can change the datatype of all the variables to integer datatype or use a generic pointer for working.

Related