473,404 Members | 2,137 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,404 software developers and data experts.

matrix of function pointers

Hi all,

I'm in need of a matrix of function pointers, and to be honest. No
'nice' solution has been found yet on that big big internet.

It is possible to declare a matrix of function pointers in the following
way

void (*f[2][2])(int);

But I want to know how I can declare this only using double pointers.
like an array

double **a;
a = new double *[2];
for (int i = 0; i < 2; i++)
a[i] = new double [2];

I would like to know this, because I have in my code something which is
similar like below, and i want it to work. The problem is, that during
compiling i obtain the following error.

cannot convert 'void (* (*)[2])(int)' to 'void (***)(int)' for argument
'1' to 'void pm_funcion(void (***)(int), int)'
cannot convert 'void (* (*)[3])(int)' to 'void (***)(int)' for argument
'1' to 'void pm_funcion(void (***)(int), int)'

thanks in advance

klaas
//function
void pm_function(void (***f) (int), int dim) {
for (int i = 0; i < dim; i++)
for (int j = 0; j < dim; j++)
f[i][j](5);
}

int main(void) {
void (*f[2][2])(int);
void (*g[3][3])(int);
// I want this to work, but it doesn not! See error above message
pm_function(f,2);
pm_function(g,3);

}
Mar 20 '06 #1
8 2446

Maybe the following code would help:

typedef void (*fnptr)(int);
typedef fnptr** fnptr_mtrx;

fnptr_mtrx matrix = ...
Mar 20 '06 #2
"Klaas Vantournhout" <no************@spam.com> wrote in message
news:dv**********@gaudi2.UGent.be
Hi all,

I'm in need of a matrix of function pointers, and to be honest. No
'nice' solution has been found yet on that big big internet.

It is possible to declare a matrix of function pointers in the
following way

void (*f[2][2])(int);

But I want to know how I can declare this only using double pointers.
like an array

double **a;
a = new double *[2];
for (int i = 0; i < 2; i++)
a[i] = new double [2];

I would like to know this, because I have in my code something which
is similar like below, and i want it to work. The problem is, that
during compiling i obtain the following error.

cannot convert 'void (* (*)[2])(int)' to 'void (***)(int)' for
argument '1' to 'void pm_funcion(void (***)(int), int)'
cannot convert 'void (* (*)[3])(int)' to 'void (***)(int)' for
argument '1' to 'void pm_funcion(void (***)(int), int)'

thanks in advance

klaas
//function
void pm_function(void (***f) (int), int dim) {
for (int i = 0; i < dim; i++)
for (int j = 0; j < dim; j++)
f[i][j](5);
}

int main(void) {
void (*f[2][2])(int);
void (*g[3][3])(int);
You realise of course that you have never initialised these function
pointers to point to anything.
// I want this to work, but it doesn not! See error above message
pm_function(f,2);
pm_function(g,3);

}


Your problem is not specifically with function pointers. You would have the
same problem with arrays of ints, e.g., the following won't compile for the
same reason.

void pm_function(int **pptr, int dim)
{
for (int i = 0; i < dim; i++)
for (int j = 0; j < dim; j++)
cout << pptr[i][j];
}

int main()
{
int arraytwo[2][2];
int arraythree[3][3];

pm_function(arraytwo,2);
pm_function(arraythree,3);

return 0;
}

Array names and pointers are only (more or less) interchangeable when the
array is one dimensional (in the sense of having a single subscript). For
two and more dimensions (in the sense of two or more subscripts) they are
quite different.

To illustrate, if pptr points to an int pointer, then pptr+1 is an address
that is sizeof(int*) greater than pptr. By contrast, using the definition of
arraythree given above, arraythree+1 yields an address that is 3*sizeof(int)
greater than the address of arraythree. The difference is because pptr
points to an int* pointer, whereas arraythree points to a row of three ints.

To prove it, run the following code:

int main()
{
int x;
int *ptr = &x;
int **pptr = &ptr;
cout << "pptr address is " << pptr << '\n';
cout << "pptr+1 address is " << pptr+1 << '\n';

int arraythree[3][3];

cout << "arraythree address is " << arraythree << '\n';
cout << "arraythree+1 address is " << arraythree+1 << '\n';
return 0;
}

If you want to pass 2-dimensional arrays to a function, then you need to a
different function for each different column count. Templates can help here.
--
John Carson
Mar 20 '06 #3
>> //function
void pm_function(void (***f) (int), int dim) {
for (int i = 0; i < dim; i++)
for (int j = 0; j < dim; j++)
f[i][j](5);
}

int main(void) {
void (*f[2][2])(int);
void (*g[3][3])(int);
You realise of course that you have never initialised these function
pointers to point to anything.


Yes I do ;-)

// I want this to work, but it doesn not! See error above message
pm_function(f,2);
pm_function(g,3);

}

Your problem is not specifically with function pointers. You would have the
same problem with arrays of ints, e.g., the following won't compile for the
same reason. <snip> If you want to pass 2-dimensional arrays to a function, then you need to a different function for each different column count. Templates can help here.


I am indeed aware of this. That is why I would like to define my matrix
of function pointers using dynamical allocation using the new operator.
This should sort that problem out and let me use a double pointer in
the function call.

The answer given by benben is indeed a solution. But I was wondering if
you could do it without defining a new type.

Already thanks for your swift response.

klaas
Mar 20 '06 #4
I think you should go back to basics, first the work out the pointers
to functions:

#ifdef HAVE_CONFIG_H
#include <config.h>
#endif

#include <iostream>
#include <cstdlib>

using namespace std;
//-----------------------------------------------------------------------------
// define the type
typedef void (*Tpointer2Function)(int);
// define the array with 3 elements
Tpointer2Function ArrayOfFunctions[3];
//-----------------------------------------------------------------------------
void function1(int a)
{
cout << "function 1 = " << a << endl;
}
//-----------------------------------------------------------------------------
void function2(int a)
{
cout << "function 2 = " << a << endl;
}
//-----------------------------------------------------------------------------
void function3(int a)
{
cout << "function 3 = " << a << endl;
}
//-----------------------------------------------------------------------------
int main(int argc, char *argv[])
{
// assign the functions you want to call to the array
ArrayOfFunctions[0] = function1;
ArrayOfFunctions[1] = function2;
ArrayOfFunctions[2] = function3;
// iterate thru the array
for (int i=0; i <=2; i++)
{
ArrayOfFunctions[i](i);
}
return EXIT_SUCCESS;
}
//-----------------------------------------------------------------------------

Once you've done that you could go and have a dynamic array (see Bruce
Eckel's 'thinking in c++' 2nd edition - "Arrays of pointers to
functions" section - with minor modifications):

#include <iostream>
#include <cstdlib>

using namespace std;
//-----------------------------------------------------------------------------
// A macro to define dummy functions - Bruce's functions have no int
parameter;
#define DF(N) void N(int a) { cout << "function " #N " called with
parameter " << a << endl; }

DF(a); DF(b); DF(c); DF(d); DF(e); DF(f); DF(g);

void (*func_table[])(int) = {a, b, c, d, e, f, g};
//-----------------------------------------------------------------------------
int main(int argc, char *argv[])
{
while (true)
{
char c, cr;
cout << "press a key from 'a' to 'g' or 'q' to quit" << endl;
cin.get(c); cin.get(cr); // second one for CR
// another alteration LValues are better there so you don't get
assignments
// rather than comparisons
if ('q'== c)
break;
if (c < 'a' || c > 'g')
continue;
(*func_table[c - 'a'])(101);
}
return EXIT_SUCCESS;
}
//-----------------------------------------------------------------------------

Mar 20 '06 #5
benben wrote:

Maybe the following code would help:

typedef void (*fnptr)(int);
typedef fnptr** fnptr_mtrx;

fnptr_mtrx matrix = ...

Thanks benben for the swift response,

But is this possible without redefining a new type?

In your declaration fnptr_mtrx is indeed of the type void (***)(int);

using your declartion I would be able to do
fnptr_mtrx = new fnptr *[n];
for (int i = 0; i < n; i++)
fnptr[i] = new fnptr [m];

to construct an n x m function pointer matrix, but is it possible to
write something like

void (***g)(int);
g = new void (**)(int) *[5];

or anything like that? (the above does not work)

klaas
Mar 20 '06 #6
"Klaas Vantournhout" <no************@spam.com> wrote in message
news:dv**********@gaudi2.UGent.be

I am indeed aware of this. That is why I would like to define my
matrix of function pointers using dynamical allocation using the new
operator. This should sort that problem out and let me use a double
pointer in the function call.

The answer given by benben is indeed a solution. But I was wondering
if you could do it without defining a new type.

Already thanks for your swift response.

klaas


A typedef does not introduce a new type. It is simply an alias for a type.

You can do dynamic allocation of function pointers without using a typedef,
but it is pointlessly difficult to do so.

Just for the record:

#include <iostream>

using namespace std;

// function to which function pointers will point
template<int n>
void func(int x)
{
cout << n*x << '\n';
}

// your (modified) function
void pm_function(void (*(*(*f)))(int), int dim)
{
for (int i = 0; i < dim; i++)
for (int j = 0; j < dim; j++)
f[i][j](5);
}

int main()
{
// dynamic pointer allocation

void (*(*(*g)))(int) = new (void (*(*[3]))(int));

for(int i=0; i<3; ++i)
g[i] = new (void (*[3])(int));

// initialise function pointers
for(int i=0; i<3; ++i)
{
for(int j=0; j<3; ++j)
{
switch(i)
{
case 0:
g[i][j]=&func<0>;
break;
case 1:
g[i][j]=&func<1>;
break;
case 2:
g[i][j]=&func<2>;
break;
}
}
}

// test your function
pm_function(g,3);

// cleanup

for(int i=0; i<3; ++i)
delete[] g[i];

delete[] g;

return 0;
}

If you think this is good code, then we have very different ideas of what
constitutes good code.
--
John Carson


Mar 20 '06 #7
> A typedef does not introduce a new type. It is simply an alias for a type.

Indeed, my mistake there
You can do dynamic allocation of function pointers without using a typedef,
but it is pointlessly difficult to do so.

Just for the record:
<snip> void (*(*(*g)))(int) = new (void (*(*[3]))(int));

for(int i=0; i<3; ++i)
g[i] = new (void (*[3])(int));
<snip>
If you think this is good code, then we have very different ideas of what
constitutes good code.


Why should this not be good code? I dislike the use of typedef because
it makes things sometimes unreadable. It is to my opinion only usefull
when you have an extreme long annoying type which you have to declare
multiple times.

Here this is not the case, you can see immediately of what type 'g' is.
And it is not much more difficult then using a typedef. The
initialisation is done in the same way.

Or did you mean something else?

I used this in my code because I could reduce 300 lines of code to only
20 with this. Removed a big mixture of case and if conditions which was
totally unreadable. And also the size of the matrix depends on the
initial conditions of my program.

Thanks again for the answer. You made my day!

klaas
Mar 21 '06 #8
"Klaas Vantournhout" <no************@spam.com> wrote in message
news:dv**********@gaudi2.UGent.be
A typedef does not introduce a new type. It is simply an alias for a
type.


Indeed, my mistake there
You can do dynamic allocation of function pointers without using a
typedef, but it is pointlessly difficult to do so.

Just for the record:


<snip>
void (*(*(*g)))(int) = new (void (*(*[3]))(int));

for(int i=0; i<3; ++i)
g[i] = new (void (*[3])(int));


<snip>
If you think this is good code, then we have very different ideas of
what constitutes good code.


Why should this not be good code? I dislike the use of typedef
because it makes things sometimes unreadable. It is to my opinion
only usefull when you have an extreme long annoying type which you
have to declare multiple times.

Here this is not the case, you can see immediately of what type 'g'
is.

I doubt that 1 in 100 C++ programmers can "see immediately what type g is".
I couldn't do so myself if I hadn't written the code.

Compare:

typedef void (*FnPtr)(int);

FnPtr **g = new FnPtr*[3];

for(int i=0; i<3; ++i)
g[i] = new FnPtr[3];

Once you make the typedef, this looks just like what you would do if you had
an array of ints or doubles. It is familiar and easy to comprehend.
--
John Carson
Mar 23 '06 #9

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

7
by: Erik Borgstr?m | last post by:
Hi, I simply want to use simple matrices of ints or doubles in C++ and I want all the good: 1) be able to use double-index, e.g. m 2) not have to use pointers at all 3) do it fast I know...
3
by: paytam | last post by:
Hi all How can I define a dynamic matrix and pass it to a function?
16
by: Martin Jørgensen | last post by:
Hi, I've made a program from numerical recipes. Looks like I'm not allowed to distribute the source code from numerical recipes but it shouldn't even be necessary to do that. My problem is...
20
by: Frank-O | last post by:
Hi , Recently I have been commited to the task of "translating" some complex statistical algorithms from Matlab to C++. The goal is to be three times as fast as matlab ( the latest) . I've...
5
by: Anolethron | last post by:
Wrong one: void minptr (int *matrix, int rows, int columns,int *min){ int i=0,j=0; *min=*matrix; //!!!!!!!!!!!!!!!!! for (i=0; i < rows; i++) { for (j=0; j < columns; j++) { if( *min...
4
by: =?iso-8859-9?B?RGlu52F5IEFr5/ZyZW4=?= | last post by:
I need to pass a two dimensional matrix to a function. Function gets int ** but i cannot find appropriate input to function in main. in main mdelc(&ar1, 5, 5, 3); function prototype: void...
3
by: craziileeboi | last post by:
Hi I have been pulling my hair out trying to figure this out. Please help!!! Here is my project description: By using a pointer to pointers **A and **B and the function calloc() allocate...
2
by: Encrypted | last post by:
i am working with a matrix manipulation program...consists of a matrix class and its member functions.. i have also overloaded << and >>...so dat dey can read and print d whole matrix at one...
10
by: Babak | last post by:
Hi, I've developed a C program which contains a large number of vectors and matrices operations. Throughout my code, I used the template from the Numerical Recipes book to define vectors and...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
0
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.