table of function calls: need sample code

R

Roman Mashak

Hello, All!

I started to implement simple command line interface (CLI), and wanna
know how to use table of fucntion calls. Could you please, recommend me some
link or give example directly in conference?

Thanks in advance!

With best regards, Roman Mashak. E-mail: (e-mail address removed)
 
M

Me

I started to implement simple command line interface (CLI), and wanna
know how to use table of fucntion calls. Could you please, recommend me some
link or give example directly in conference?

Not the greatest example in the world but it should get you started:

#include <stdlib.h>
#include <stdio.h>

enum NextThing { GET, PRINT, BYEBYE };

enum NextThing nextThing;
int ch;

void get()
{
ch = getc(stdin);
nextThing = (ch != EOF) ? PRINT : BYEBYE;
}

void byebye() { exit(0); }

void print() { fputc(ch, stdout); nextThing = GET; }

void (* const ftable[])() = {
get,
print,
byebye
};

int main()
{
for (;;)
ftable[nextThing]();
return 0;
}
 
R

Roman Mashak

Hello, Me!
You wrote on 7 Jun 2005 22:49:49 -0700:

M> enum NextThing { GET, PRINT, BYEBYE };

M> enum NextThing nextThing;
M> int ch;

M> void get()
M> {
M> ch = getc(stdin);
M> nextThing = (ch != EOF) ? PRINT : BYEBYE;
M> }

M> void byebye() { exit(0); }

M> void print() { fputc(ch, stdout); nextThing = GET; }

M> void (* const ftable[])() = {
M> get,
M> print,
M> byebye
M> };

M> int main()
M> {
M> for (;;)
M> ftable[nextThing]();
M> return 0;
M> }

I'm not sure I understood well - how will the function 'ftable[nextThing]()'
know what index to pickup? Could ypu please clear up this?

With best regards, Roman Mashak. E-mail: (e-mail address removed)
 
M

Me

M> enum NextThing { GET, PRINT, BYEBYE };

GET==0
PRINT==1
BYEBYE==2

we use these to index into the ftable array
M> enum NextThing nextThing;

nextThing initialized to GET, so the get function is the first one we
call.
M> int ch;

M> void get()
M> {
M> ch = getc(stdin);
M> nextThing = (ch != EOF) ? PRINT : BYEBYE;
M> }

Read a character from stdin and save it in the global variable ch. If
we reached the end, call the byebye function on the next iteration,
else call the print function
M> void byebye() { exit(0); }

exit(0) quits the program. This will terminate the infinite loop down
in main
M> void print() { fputc(ch, stdout); nextThing = GET; }

print ch out and and call get on the next iteration to read another
character. You can see we are bouncing back and forth between get and
print until we reach the end of the stream.
M> void (* const ftable[])() = {
M> get,
M> print,
M> byebye
M> };

ftable[GET] == &get
ftable[PRINT] == &print
ftable[BYEBYE] == &byebye

To make the type easier to understand, you can also use typedefs:

typedef void (*FN)(void);

FN is a pointer to a function taking no parameters and returning
nothing

FN ftable[3] = { get, print, byebye };

ftable is a 3 element array of function pointers
M> int main()
M> {
M> for (;;)
M> ftable[nextThing]();
M> return 0;
M> }

I'm not sure I understood well - how will the function 'ftable[nextThing]()'
know what index to pickup? Could ypu please clear up this?

ftable is an array of function pointers (you can't create an array of
functions by the way for various reasons). You index it with nextThing
as the index. The print and get functions modify the nextThing index
depending on the state. For example:

void (*fnptr)() = ftable[1];

copies the function pointer at ftable[1] (&print in this case) over to
the variable fnptr. Now, we can call the function by using fnptr(). You
could have also called it without the temporary variable by using
ftable[1]().

You should probably step through this code with a debugger to examine
what's going on at each step if you still don't get it.
 
J

Jens.Toerring

Roman Mashak said:
Hello, Me!
You wrote on 7 Jun 2005 22:49:49 -0700:
enum NextThing { GET, PRINT, BYEBYE };
enum NextThing nextThing;
int ch;
void get()
{
ch = getc(stdin);
nextThing = (ch != EOF) ? PRINT : BYEBYE;
}
void byebye() { exit(0); }
void print() { fputc(ch, stdout); nextThing = GET; }
void (* const ftable[])() = {
get,
print,
byebye
};
int main()
{
for (;;)
ftable[nextThing]();
return 0;
}
I'm not sure I understood well - how will the function 'ftable[nextThing]()'
know what index to pickup? Could ypu please clear up this?

'ftable' isn't a function but an array of function pointers. And
'ftable[nextThing]' is a pointer to the element with index 'nextThing'
in this array, which, of course, is a function pointer. When you write
a function pointer followed by parentheses then the function this
pointer points to gets invoked. So the line

ftable[ 0 ]( );

is a call of get(),

ftable[ 1 ]( );

is a call of print() and, finally,

ftable[ 2 ]( );

is a call of byebye().

And 'nextThing' is a global variable, so it's initialized automatically
to 0 and the first thing done in main is calling get(). And in get() as
well as print() 'nextThing' always gets assigned a new value print()
sets it to 0 each time and in get() it gets set according to the user
input (either to 1 or 2).
Regards, Jens
 
R

Roman Mashak

Hello, Me!
You wrote on 8 Jun 2005 06:05:38 -0700:

M> copies the function pointer at ftable[1] (&print in this case) over to
M> the variable fnptr. Now, we can call the function by using fnptr(). You
M> could have also called it without the temporary variable by using
M> ftable[1]().

Thanks very much to you and Jens Thoms Toerring for detailed explanation!

Regarding to my program (simple command line interface).
The command line has the following style:
<cmd_action> <arg1> <arg2> ... <argN>

I'm going to use 2 tables (arrays): one will contain <cmd_action> names and
the second will contain the functions pointers processing every command (i
guess it's correct way). It means I'll need some keys for finding matches
between tables, right?

So, waht I'd like to know is how can I implement this in C, I'm not quite
sure about keys in tables...

Anyway, thanks for any advice!

With best regards, Roman Mashak. E-mail: (e-mail address removed)
 
M

Me

Regarding to my program (simple command line interface).
The command line has the following style:
<cmd_action> <arg1> <arg2> ... <argN>

I'm going to use 2 tables (arrays): one will contain <cmd_action> names and
the second will contain the functions pointers processing every command (i
guess it's correct way). It means I'll need some keys for finding matches
between tables, right?

One way to do this is to get a complete line from stdin, this requires
dynamic array allocation (and resizing) unless you want to hardcode the
max length of a line.

The next step is to take this line and tokenize it into smaller
substrings. You're basically doing the same code that the runtime does
to convert what you type in at a terminal to run your program into the
argv array that gets passed as the 2nd parameter to main. This part is
optional, you could just pass in the whole line to the function but
then each function has to do its own parameter parsing. There are
tradeoffs to both ways but tokenizing it into smaller substrings is
probably the way to go.

The next step is to take the first substring and map it to a function.
The easiest way is to just use a bunch of if statements with strcmp (or
stricmp if your platform has it), you don't even need function pointers
for this. The other ways (which all involve function pointers) are to
keep a sorted table and use binary search, use a sorted linked list and
linearly look through it, use a hash table, use a binary tree, etc.
Once you map the string to the function, just call it with in the
tokenized array.
So, waht I'd like to know is how can I implement this in C, I'm not quite
sure about keys in tables...

The above takes a bit of code to do in C because I'm assuming you want
to learn how to do it yourself instead of using somebody else's
functions. I'd highly suggest you get this book
http://cm.bell-labs.com/cm/cs/tpop/ because it pretty much is perfect
for somebody with your experience and it covers everything you need to
know to write something like that (and then some).
 
R

Roman Mashak

Hello, Me!
You wrote on 9 Jun 2005 01:21:51 -0700:

[skip]
M> The next step is to take the first substring and map it to a function.
M> The easiest way is to just use a bunch of if statements with strcmp (or
M> stricmp if your platform has it), you don't even need function pointers
M> for this. The other ways (which all involve function pointers) are to
M> keep a sorted table and use binary search, use a sorted linked list and
M> linearly look through it, use a hash table, use a binary tree, etc.
M> Once you map the string to the function, just call it with in the
M> tokenized array.
Thanks, this is the way I assumed to follow. Frankly speaking I would not
mind to find some example source code for reference. Could you recommend me
some? For example, simple implementation of binary search, or sorted lined
list, CLI is also welcome.

All I want now - is understand some major concepts and algorithms.

With best regards, Roman Mashak. E-mail: (e-mail address removed)
 
C

CBFalconer

Roman said:
.... snip ...

Thanks, this is the way I assumed to follow. Frankly speaking I
would not mind to find some example source code for reference.
Could you recommend me some? For example, simple implementation
of binary search, or sorted lined list, CLI is also welcome.

All I want now - is understand some major concepts and algorithms.

I think the example wdfreq.c, showing a usage of the hashlib
package, will do what you want. It scans an input file, extracts
words, counts duplicates, forms a singly linked list of the
results, sorts that alphabetically and by count, and dumps the
result. It uses a stable sort, namely mergesort. Heavily
commented. You can get the whole package at:

<http://cbfalconer.home.att.net/download/hashlib.zip>
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
474,164
Messages
2,570,898
Members
47,439
Latest member
shasuze

Latest Threads

Top