PDA

View Full Version : TWO DIMENSIONNED ARRAY as an ARGUMENT for all the classes functions



hichemnho
9th February 2012, 18:19
Hello ,


I tried but with no success to pass a TWO DIMENSIONNED ARRAY , here called M, rows =cloumns=10,as an ARGUMENT for all the classes functions that I use in my program.
Even after reading the articles posted in this website I could not make it .
Here is my code:


// headers
#ifndef FENPRINCIPALE_H
#define FENPRINCIPALE_H
#include <QtGui>
class FenPrincipale : public QWidget
{
Q_OBJECT
public:
FenPrincipale();

private slots:
void genererCC(int **);
void paintEvent(QPaintEvent *,int **);

private:
QPainter *painter;
int M [10][10];
QPushButton *generer;

};
#endif
/////////////////Second Header//////////////////
#ifndef FENCC_H
#define FENCC_H
#include <QtGui>
class FenCC : public QDialog
{
public:
FenCC ( QWidget *parent , int **);
private:
QPushButton *fermer;
QPainter *painter;
private slots:
void paintEvent (QPaintEvent *, int **);
};
#endif

///FenPrincipale.cpp
#include "FenPrincipale.h"
#include "FenCC.h"
FenPrincipale::FenPrincipale()
{ int o,p;
for (o=0; o<10; o++)
{
for (p=0; p<10; p++)
{
M[o][p]=0;
}
}
M[0][3]=1;
M[0][9]=1;
M[2][6]=1;
M[3][5]=1;
M[5][3]=1;
M[2][4]=1;
M[4][2]=1;
QPaintEvent *e;
paintEvent(e,M);
generer = new QPushButton("&Générer !",this);
connect(generer, SIGNAL(clicked()), this, SLOT(genererCC(M)));
}
void FenPrincipale::genererCC(int **M)
{
FenCC *fenetreCC = new FenCC( this , M);
fenetreCC->exec();
}
void FenPrincipale::paintEvent(QPaintEvent *e, int **M)
{
QPainter painter(this);
int tour=0;
int x=10;
int y=10;
int Num_Sommet=0;
int T_Coordonnees [10][3];
for (Num_Sommet=0; Num_Sommet<10; Num_Sommet++)
{
(T_Coordonnees[Num_Sommet][0])=x;
(T_Coordonnees[Num_Sommet][1])=y;
(T_Coordonnees[Num_Sommet][2])=tour;
if (tour==0)
{
x+=35;
tour=1;
}
else
{
y+=55;
tour=0;
}
}
int w1=0;
int w2=0;
int cpt=10;
Num_Sommet=0;
for (Num_Sommet=0; Num_Sommet<10; Num_Sommet++)
{
if ((T_Coordonnees[Num_Sommet][2])==1)
{
if(w1==0)
{
(T_Coordonnees[Num_Sommet][0])=((T_Coordonnees[Num_Sommet][0])+500) ;
w1=1;
}
else
{
if(w1==1)
{
(T_Coordonnees[Num_Sommet][0])=((T_Coordonnees[Num_Sommet][0])+250+cpt) ;
w1=0;
cpt=cpt+15;
}
}
if (Num_Sommet==9)
{
(T_Coordonnees[Num_Sommet][0])=((T_Coordonnees[Num_Sommet][0])+45) ;
}

}
else
{
if(w2==0)
{
(T_Coordonnees[Num_Sommet][0])=(T_Coordonnees[Num_Sommet][0])+200;
w2=1;
}
else
{
(T_Coordonnees[Num_Sommet][0])=(T_Coordonnees[Num_Sommet][0])+100+cpt;
w2=0;
cpt=cpt+15;
}

if (Num_Sommet==4)
{
(T_Coordonnees[Num_Sommet][0])=((T_Coordonnees[Num_Sommet][0])+45) ;
}
}
painter.drawEllipse((T_Coordonnees[Num_Sommet][0]), (T_Coordonnees[Num_Sommet][1]), 30.0, 30.0);


}

int i,j;
for (i=0; i<10; i++)
{
for (j=0; j<10; j++)
{
if (M[i][j]==1)
{
painter.drawLine((T_Coordonnees[i][0]+20),(T_Coordonnees[i][1]),(T_Coordonnees[j][0]+20),(T_Coordonnees[j][1]));
}
}
}



for (i=0; i<10; i++)
{
for (j=0; j<10; j++)
{
if ((M[i][j]==1) && (M[j][i]==1))
{
painter.drawLine((T_Coordonnees[i][0]+20),(T_Coordonnees[i][1]),(T_Coordonnees[j][0]+20),(T_Coordonnees[j][1]));
if( (T_Coordonnees[i][1]>45)||(T_Coordonnees[j][1]>45) )
{
painter.drawLine(((T_Coordonnees[i][0]+20)-10),(T_Coordonnees[i][1]),((T_Coordonnees[j][0]+20)-10),(T_Coordonnees[j][1]));
}
else
{
painter.drawLine((T_Coordonnees[i][0]+20),(T_Coordonnees[i][1]+30),(T_Coordonnees[j][0]+20),(T_Coordonnees[j][1]+30));
}
}
}
}



Num_Sommet=0;
for (Num_Sommet=0; Num_Sommet<10; Num_Sommet++)
{
QPoint point = QPoint( (((T_Coordonnees[Num_Sommet][0])+15)), ((T_Coordonnees[Num_Sommet][1])+15) );
QString str;
str.setNum(Num_Sommet);
painter.drawText( point,str);

}
}

///////FenCC.cpp
#include "FenCC.h"
FenCC::FenCC( QWidget *parent = 0 , int **M) :QDialog(parent)
{
QPaintEvent *c;
paintEvent(c,M);
fermer = new QPushButton("Fermer",this);
connect(fermer, SIGNAL(clicked()), this, SLOT(accept()));

}
void FenCC::paintEvent(QPaintEvent *c ,int **M)
{
QPainter painter(this);
int tour=0;
int x=10;
int y=10;
int Num_Sommet=0;
int T_Coordonnees [10][3];
for (Num_Sommet=0; Num_Sommet<10; Num_Sommet++)
{
(T_Coordonnees[Num_Sommet][0])=x;
(T_Coordonnees[Num_Sommet][1])=y;
(T_Coordonnees[Num_Sommet][2])=tour;
if (tour==0)
{
x+=35;
tour=1;
}
else
{
y+=55;
tour=0;
}
}
int w1=0;
int w2=0;
int cpt=10;
Num_Sommet=0;
for (Num_Sommet=0; Num_Sommet<10; Num_Sommet++)
{
if ( (T_Coordonnees[Num_Sommet][2])==1)
{
if(w1==0)
{
(T_Coordonnees[Num_Sommet][0])=((T_Coordonnees[Num_Sommet][0])+500) ;
w1=1;
}
else
{
if(w1==1)
{
(T_Coordonnees[Num_Sommet][0])=((T_Coordonnees[Num_Sommet][0])+250+cpt) ;
w1=0;
cpt=cpt+15;
}
}
if (Num_Sommet==9)
{
(T_Coordonnees[Num_Sommet][0])=((T_Coordonnees[Num_Sommet][0])+45) ;
}

}
else
{
if(w2==0)
{
(T_Coordonnees[Num_Sommet][0])=(T_Coordonnees[Num_Sommet][0])+200;
w2=1;
}
else
{
(T_Coordonnees[Num_Sommet][0])=(T_Coordonnees[Num_Sommet][0])+100+cpt;
w2=0;
cpt=cpt+15;
}
if (Num_Sommet==4)
{
(T_Coordonnees[Num_Sommet][0])=((T_Coordonnees[Num_Sommet][0])+45) ;
}
}
painter.drawEllipse((T_Coordonnees[Num_Sommet][0]), (T_Coordonnees[Num_Sommet][1]), 30.0, 30.0);
}
int i,j;
for (i=0; i<10; i++)
{
for (j=0; j<10; j++)
{
if (M[i][j]==1)
{
painter.drawLine((T_Coordonnees[i][0]+20),(T_Coordonnees[i][1]),(T_Coordonnees[j][0]+20),(T_Coordonnees[j][1]));
}
}
}
for (i=0; i<10; i++)
{
for (j=0; j<10; j++)
{
if ((M[i][j]==1) && (M[j][i]==1))
{
painter.drawLine((T_Coordonnees[i][0]+20),(T_Coordonnees[i][1]),(T_Coordonnees[j][0]+20),(T_Coordonnees[j][1]));
if( (T_Coordonnees[i][1]>45)||(T_Coordonnees[j][1]>45) )
{
painter.drawLine(((T_Coordonnees[i][0]+20)-10),(T_Coordonnees[i][1]),((T_Coordonnees[j][0]+20)-10),(T_Coordonnees[j][1]));
}
else
{
painter.drawLine((T_Coordonnees[i][0]+20),(T_Coordonnees[i][1]+30),(T_Coordonnees[j][0]+20),(T_Coordonnees[j][1]+30));
}
}
}
}
Num_Sommet=0;
for (Num_Sommet=0; Num_Sommet<10; Num_Sommet++)
{
QPoint point = QPoint( (((T_Coordonnees[Num_Sommet][0])+15)), ((T_Coordonnees[Num_Sommet][1])+15) );
QString str;
str.setNum(Num_Sommet);
painter.drawText( point,str);
}
}
///////////////////main.cpp
#include <QApplication>
#include "FenPrincipale.h"
int main(int argc, char* argv[])
{
QApplication app(argc, argv);
FenPrincipale fenetre;
fenetre.show();
return app.exec();
}



I respectly repeat that the most important is not this code , but only how to declare the two dimensionned array in the headers and use it in the ".cpp" extensionned files.
I apreciate the time and attention given to this message.
Thank you.

ChrisW67
9th February 2012, 23:23
This is a generic C question. If the dimensions of the array are known and fixed then you simply declare your function:


void doStuff(int array[10][10]) { ... }
// and call it
int test[10][10];
doStuff(test);

If the dimensions are set at run time then you need to allocate the array memory dynamically, pass the dimensions around with the array, and remember to free the memory allocated. You could alternatively also pass a pointer to the first element of the array, along with the dimensions, and access the 1D array element for [r][c] using some simple maths [r*colCount + col]. See Passing multidimensional arrays as function arguments in C (http://stackoverflow.com/questions/4051/passing-multidimensional-arrays-as-function-arguments-in-c)

The generic C++ answer to arrays in general is std::vector. std::vector dispenses with the memory management and array dimension headaches of C. The generic C++ construct for a multi dimensional array is nested std::vectors.


#include <iostream>
#include <vector>

void dumpVec(const std::vector<std::vector<int> > &vec)
{
for (int r = 0; r < vec.size(); ++r) {
std::cout << r << ":\t";
for (int c = 0; c < vec[r].size(); ++c) {
std::cout << vec[r][c] << "\t";
}
std::cout << std::endl;
}
}

int main(int argc, char **argv)
{
static const int rowCount = 10;
static const int colCount = 10;

// Declare and init to zero
std::vector<std::vector<int> > vec(rowCount, std::vector<int>(colCount, 0));

// simple multiplication table
for (int r = 0; r < rowCount; ++r) {
for (int c = 0; c < colCount; ++c) {
vec[r][c] = r * c;
}
}

dumpVec(vec);

return 0;
}

The syntax can be tidied up a bit with typedefs.

Qt has QVector and QGenericMatrix which may be of use to you.

hichemnho
10th February 2012, 11:13
thank you for your answer,
I tried what you have suggested but without success, can you please see if the problem is in thee declaration in the HEADERS, I really tries all kinds of declarations but it is till not working .The error is that the second parameter of the constructor of FenCC is missing in other terms the array M , I do not understand.So please can you give me any advice concerning the headers evend the declaration of the array M in the private zone of FenPrincipale , I do not know if it is right
Here is the code:


//Headers
#ifndef FENCC_H
#define FENCC_H
#include <QtGui>
class FenCC : public QDialog
{
public:
FenCC ( QWidget *parent , int [10][10]);
private:
QPushButton *fermer;
QPainter *painter;
private slots:
void paintEvent (QPaintEvent *, int [10][10]);
};
#endif



#ifndef FENPRINCIPALE_H
#define FENPRINCIPALE_H
#include <QtGui>
class FenPrincipale : public QWidget
{
Q_OBJECT
public:
FenPrincipale();

private slots:
void genererCC(int [10][10]);
void paintEvent(QPaintEvent *,int [10][10]);

private:
QPainter *painter;
int M[10][10] ;
QPushButton *generer;

};
#endif



//////FenCC.cpp
#include "FenCC.h"
FenCC::FenCC( QWidget *parent = 0 , int M[10][10]) :QDialog(parent)
{
QPaintEvent *c;
paintEvent(c,M);
fermer = new QPushButton("Fermer",this);
connect(fermer, SIGNAL(clicked()), this, SLOT(accept()));

}
void FenCC::paintEvent(QPaintEvent *c ,int M[10][10])
{
QPainter painter(this);
int tour=0;
int x=10;
int y=10;
int Num_Sommet=0;
int T_Coordonnees [10][3];
for (Num_Sommet=0; Num_Sommet<10; Num_Sommet++)
{
(T_Coordonnees[Num_Sommet][0])=x;
(T_Coordonnees[Num_Sommet][1])=y;
(T_Coordonnees[Num_Sommet][2])=tour;
if (tour==0)
{
x+=35;
tour=1;
}
else
{
y+=55;
tour=0;
}
}
int w1=0;
int w2=0;
int cpt=10;
Num_Sommet=0;
for (Num_Sommet=0; Num_Sommet<10; Num_Sommet++)
{
if ( (T_Coordonnees[Num_Sommet][2])==1)
{
if(w1==0)
{
(T_Coordonnees[Num_Sommet][0])=((T_Coordonnees[Num_Sommet][0])+500) ;
w1=1;
}
else
{
if(w1==1)
{
(T_Coordonnees[Num_Sommet][0])=((T_Coordonnees[Num_Sommet][0])+250+cpt) ;
w1=0;
cpt=cpt+15;
}
}
if (Num_Sommet==9)
{
(T_Coordonnees[Num_Sommet][0])=((T_Coordonnees[Num_Sommet][0])+45) ;
}

}
else
{
if(w2==0)
{
(T_Coordonnees[Num_Sommet][0])=(T_Coordonnees[Num_Sommet][0])+200;
w2=1;
}
else
{
(T_Coordonnees[Num_Sommet][0])=(T_Coordonnees[Num_Sommet][0])+100+cpt;
w2=0;
cpt=cpt+15;
}
if (Num_Sommet==4)
{
(T_Coordonnees[Num_Sommet][0])=((T_Coordonnees[Num_Sommet][0])+45) ;
}
}
painter.drawEllipse((T_Coordonnees[Num_Sommet][0]), (T_Coordonnees[Num_Sommet][1]), 30.0, 30.0);
}
int i,j;
for (i=0; i<10; i++)
{
for (j=0; j<10; j++)
{
if (M[i][j]==1)
{
painter.drawLine((T_Coordonnees[i][0]+20),(T_Coordonnees[i][1]),(T_Coordonnees[j][0]+20),(T_Coordonnees[j][1]));
}
}
}
for (i=0; i<10; i++)
{
for (j=0; j<10; j++)
{
if ((M[i][j]==1) && (M[j][i]==1))
{
painter.drawLine((T_Coordonnees[i][0]+20),(T_Coordonnees[i][1]),(T_Coordonnees[j][0]+20),(T_Coordonnees[j][1]));
if( (T_Coordonnees[i][1]>45)||(T_Coordonnees[j][1]>45) )
{
painter.drawLine(((T_Coordonnees[i][0]+20)-10),(T_Coordonnees[i][1]),((T_Coordonnees[j][0]+20)-10),(T_Coordonnees[j][1]));
}
else
{
painter.drawLine((T_Coordonnees[i][0]+20),(T_Coordonnees[i][1]+30),(T_Coordonnees[j][0]+20),(T_Coordonnees[j][1]+30));
}
}
}
}
Num_Sommet=0;
for (Num_Sommet=0; Num_Sommet<10; Num_Sommet++)
{
QPoint point = QPoint( (((T_Coordonnees[Num_Sommet][0])+15)), ((T_Coordonnees[Num_Sommet][1])+15) );
QString str;
str.setNum(Num_Sommet);
painter.drawText( point,str);
}
}

///////FenPrincipale.cpp
#include "FenPrincipale.h"
#include "FenCC.h"
FenPrincipale::FenPrincipale()
{ int o,p;
int M [10][10];
for (o=0; o<10; o++)
{

for (p=0; p<10; p++)
{
M[o][p]=0;
}
}
M[0][3]=1;
M[0][9]=1;
M[2][6]=1;
M[3][5]=1;
M[5][3]=1;
M[2][4]=1;
M[4][2]=1;
QPaintEvent *e;
paintEvent(e,M);
generer = new QPushButton("&Générer !",this);
connect(generer, SIGNAL(clicked()), this, SLOT(genererCC(M)));
}
void FenPrincipale::genererCC(int M[10][10])
{
FenCC *fenetreCC = new FenCC( this , M);
fenetreCC->exec();
}
void FenPrincipale::paintEvent(QPaintEvent *e, int M[10][10])
{
QPainter painter(this);
int tour=0;
int x=10;
int y=10;
int Num_Sommet=0;
int T_Coordonnees [10][3];
for (Num_Sommet=0; Num_Sommet<10; Num_Sommet++)
{
(T_Coordonnees[Num_Sommet][0])=x;
(T_Coordonnees[Num_Sommet][1])=y;
(T_Coordonnees[Num_Sommet][2])=tour;
if (tour==0)
{
x+=35;
tour=1;
}
else
{
y+=55;
tour=0;
}
}
int w1=0;
int w2=0;
int cpt=10;
Num_Sommet=0;
for (Num_Sommet=0; Num_Sommet<10; Num_Sommet++)
{
if ((T_Coordonnees[Num_Sommet][2])==1)
{
if(w1==0)
{
(T_Coordonnees[Num_Sommet][0])=((T_Coordonnees[Num_Sommet][0])+500) ;
w1=1;
}
else
{
if(w1==1)
{
(T_Coordonnees[Num_Sommet][0])=((T_Coordonnees[Num_Sommet][0])+250+cpt) ;
w1=0;
cpt=cpt+15;
}
}
if (Num_Sommet==9)
{
(T_Coordonnees[Num_Sommet][0])=((T_Coordonnees[Num_Sommet][0])+45) ;
}

}
else
{
if(w2==0)
{
(T_Coordonnees[Num_Sommet][0])=(T_Coordonnees[Num_Sommet][0])+200;
w2=1;
}
else
{
(T_Coordonnees[Num_Sommet][0])=(T_Coordonnees[Num_Sommet][0])+100+cpt;
w2=0;
cpt=cpt+15;
}

if (Num_Sommet==4)
{
(T_Coordonnees[Num_Sommet][0])=((T_Coordonnees[Num_Sommet][0])+45) ;
}
}
painter.drawEllipse((T_Coordonnees[Num_Sommet][0]), (T_Coordonnees[Num_Sommet][1]), 30.0, 30.0);


}

int i,j;
for (i=0; i<10; i++)
{
for (j=0; j<10; j++)
{
if (M[i][j]==1)
{
painter.drawLine((T_Coordonnees[i][0]+20),(T_Coordonnees[i][1]),(T_Coordonnees[j][0]+20),(T_Coordonnees[j][1]));
}
}
}



for (i=0; i<10; i++)
{
for (j=0; j<10; j++)
{
if ((M[i][j]==1) && (M[j][i]==1))
{
painter.drawLine((T_Coordonnees[i][0]+20),(T_Coordonnees[i][1]),(T_Coordonnees[j][0]+20),(T_Coordonnees[j][1]));
if( (T_Coordonnees[i][1]>45)||(T_Coordonnees[j][1]>45) )
{
painter.drawLine(((T_Coordonnees[i][0]+20)-10),(T_Coordonnees[i][1]),((T_Coordonnees[j][0]+20)-10),(T_Coordonnees[j][1]));
}
else
{
painter.drawLine((T_Coordonnees[i][0]+20),(T_Coordonnees[i][1]+30),(T_Coordonnees[j][0]+20),(T_Coordonnees[j][1]+30));
}
}
}
}



Num_Sommet=0;
for (Num_Sommet=0; Num_Sommet<10; Num_Sommet++)
{
QPoint point = QPoint( (((T_Coordonnees[Num_Sommet][0])+15)), ((T_Coordonnees[Num_Sommet][1])+15) );
QString str;
str.setNum(Num_Sommet);
painter.drawText( point,str);

}
}


//////////////main.cpp

#include <QApplication>
#include "FenPrincipale.h"
int main(int argc, char* argv[])
{
QApplication app(argc, argv);
FenPrincipale fenetre;
fenetre.show();
return app.exec();
}



Thank you in advance.

wysota
10th February 2012, 12:19
Hmm... do you expect your paintEvent() implementation to ever be called (apart from calling it from the constructor yourself which doesn't make any sense)? Furthermore calculating so many things in a painting routine will make your application very slow. As for your current problem, why don't you use more high-level solutions such QGenericMatrix<10,10,int> ?

ChrisW67
11th February 2012, 02:32
The array M declared at line 34 of your last post listing, and the array M you declare locally in FenPrincipale::FenPrincipale() (line 168) are not the same variable. You initialise the local variable which goes out of scope at the end of the constructor. The member variable is not initialised.

As for the places you are passing M as a parameter... you are passing a copy of the array. You should consider passing a const reference to the array, or not passing the array at all where it is a member variable.

wysota
11th February 2012, 12:38
you are passing a copy of the array. You should consider passing a const reference to the array
I don't think this matters here since in the end int[][] is really a int** so it is a pointer that is copied, not the contents of the array.

ChrisW67
12th February 2012, 04:52
Your point about the copy is correct. My mistake.

However, int[10][10] is 100 ints in a contiguous block of memory (that the compiler accesses using an int* and known geometry), and not a pointer to a block of 10 pointers to blocks of 10 ints each (i.e. not int**). So:


void foo(int M[10][10]) { }
void bar(int **M) { }

int array[10][10]; // sizeof(array) == 400

foo(array); // will compile
bar(array); // error: cannot convert ‘int (*)[10]’ to ‘int**’ for argument ‘1’ to ‘void bar(int**)’