0

This is just a test, just to understand how it works.But I cant understand why im getting this output.

#include <stdio.h>

void f(void *a[]){
    for(int t=0; t<5;t++){
        printf("--%d--",a[t]);
    }
}

void main(void){
    int a[5]={1,2,3,4,5};
    f(a);
}

so Im getting this output:

--1----3----5----428351232----4195936--

Theredone
  • 55
  • 1
  • 6

3 Answers3

2

You are telling the function to expect an array of void* pointers. Also the function return value is incorrect, and the loop increment is unusual. Try this:

#include <stdio.h>

int f(int a[]){
    int r = 0;
    for(int t = 0; t < 5; t++){
        printf("--%d--", a[t]);
    }
    return r;
}

void main(void){
    int a[5]= { 1, 2, 3, 4, 5};
    f(a);
}

Program output:

--1----2----3----4----5--

These faults would have been revealed to you if you enabled all compiler warnings.

Weather Vane
  • 33,872
  • 7
  • 36
  • 56
  • Ok, but how can i make a function that takes an array of unknown type and goes throught the array printing the elements? thats why i used int array to test how that works out but i cant understand whats wrong.Or how i can manage it. – Theredone Aug 30 '16 at 14:29
  • If the array is of unknown type, how can you decide which format specifier to use, and how can the compiler know the size of the array elements? You are using `%d` so you *do* know the type. – Weather Vane Aug 30 '16 at 14:31
  • @Theredone Typically by using "functors", essentially function pointers to the specific behavior that should be invoked for the specific type. Check for example how the standard C function `bsearch` works. Alternatively, with the latest C standard you can do various tricks with the `_Generic` keyword. [Here](http://stackoverflow.com/questions/33905692/combining-generic-macros/33995823#33995823) is some discussion about the topic. Please note that this is somewhat advanced stuff, beyond beginner-level. – Lundin Aug 30 '16 at 14:33
  • Im just assuming in this test that is int.My actual problem isnt the length or the type.Im just trying to find out the syndax. in order to make a function that searches the existance of an element in an array of same type, which type is unknown.So im getting in trouble when im trying to use an unknown type of array as parameter in function – Theredone Aug 30 '16 at 14:39
  • @Theredone, no. If you want to pass an array of unknown type values, you cannot pass an array of `void *` pointers. The undefined behaviour you got is from the fact that `void *` type is 8 bytes length in your architecture and you are passing a reference to an array of `int`s (which are four bytes length in a 64bit low endian architecture like yours). `void *` is valid to represent *a reference to unknown type*, not an unknown type by itself. You cannot assume you are passing unkowns, and then treat them as completely known. Somewhere you have to do a trick to do that. – Luis Colorado Sep 01 '16 at 05:42
1

Per your title, you want a function that accepts an array whose element type is unknown to the function. There is no such function, because no array is ever passed as a function argument in C. Instead, if an expression designating a function argument evaluates to an array, that array further "decays" to a pointer to the first element of the array, and it is the pointer that is passed. Indeed, arrays decay to pointers in nearly all contexts.

Do not be fooled: C allows you to specify function parameter types via syntax that designates arrays in other places, but that is a convenience feature. The actual parameter types designated that way are the corresponding pointer types. That allows you to write matching variable and function parameter declarations if you wish to do so.

Now, since it's not your array of unknown (to the function) type that is passed, but rather a pointer to the first element of such an array, your question boils down to "how do I designate a pointer type that can hold a pointer to any type?" That one I bet you already know: void * is the conventional way, but char * also works:

void f(void *a) {
    // ...
}

There's not much you can do with that alone, however. Compare with the interface to the standard library function qsort(), which indeed accepts just such a pointer. For it to be able to use the pointer, it also takes arguments designating the size of each array element and the number of elements, and for its particular purposes it also accepts a pointer to a function suitable for comparing those elements.

Update:

Following the qsort() model, if you want a function that prints the elements of any array, you might do this:

void print_elements(void *first, size_t element_size, size_t element_count,
        void (*print_element)(void *)) {
    char *element = first;  // pointer arithmetic is not allowed on void *

    for (size_t index = 0; index < element_count; index++) {
        print_element(element);
        element += element_size;
    }
}

You could then use it like this:

void print_int(void *intp) {
    printf("--%d--", *((int *) intp));
}

void main(void){
    int a[5] = { 1, 2, 3, 4, 5 };

    print_elements(a,
            sizeof(a[0]),              // The size of each element
            sizeof(a) / sizeof(a[0]),  // The number of elements
            print_int);                // A pointer to a suitable print function
}
John Bollinger
  • 160,171
  • 8
  • 81
  • 157
  • Thanks for your advices, and i can see that my title and what I ask isn't that exact. So, Im asked to create a function in C that takes an element of unknown type and an array of the same type as parameters(obviously including the legth of the array), returns 1 if the element exist in the array otherwise 0.Sorry about the confusion and inaccurate questions.I just used this test.c program to test the syndax i may use. – Theredone Aug 30 '16 at 14:54
  • 1
    Similarly with the library function `fread`. It takes a `void*` argument but it also needs to be told the element size and their number. If it were otherwise possible, then functions like `qsort` and `fread` would be doing it. – Weather Vane Aug 30 '16 at 14:57
  • @Theredone, I added an example. For your particular purpose, however, you probably don't need the function pointer. Instead, you can use `memcmp()` to compare known-size blocks of memory without knowing what type of data they represent. I have no intention of doing your homework for you, however, so I leave the details to you. – John Bollinger Aug 30 '16 at 15:04
  • Thanks! this looks helping. I think I was missing the knowledge about the pointer to functions so i couldnt manage this problem, and i dint know how to ask help. – Theredone Aug 30 '16 at 15:21
  • Finnaly I solved my problem and learn what i had to.Thank you! – Theredone Aug 30 '16 at 16:18
-1

In the function, you have to cast the vector back to integer, so that the compiler can know how wide are the elements of the array and it can add an appropriate offset when you want to access an element of the array.

So the correct code is:

void f(void *a[]){
    int *v=(int *) a;
    for(int t=0; t<5;t++){
        printf("--%d--",v[t]);
    }
}
Davide Visentin
  • 735
  • 5
  • 19
  • Nope. At least, not on any machine where the size of an `int` differs from the size of a `void *`, which is the majority of them these days. Moreover, relying on casting undermines the whole point that the function doesn't know the data type. – John Bollinger Aug 30 '16 at 15:08
  • You are right, but given that he wrote printf("--%d--",a[t]), I assumed that in the function he know which is the type of the array. This is the tipical template used when you have to create a pthread passing a void *f(void *) function. – Davide Visentin Aug 30 '16 at 15:14
  • Now I've understood the first part of your comment. That was a typing error; I wrote int v instead of int *v. Now I fix it. – Davide Visentin Aug 30 '16 at 15:17