// Complicated declarations and definitions:
typedef void* (*vpa)[10];
vpa f1(int i);
void * (*(*fp1)(int))[10];
typedef float (*f21)(int);
f21 f23(int,int,float);
float (*(*fp2)(int,int,float))(int);
typedef double (*f3)();
typedef f3 (*a3)[10];
a3 fa3(); // function declaration
typedef double (*(*(*fp3)())[10])();
fp3 a = &fa3; // fp3 a = fa3; // global variable a (pointer to function)
a3 aa = (*a)();
a3 aaa = a();
typedef int (*fp4)();
typedef fp4 (*a4)[10];
int (*(*f4())[10])();
int main()
{
vpa a; // local variable a (pointer to array)
fp1 = &f1; // fp1 = f1;
a = (*fp1)(0);
a = fp1(0);
a = (*f1)(0);
a = f1(0);
fp2 = &f23; // fp2 = f23;
(*fp2)(0,0,0);
fp2(1,2,3);
(*f23)(0,0,0);
f23(1,2,3);
(*::a)(); // global a (pointer to function)
::a(); // `::' accesses the global namespace
(*f4)();
f4();
return 0;
}
// Function definitions:
vpa f1(int i)
{
vpa a;
return a;
}
f21 f23(int i, int j, float f)
{
f21 a;
return a;
}
a3 fa3()
{
a3 a;
return a;
}
a4 f4()
{
a4 a;
return a;
}
/*
g++ ComplDefs.cpp -o ComplDefs
./ComplDefs
*/
****************************************************************************************
****************************************************************************************
****************************************************************************************
****************************************************************************************
****************************************************************************************
// Defining and using a pointer to a function
#include <iostream>
using std::cout;
using std::endl;
void func();
int main()
{
void (*fp1)(); // Define a function pointer
fp1 = &func; // fp1 = func; // Initialize it
(*fp1)(); // Dereferencing calls the function, func()
fp1(); // alternate way to call the function
(*func)();
func();
void (*fp2)() = func; // Define and initialize
fp2 = fp1; // nothing changes, both pointers point to func()
// fp2 = &fp1; // compile error, both are pointers
(*fp2)(); // function call, func()
fp2 = &func;
fp2(); // same function call
return 0;
}
void func()
{
cout << "func() called..." << endl;
}
/*
g++ PointerToFunction.cpp -o PointerToFunction
./PointerToFunction
func() called...
func() called...
func() called...
func() called...
func() called...
func() called...
*/
****************************************************************************************
****************************************************************************************
****************************************************************************************
****************************************************************************************
****************************************************************************************
Exercise 3-32. Define a function that takes a double argument and returns an int. Create and initialize a pointer to this function, and call the function through your pointer.
// Defining and using a pointer to a function
#include <iostream>
using std::cout;
using std::endl;
int truncate(double);
int main()
{
int (*fp1)(double); // Define a function pointer
fp1 = &truncate; // fp1 = truncate; // Initialize it
cout << (*fp1)(1.1) << endl; // Dereferencing calls the function, truncate()
cout << fp1(1.2) << endl; // alternate way to call the function
cout << (*truncate)(2.4) << endl;
cout << truncate(2.5) << endl;
int (*fp2)(double) = truncate; // Define and initialize
fp2 = fp1; // nothing changes, both pointers point to truncate()
// fp2 = &fp1; // compile error, both are pointers
cout << (*fp2)(1.5) << endl; // function call, truncate()
fp2 = &truncate;
cout << fp2(1.6) << endl; // same function call
return 0;
}
int truncate(double d)
{
return int(d); // (int)d;
}
/*
g++ FunctionPointer.cpp -o FunctionPointer
./FunctionPointer
1
1
2
2
1
1
*/
****************************************************************************************
****************************************************************************************
****************************************************************************************
****************************************************************************************
****************************************************************************************
Exercise 3-33. Declare a pointer to a function taking an int argument and returning a pointer to a function that takes a char argument and returns a float.
#include <iostream>
using std::cout;
using std::endl;
float fc (char);
typedef float (*fpc)(char);
fpc fi (int);
int main()
{
float (*(*fpi)(int))(char); // complicated function pointer declaration
// fpc (*fpi)(int); // simpler alternative declaration
fpi = &fi; // fpi = fi; // initialize pointer
fpc a = (*fpi)(0);
a = &fc; // a = fc;
cout << "(*a)(0): " << (*a)(0) << ", a(1): " << a(1) << endl;
fpc b = fpi(1);
b = fc; // b = &fc;
cout << "(*b)(0): " << (*b)(0) << ", b(1): " << b(1) << endl;
a = (*fi)(0);
a = fc;
cout << "(*a)(1): " << (*a)(1) << ", a(2): " << a(2) << endl;
b = fi(1);
b = &fc;
cout << "(*b)(1): " << (*b)(1) << ", b(2): " << b(2) << endl;
return 0;
}
float fc (char c)
{
float f = c*2;
return f;
}
fpc fi (int i)
{
fpc a;
cout << "fi(" << i << ")" << endl;
return a;
}
/*
g++ ComplDecl.cpp -o ComplDecl
./ComplDecl
fi(0)
(*a)(0): 0, a(1): 2
fi(1)
(*b)(0): 0, b(1): 2
fi(0)
(*a)(1): 2, a(2): 4
fi(1)
(*b)(1): 2, b(2): 4
*/
****************************************************************************************
****************************************************************************************
****************************************************************************************
****************************************************************************************
****************************************************************************************
// Using an array of pointers to functions
#include <stdio.h> // for printf(), getchar()
// A macro to define dummy functions:
#define DF(N) void N() \
{printf("Function %s() called...\n", #N);}
DF(a); DF(b); DF(c); DF(d); DF(e); DF(f); DF(g); // semicolons not required here
void (*func_table[])() = {a, b, c, d, e, f, g};
int main()
{
char c;
while(1)
{
printf("Press a key from 'a' to 'g' or 'q' to quit\n");
c = getchar(); getchar(); // second one for newline (ENTER)
if (c == 'q') {break;} // out of while(1)
if (c < 'a' || c > 'g') {continue;} // function not defined
// else 'a' <= c <= 'g'
(*func_table[c - 'a'])();
func_table[c - 'a'](); // same function call
}
return 0;
}
/*
gcc function_table.c -o function_table
./function_table
Press a key from 'a' to 'g' or 'q' to quit
0
Press a key from 'a' to 'g' or 'q' to quit
h
Press a key from 'a' to 'g' or 'q' to quit
a
Function a() called...
Function a() called...
Press a key from 'a' to 'g' or 'q' to quit
g
Function g() called...
Function g() called...
Press a key from 'a' to 'g' or 'q' to quit
c
Function c() called...
Function c() called...
Press a key from 'a' to 'g' or 'q' to quit
q
*/
****************************************************************************************
****************************************************************************************
****************************************************************************************
// Using an array of pointers to functions
#include <iostream>
using std::cout;
using std::cin;
using std::endl;
// A macro to define dummy functions:
#define DF(N) void N() \
{cout << "Function " #N "() called..." << endl;}
DF(a); DF(b); DF(c); DF(d); DF(e); DF(f); DF(g); // semicolons not required here
void (*func_table[])() = {a, b, c, d, e, f, g};
int main()
{
char c, cr; // CR - carriage return or newline
while(1) // while(true)
{
cout << "Press a key from 'a' to 'g' or 'q' to quit" << endl;
cin.get(c); cin.get(cr); // second one for CR (ENTER)
if (c == 'q') {break;} // out of while(1)
if (c < 'a' || c > 'g') {continue;} // function not defined
// else 'a' <= c <= 'g'
(*func_table[c - 'a'])();
func_table[c - 'a'](); // same function call
}
return 0;
}
/*
g++ FunctionTable.cpp -o FunctionTable
./FunctionTable
Press a key from 'a' to 'g' or 'q' to quit
0
Press a key from 'a' to 'g' or 'q' to quit
h
Press a key from 'a' to 'g' or 'q' to quit
a
Function a() called...
Function a() called...
Press a key from 'a' to 'g' or 'q' to quit
g
Function g() called...
Function g() called...
Press a key from 'a' to 'g' or 'q' to quit
c
Function c() called...
Function c() called...
Press a key from 'a' to 'g' or 'q' to quit
q
*/
****************************************************************************************
****************************************************************************************
****************************************************************************************
****************************************************************************************
****************************************************************************************
Exercise 3-34. Modify FunctionTable.cpp (see ch3-FunctionTable) so that each function returns a string (instead of printing out a message) and so that this value is printed inside of main().
// Using an array of pointers to functions
#include <stdio.h> // for printf(), getchar()
#include <string.h> // for strcpy(), strcat()
#define LENGTH 100 // max string length
// A macro to define dummy functions:
#define DF(N) char* N() \
{ \
char retval[LENGTH]; \
strcpy(retval, "Function "); \
strcat(retval, #N); \
strcat(retval, "() called..."); \
char* cp = retval; \
return cp; \
}
DF(a); DF(b); DF(c); DF(d); DF(e); DF(f); DF(g); // semicolons not required here
char* (*func_table[])() = {a, b, c, d, e, f, g};
int main()
{
char c;
while(1)
{
printf("Press a key from 'a' to 'g' or 'q' to quit\n");
c = getchar(); getchar(); // second one for newline (ENTER)
if (c == 'q') {break;} // out of while(1)
if (c < 'a' || c > 'g') {continue;} // function not defined
// else 'a' <= c <= 'g'
printf("%s\n", (*func_table[c - 'a'])());
printf("%s\n", func_table[c - 'a']()); // same function call
}
return 0;
}
/*
gcc function_table_string.c -o function_table_string
./function_table_string
Press a key from 'a' to 'g' or 'q' to quit
0
Press a key from 'a' to 'g' or 'q' to quit
h
Press a key from 'a' to 'g' or 'q' to quit
a
Function a() called...
Function a() called...
Press a key from 'a' to 'g' or 'q' to quit
g
Function g() called...
Function g() called...
Press a key from 'a' to 'g' or 'q' to quit
c
Function c() called...
Function c() called...
Press a key from 'a' to 'g' or 'q' to quit
q
*/
****************************************************************************************
****************************************************************************************
****************************************************************************************
// Using an array of pointers to functions
#include <iostream>
#include <string>
using std::string;
using std::cout;
using std::cin;
using std::endl;
// A macro to define dummy functions:
#define DF(N) string N() \
{return "Function " + string(#N) + "() called...";}
DF(a); DF(b); DF(c); DF(d); DF(e); DF(f); DF(g); // semicolons not required here
string (*func_table[])() = {a, b, c, d, e, f, g};
int main()
{
char c, cr; // CR - carriage return or newline
while(1) // while(true)
{
cout << "Press a key from 'a' to 'g' or 'q' to quit" << endl;
cin.get(c); cin.get(cr); // second one for CR (ENTER)
if (c == 'q') {break;} // out of while(1)
if (c < 'a' || c > 'g') {continue;} // function not defined
// else 'a' <= c <= 'g'
cout << (*func_table[c - 'a'])() << endl;
cout << func_table[c - 'a']() << endl; // same function call
}
return 0;
}
/*
g++ FunctionTableString.cpp -o FunctionTableString
./FunctionTableString
Press a key from 'a' to 'g' or 'q' to quit
0
Press a key from 'a' to 'g' or 'q' to quit
h
Press a key from 'a' to 'g' or 'q' to quit
a
Function a() called...
Function a() called...
Press a key from 'a' to 'g' or 'q' to quit
g
Function g() called...
Function g() called...
Press a key from 'a' to 'g' or 'q' to quit
c
Function c() called...
Function c() called...
Press a key from 'a' to 'g' or 'q' to quit
q
*/