3

Can someone explain what is going on here in this question?

Print 1 to 100 with out loop and conditions in C

What is the theory or possible low-level explanation to

void(*ptr[2])() = {blah, blah2};

I'm new to C, and I would like to know what is going on here ;)

Thank's in advance.

P.S: I searched around a bit but unfortunately couldn't find anything.

Community
  • 1
  • 1
  • 5
    You've copied it wrong; it should be `void (*ptr[2])() = ...`. – ecatmur Apr 03 '13 at 09:51
  • possible duplicate of [How to understand complicated function declarations?](http://stackoverflow.com/questions/1448849/how-to-understand-complicated-function-declarations) – user93353 Apr 03 '13 at 10:35

6 Answers6

7

It's just an array of function pointers with two elements - ptr[0] points to the function blah() and ptr[1] points to the function blah2().

You can call each function like this:

(ptr[0])(); // call blah()

(ptr[1])(); // call blah2()
Paul R
  • 208,748
  • 37
  • 389
  • 560
  • Hmm, well, I got that so far, but what I'm trying to get is that can we just say that the functions are stored in the memory like variables and because of both functions are `void`s, so we can create two `void` pointers to point to that "places" where the functions are stored? – john hackman Apr 03 '13 at 09:54
  • 1
    No - they're not *pointers to void*, they are *pointers to functions returning void* (or they would be if you hadn't made a mistake when you copied the code - it should be `void (*ptr[2])() = { blah, blah2 };` - note the missing parentheses in your question). – Paul R Apr 03 '13 at 09:55
7

Do you mean how do I read this?

You discarded some useful context from the original answer, so let's repair that:

void print();
void exitme();

int main() {
    void (*p[2])()={print,exitme};

so now it's obvious that print and exitme refer to functions. Specifically, they both return void and take no arguments, so they share the function pointer type

void (*)()

(that is, a function pointer of that type can point to either print or exitme). For example,

void (*print_or_exit)() = (rand() % 2) ? print : exitme;
print_or_exit(); // who knows what it will do!

Now, an array of two of these function pointers looks like:

void (*ptr[2])()

and can be initialized as:

void (*ptr[2])() = { print, exitme };

so now we can rewrite our stupid example as:

void (*print_or_exit)() = ptr[rand() % 2];
Useless
  • 64,155
  • 6
  • 88
  • 132
2
void(*ptr[2])()

Declares an array of function pointers, where blah and blah2 are the functions that are pointed to. In this case the functions that are pointed to must have void as 'return type' (ie they must not return anything) and must not have any parameters (due to the () at the end of the declaration).

The example code you link to, uses these function pointers to either print the value of i or exit the application (when i = 100 and i/100 result in 1, which is the second array element)

As the example shows you can call a function using the function liek this:

i = 0; // or 1 (as your array has a size of 2)
(ptr[i])();

Note: the example could be considered (very) bad practice, so please do not use it instead of a simple for-loop! :)

Veger
  • 37,240
  • 11
  • 105
  • 116
2

That is declaring ptr as an array of two function pointers, and initializing them to point to the two functions blah() and blah2(), respectively.

The parenthesis are needed to protect it from becoming a declaration of void * (void pointers), which would be something else.

unwind
  • 391,730
  • 64
  • 469
  • 606
2

This is an array of function-pointers. You are initializing it with the addresses of the two functions blah and blah2.

bash.d
  • 13,029
  • 3
  • 29
  • 42
1

ptr is an array of pointers to a function that doesn't return any value and has no arguments.

in general, ptr[1] is calling to exitme function, which calls exit(1) and ptr[0] calls to a function that handles the printing. the variable i is static so its usage ends when the program quits.

at the first iteration, there is a new memory block allocated for array of two pointers that points to exitme and print functions (actually at each iteration, this is done, not like with the i). then, a static variable i is declared and initialized to zero (for sure in ansi-c), later the first function called (print) because i++/100 is 0.001 but it's equal to 0 (because neither a cast has been done nor they are float) and on the same time i is being increased. after calling print and printing the value of i, we call again to main and this keeps iterating, til i gets to 100.

note that there are two static integers i but each one has different scope, therefore, they have different values.

thus you print 1...100 without using loop.

boaz_shuster
  • 2,825
  • 20
  • 26