Dave win wrote:

I'm confused with the expression "(float *())".

Book says that this is a cast. But, I have no idea of this expr.

why could this expr ignore the variable???

Sometimes you want to create something that doesn't know what it is

dealing with. You can just hand it some random data in void pointers

(that is, a pointer that officially just points to "some unknown

something, maybe") plus some extra info which tells you precisely what

that void* is supposed to point to.

For example in the below example, I keep an array of void pointers to

all of my math functions. Then I have an array of desired operations

which, in conjunction with the type of my datatype, I use to access the

array of math functions.

#define TYPE_INT 0

#define TYPE_FLOAT 1

struct genericNumber { /*a generic variable type that can pretend to be

any kind of number*/

int type; /*what type it should be interpretted as*/

int intVal;

float floatVal;

};

#define OP_ADD 0 /*possible operations*/

#define OP_SUB 1

int addInts(int a, int b) { /*a function for each operation and each

possible type of number*/

return a + b;

}

float addFloats(float a, float b) {

return a + b;

}

int subInts(int a, int b) {

return a - b;

}

float subFloats(float a, float b) {

return a - b;

}

void* funcs[] = {addInts, addFloats, subInts, subFloats}; /*keep them

in an array so that we can perform operations based on some sort of

script instead of hard coded functionality*/

int opCount = 5;

int ops[] = {OP_ADD, OP_ADD, OP_SUB, OP_ADD, OP_SUB}; /*operations we

want to perform and the order we want to perform them*/

int main(void) {

int L;

struct genericNumber a;

struct genericNumber b;

a.type = TYPE_INT;

a.intVal = 5;

b.type = TYPE_FLOAT;

b.floatVal = 3.0f;

/*run all operations, indexing into our function array based on

operation and variable type. Righthand parameter will be cast to be the

same as lefthand. The result of the operation will be written back into

the variable that was the lefthand parameter (a)*/

for (L = 0; L < opCount; L++) {

if (a.type == TYPE_INT) {

if (b.type == TYPE_INT) {

a.intVal = ((int (*)(int, int))funcs[ops[L] <<

1])(a.intVal, b.intVal); /*cast our void* to a function of the correct

type. We are assuming that all of our math is correct and that our

functions are similarly all in the right order in our function array*/

}

else if (b.type == TYPE_FLOAT) {

int temp = (int)b.floatVal;

a.intVal = ((int (*)(int, int))funcs[ops[L] <<

1])(a.intVal, temp);

}

}

else if (a.type == TYPE_FLOAT) {

if (b.type == TYPE_INT) {

float temp = (float)b.floatVal;

a.floatVal = ((float (*)(float, float))funcs[(ops[L] << 1])

+ 1)(a.floatVal, temp);

}

else if (b.type == TYPE_FLOAT) {

a.floatVal = ((float (*)(float, float))funcs[(ops[L] <<

1]) + 1)(a.floatVal, b.floatVal);

}

}

}

return 0;

}

This is the kind of thing I can imagine you might do if you were

building the engine for a scripting language that used generic variable

types. If you just assume that for every operation there will only be

two inputs and one output, then you would parse the script code and

create arrays of generic variables, lefthand and righthand parameters,

what variable to assign the result to, and what operation to perform.

Voila, Perl.

* note that I just wrote that code in there and have not tested, so no

guarantees that it works correctly.

-Chris