mdb@abcom.ATT.COM (5013 ) (11/07/90)
Hi, netlanders, I need help. I am building a menu using structures and would like to be able to include the function to be run within the structure. Below is an example of what I would like to do. =========================================================================== /**************************************************************************** ** ** Program : CH10.c ** Author : Michael D. Barnes ** Date Created: November 04, 1990 ** Date Revised: ** Notes : This database manager will: ** ** ADD RECORD ** FIND RECORD ** QUIT ** ** Globals used: MENU_ITEM -> Number of items in menu ** MAX_RECS -> Maximum Records in database allowed ** sorted -> Does database need to be sorted? ** phone_bk -> structure phone book data record ** menu -> structure menu data record ** ****************************************************************************/ #include <stdio.h> #include <conio.h> #include <bios.h> #include <ctype.h> #define MENU_ITEM 2 #define MAX_RECS 6 int add_rec(); int find_rec(); int quit(); unsigned int records=0; typedef struct { char key; int x_row; int y_row; char msg[20]; } MENU; MENU menu[MENU_ITEM+1] = { { '1',7,25,"Add Phone Number",add_rec() }, { '2',9,25,"Find Phone number",find_rec() }, { 'Q',12,25,"QUIT",quit() } } ; int menu_cnt=MENU_ITEM; /* What menu option is used */ main(void) { int menu_opt; disp_menu(menu,menu_cnt); while ( 1 ) { menu_opt = select(); (*(menu[menu_opt].foo))(); gotoxy ( menu[menu_cnt].y_row,menu[menu_cnt].x_row ); printf ( "%c. %s",menu[menu_cnt].key,menu[menu_cnt].msg ); gotoxy ( menu[menu_cnt].y_row,menu[menu_cnt].x_row ); } } ======================================================================= Now, how do I assigned these functions to the structure (or is it posible) and then access these same functions? Any help will be greatly appreciated. Thank for yor help in advance Mike Barnes (415) 224-3030
hagins@gamecock.rtp.dg.com (Jody Hagins) (11/08/90)
First off, this sounds like a class project, but since you are not asking for a program, but specific help, I consider this to be fine since you could find this in any C book. I used to teach, and I would not have a problem with this type of assistance. In article <2203@abcom.ATT.COM>, mdb@abcom.ATT.COM (5013 ) writes: |> Hi, netlanders, |> |> I need help. I am building a menu using structures and would like |> to be able to include the function to be run within the structure. |> |> Below is an example of what I would like to do. |> =========================================================================== |> /**************************************************************************** |> ** |> ** Program : CH10.c |> ** Author : Michael D. Barnes |> ** Date Created: November 04, 1990 |> ** Date Revised: |> ** Notes : This database manager will: |> ** |> ** ADD RECORD |> ** FIND RECORD |> ** QUIT |> ** |> ** Globals used: MENU_ITEM -> Number of items in menu |> ** MAX_RECS -> Maximum Records in database allowed |> ** sorted -> Does database need to be sorted? |> ** phone_bk -> structure phone book data record |> ** menu -> structure menu data record |> ** |> ****************************************************************************/ |> |> #include <stdio.h> |> #include <conio.h> |> #include <bios.h> |> #include <ctype.h> |> |> #define MENU_ITEM 2 |> #define MAX_RECS 6 |> |> int add_rec(); |> int find_rec(); |> int quit(); |> |> unsigned int records=0; |> typedef struct { |> char key; |> int x_row; |> int y_row; |> char msg[20]; int (*foo)(); /* You need to have this field */ |> } MENU; |> |> MENU menu[MENU_ITEM+1] = { |> { '1',7,25,"Add Phone Number",add_rec() }, |> { '2',9,25,"Find Phone number",find_rec() }, |> { 'Q',12,25,"QUIT",quit() } |> } ; Remove the ()'s from the above assignments of add_rec(), find_rec(), and quit(). |> |> int menu_cnt=MENU_ITEM; /* What menu option is used */ |> |> main(void) |> { |> |> int menu_opt; |> disp_menu(menu,menu_cnt); |> |> while ( 1 ) |> { |> |> menu_opt = select(); |> (*(menu[menu_opt].foo))(); This should work now. However, keep in mind that menu[menu_opt].foo is a pointer to a function of type int. Don't try to mix function pointer types. Also, remember that you need to pass parms in the ()'s if they are needed. |> gotoxy ( menu[menu_cnt].y_row,menu[menu_cnt].x_row ); |> printf ( "%c. %s",menu[menu_cnt].key,menu[menu_cnt].msg ); |> gotoxy ( menu[menu_cnt].y_row,menu[menu_cnt].x_row ); |> } |> } |> ======================================================================= |> Now, how do I assigned these functions to the structure (or is it posible) |> and then access these same functions? Any help will be greatly appreciated. |> |> |> |> Thank for yor help in advance |> |> Mike Barnes |> (415) 224-3030
gwyn@smoke.brl.mil (Doug Gwyn) (11/09/90)
In article <2203@abcom.ATT.COM> mdb@abcom.ATT.COM (5013 ) writes:
-> int add_rec();
-> int find_rec();
-> int quit();
-> unsigned int records=0;
-> typedef struct {
-> char key;
-> int x_row;
-> int y_row;
-> char msg[20];
int (*foo)(); /* ADD THIS MEMBER */
-> } MENU;
-> MENU menu[MENU_ITEM+1] = {
-> { '1',7,25,"Add Phone Number",add_rec() },
/* CHANGE THE ABOVE TO: */
{ '1', 7, 25, "Add phone number", add_rec },
[...]
-> } ;
[...]
-> menu_opt = select();
-> (*(menu[menu_opt].foo))();
/* That's okay although excessively parenthesized. */
wallace@ynotme.enet.dec.com (Ray Wallace) (11/10/90)
In article <2203@abcom.ATT.COM>, mdb@abcom.ATT.COM (5013 ) writes... > I need help. I am building a menu using structures and would like > to be able to include the function to be run within the structure. Change your menu structure to have - void (*foo)(); /* Pointer to a function returning void */ Change your function call to - menu[menu_opt].foo(); --- Ray Wallace (INTERNET,UUCP) wallace@oldtmr.enet.dec.com (UUCP) ...!decwrl!oldtmr.enet!wallace (INTERNET) wallace%oldtmr.enet@decwrl.dec.com ---
john@chinet.chi.il.us (John Mundt) (11/10/90)
In article <2203@abcom.ATT.COM> mdb@abcom.ATT.COM (5013 ) writes: > I need help. I am building a menu using structures and would like > to be able to include the function to be run within the structure. .... > >int add_rec(); >int find_rec(); >int quit(); > >unsigned int records=0; >typedef struct { > char key; > int x_row; > int y_row; > char msg[20]; int (*fptr)(); /* add this to your structure prototype */ >} MENU; > >MENU menu[MENU_ITEM+1] = { > { '1',7,25,"Add Phone Number",add_rec }, > { '2',9,25,"Find Phone number",find_rec }, > { 'Q',12,25,"QUIT",quit } > } ; Notice that the ()'s were removed from the functions. > >Now, how do I assigned these functions to the structure (or is it posible) >and then access these same functions? Any help will be greatly appreciated. The functions are now assigned, so that menu[whatever].fptr is the function. You can use the function thusly, { int some_value; some_value = (*menu[whatever].fptr)(); } since menu[whatever].fptr is the address of the function, and *menu[whatever].fptr is the function. K&R says it better. Lint and/or your compiler may or may not complain about this. Seems to depend on the machine. 3b2's like it, 3b1's do not. 386's don't like it, but in all cases it works. As an aside, some_value = (*menu[whatever].fptr)(); some_value = (menu[whatever].fptr)(); produce the same assembler code on at least one machine, and both work, though the first one is the one that is considered correct. -- --------------------- john@admctr.chi.il.us John Mundt Teachers' Aide, Inc. P.O. Box 1666, Highland Park, IL (708) 998-5007 || -432-8860
gwyn@smoke.brl.mil (Doug Gwyn) (11/12/90)
In article <1990Nov10.155153.20639@chinet.chi.il.us> john@chinet.chi.il.us (John Mundt) writes: > some_value = (*menu[whatever].fptr)(); > some_value = (menu[whatever].fptr)(); >produce the same assembler code on at least one machine, and both >work, though the first one is the one that is considered correct. Actually the second one is more "theoretically" correct. The function designator in the first expression is automatically converted to a pointer to the function; the second form is already that way.
scjones@thor.UUCP (Larry Jones) (11/14/90)
In article <14431@smoke.brl.mil>, gwyn@smoke.brl.mil (Doug Gwyn) writes: > [ about whether "(*pf)() or (pf)() is more correct ] > > Actually the second one is more "theoretically" correct. The function > designator in the first expression is automatically converted to a > pointer to the function; the second form is already that way. That depends on which theory you subscribe to. In classic C, you called a function -- there was no automatic conversion to a pointer -- and the first form was thus "theoretically" correct. The second form was, at least for some compilers, "completely" wrong -- they refused to generate code when presented with that construct. Of course, we all know that you use the address to call a function so it makes much more sense to say that a call is made using a pointer to the function and having the name of a function decay into a function pointer like the name of an array decays into a pointer to the first element. That's precisely what X3J11 did, although both decays were generalize to expressions of the specified type rather than special casing names. ---- Larry Jones UUCP: uunet!sdrc!thor!scjones SDRC scjones@thor.UUCP 2000 Eastman Dr. BIX: ltl Milford, OH 45150-2789 AT&T: (513) 576-2070 Don't you hate it when your boogers freeze? -- Calvin