Avatar billede ladyhawke Novice
29. juli 2002 - 08:02 Der er 16 kommentarer og
1 løsning

Returner flere variable

Jeg arbejder med Visual C++ 6.0

Jeg vil gerne returnere flere variable fra en funktion, men hvordan gør man det nemmest?

Måske kan Vector bruges, men hvordan opretter man den og hvordan får man fat i den enkelte variabel bagefter?
Avatar billede jpk Nybegynder
29. juli 2002 - 08:47 #1
void MyFunc(int& Var1, int& var2)
{
  Var1 = 10;
  Var2 = 20;
}

//Kald
int a, b;
MyFunc(a, b);
Avatar billede jpk Nybegynder
29. juli 2002 - 08:48 #2
Du giver funktionen adresserne på dine variable, så kan den arbejde direkte på dem...
Avatar billede ladyhawke Novice
29. juli 2002 - 09:22 #3
I mit tilfælde vil det være ret klodset at have enkeltstående variable for alt det som skal returneres. Kan man ikke returnere et 2 dim array som består af strenge? Det vil sige at men finder en "liste" af strenge i hvert entry i arrayet...
Avatar billede jpk Nybegynder
29. juli 2002 - 09:35 #4
Hvis de variable der skal returneres "hører sammen", kan du definere en struktur eller klasse til dem.

class Person
{
  string strName;
  string strAddress;
  int nAge;
  ...
  ...
};

void MyFunc(Person& person)
{
  // Do whatever...
}

Hvis ikke, skal du måske overveje om du kan ændre dit design.
Avatar billede ladyhawke Novice
29. juli 2002 - 09:44 #5
Jeg vil lige forsøge med array/struct ideen.

Den basale funktion gennemløber en tekst fil fort at finde bestemte oplysninger. For hver linie i tekstfilen (som indholder en bestemt streng) noteres linie nr., tekst, mm.

Hver linie (svarende til en struct) opsamles i en anden funktion der skal aflevere resultatet til GUI håndteringen hvor informationenerne skal tilføjes til en List Ctrl.
Avatar billede jpk Nybegynder
29. juli 2002 - 09:53 #6
Okay, men så ville jeg da give funktionen en reference til en vector der kan indeholde din struct, fx:

vector<LineData> LineDataVector;

void MyFunc(vector<LineData>& vec)
{
  vec.push_back(...); // Smid de elementer i, du skal bruge
  // Hvis du har nogen mulighed for at foresige hvor mange elementer der skal i vectoren, kan du med fordel (performance) bruge vec.reserve(Number), da det forhindrer en del reallokering
}

Du kan naturligvis også bare lade funktionen returnere en vector af ovenstående type, men kopieres hele indholdet, hvilket ikke er særlig smart (især ikke hvis der er meget data i)
Avatar billede jpk Nybegynder
29. juli 2002 - 09:55 #7
Finktionskaldet vil så være:

vector<LineData> LineDataVector;
MyFunc(LineDataVector);
// Ved returnering fra funktion, er vectoren fyldt med oplysningerne du skal bruge...
Avatar billede ladyhawke Novice
29. juli 2002 - 09:58 #8
jeg tror godt jeg kan returnere en vector, det er altid det samme antal parametre i vektoren og det er nogle strenge der skal overføres... Så kan jeg vel samle det hele til et array af vektorer, når GUI'en skal opdateres...
Avatar billede jpk Nybegynder
29. juli 2002 - 10:12 #9
Jeg er ikke helt med på dit sidste indlæg...

Afhænger antallet af parametre ikke af hvor mange gange du finder "en bestemt streng"?

Jeg havde egentlig forstået, at det du skulle bruge var noget lign.:

class LineData
{
  int nLine;
  string strText;
  ...
};

vector<LineData> CheckFile()
{
  vector<LineData> vec;
  // while file not at end, read line
  //  if line OK, put into vector
        vec.push_back(LineData(nLineNumber, strText));
  // end while

  return vec;
}

derfor forstår jeg ikke din sidste kommentar "Så kan jeg vel samle det hele til et array af vektorer, når GUI'en skal opdateres..."?
Avatar billede ladyhawke Novice
29. juli 2002 - 10:19 #10
Den første funktion en en linie scanner, der scanner én linie og hvis den finder strengen returneres en vektor (efter forskellig data behandling).

Den næste funktion er en fil scanner, der opsamler de returnerede vektorer (i et array f.eks). Disse skal overføre til GUI samlet...
Avatar billede jpk Nybegynder
29. juli 2002 - 10:26 #11
Okay...
Avatar billede ladyhawke Novice
29. juli 2002 - 11:11 #12
Hvordan definerer jeg et array af vektorer?
Avatar billede jpk Nybegynder
29. juli 2002 - 11:15 #13
Lave en matrix klasse...

Fx:

#ifndef MATRIX_H
#define MATRIX_H

#include <vector>  //STL-klasse
#include <cassert> //erstatter assert.h

    using std::vector;

//-------------- class row er en række i Matrix: -------------------

template <class T>
class row
{
public:           
//klassen indeholder netop én vector = 1 række i Matrix:
vector<T> aRow;
};


//-------------------- class Matrix --------------------------------
template <class T>
class Matrix
{
public:
Matrix  (size_t Rows=0, size_t Cols=0);
Matrix  (size_t Rows, size_t Cols, const T& Value); 
Matrix  (const Matrix<T>& source);      //copy-constructor
virtual ~Matrix() {};

void Init(const T& Value);

vector<T>& operator[] (size_t index);      //LValue indexering
const vector<T>& operator[] (size_t index) const; //RValue indexering
const T& GetAt (size_t Row, size_t Col) const;
void  SetAt (size_t Row, size_t Col, const T& Value);

Matrix<T>& operator= (const Matrix<T>& m); //assignment

virtual void Resize(size_t Rows, size_t Cols); 
virtual void Resize(size_t Rows, size_t Cols, const T& Value); 

//inspektører:
size_t NoOfRows () const;
size_t NoOfCols () const;

protected:

vector< row<T> > rows;  //vector med rows vectorer
}; //end of class Matrix

/* ------------------------ Kontrakter -----------------------------

---------------  Constructor, evt. uinitialiseret Matrix: ---------
Matrix (size_t Rows=0, size_t Cols=0)
PRE : true
POST: konstruerer Matrix med Rows rækker og Cols søjler
      Der kan konstrueres en matrix (0,0), som senere skal
      Resize's. Uden argumenter er det default constructor         

---------------  Constructor, initialiseret Matrix: ----------
Matrix  (size_t Rows, size_t Cols, const T& Value)
PRE : Value def.
POST: konstruerer Matrix med Rows rækker og Cols søjler og alle
        elementer = Value. Value skal have en default-constructor

---------------  Copy Constructor: ---------------------------
Matrix  (const Matrix<T>& source)
PRE : source def.
POST: konstruerer kopi af Matrix source

---------------  Init: ---------------------------------------
void Init(const T& Value)
PRE : true
POST: Matrix initialiseret med Value

---------------  Operator []: --------------------------------
vector <T>& operator[] (size_t index)
PRE : index < NoOfRows()
POST: returnerer reference til række-vektor udpeget af index, LValue

const vector <T>& operator[] (size_t index) const
PRE : index < NoOfRows()
POST: returnerer reference til række-vektor udpeget af index, RValue

---------------  GetAt(..): --------------------------------
const T&  GetAt (size_t Row, size_t Col) const;
PRE : Row < NoOfRows(), 0 <= Col < NoOfCols()
POST: returnerer en const reference til elementet i [Row][Col], RValue

---------------  SetAt(..): --------------------------------
void SetAt (size_t Row, size_t Col, const T& Value);
PRE : Row < NoOfRows(), 0 <= Col < NoOfCols(), Value def.
POST: matrix elementet [Row][Col] = Value, LValue

---------------  Operator =: ---------------------------------
Matrix<T>& operator= (const Matrix<T>& m)
PRE : right-operand m defineret
POST: Matrix assigned værdien af m, returnerer Matrix = m

-----------------  Resize(): --------------------------------- 
void Resize(size_t Rows, size_t Cols); 
PRE : 0 < Rows, 0 < Cols
POST: omdanner matrix til en Rows*Cols matrix. Nye elementer
      er initialiseret med default-værdi af elementtypen.

void Resize(size_t Rows, size_t Cols, const T& Value); 
PRE : 0 < Rows, 0 < Cols, Value def.
POST: omdanner matrix til en Rows*Cols matrix. Nye elementer
      er initialiseret med Value.

---------------  NoOfRows (): ----------------------------
size_t NoOfRows ()
PRE : true
POST: returnerer antal rækker i Matrix

---------------  NoOfCols (): ----------------------------
size_t NoOfCols ()
PRE : true
POST: returnerer antal søjler i Matrix
*/


template <class T>
Matrix<T>::Matrix (size_t Rows, size_t Cols)
                : rows(Rows)
{
for (size_t i = 0; i < Rows; i++)
      rows[i].aRow.resize(Cols);
}

template <class T>
Matrix<T>::Matrix  (size_t Rows, size_t Cols, const T& Value)
    : rows(Rows)
{
    for (size_t i = 0; i < Rows; i++)
      rows[i].aRow.resize(Cols, Value);
}

template <class T>
Matrix<T>::Matrix  (const Matrix<T>& source)
    : rows(source.NoOfRows() )
{
  for (size_t i = 0; i < source.NoOfRows(); i++)
  {
    rows[i].aRow = source.rows[i].aRow;  //vector assignment
  }
}

template <class T>
void Matrix<T>::Init  (const T& Value)
{
size_t i, j;
for (i=0; i < NoOfRows(); ++i)
  for (j=0; j < NoOfCols(); ++j)
    rows[i].aRow[j] = Value;
}

template <class T>
vector<T>& Matrix<T>::operator[] (size_t index)  //LValue
{
assert (0 <= index && index < NoOfRows());
return rows[index].aRow;
//aRow er en vector<T>
//Ved indexering med [i][j] på en matrix, vil [i]
//returnere vector<T> i den i'te række.
//På denne bruges [j], således at det j'te element i den i'te række returneres.
//Og det er netop element [i][j] i matrix'en!
}

template <class T>
const vector<T>& Matrix<T>::operator[] (size_t index) const //RValue
{
assert (index < NoOfRows());
return rows[index].aRow;
}

template <class T>
const T& Matrix<T>::GetAt (size_t Row, size_t Col) const
{
return rows[Row].aRow[Col];
}

template <class T>
void Matrix<T>::SetAt (size_t Row, size_t Col, const T& Value)
{
rows[Row].aRow[Col] = Value;
}

template <class T>
Matrix<T>& Matrix<T>::operator= (const Matrix<T>& m)
{
if (this != &m) //check for selv-assignment
{
  rows.resize(m.NoOfRows()); //frigiv eller alloker memory

  //kopier rækkerne fra m, en række ad gangen:
    for (size_t i = 0; i < m.NoOfRows(); ++i)
    rows[i].aRow = m.rows[i].aRow; //vector assignment
}
return *this;
}

template <class T>
void Matrix<T>::Resize(size_t Rows, size_t Cols)
{
rows.resize(Rows);
for (size_t i=0; i < Rows; ++i)
  rows[i].aRow.resize(Cols);
}

template <class T>
void Matrix<T>::Resize(size_t Rows, size_t Cols, const T& Value) 
{
rows.resize(Rows);
for (size_t i=0; i < Rows; ++i)
  rows[i].aRow.resize(Cols, Value);
}

template <class T>
size_t Matrix<T>::NoOfRows () const
{
return rows.size();
}

template <class T>
size_t Matrix<T>::NoOfCols () const
{
return rows[0].aRow.size();
}

#endif
Avatar billede ladyhawke Novice
29. juli 2002 - 11:43 #14
Det har jeg ikke set før, jeg kan godt kompilere klassen, men hvordan instantierer (lille eksempel) jeg matrix klassen? Jeg ved ikke på forhånd hvor mange rækker der skal være i den...

Min ide er at lave en instans af denne klasse og så skrive i den ved hjælp af fil scanne klassen, men er det den "rigtige" måde at gøre det på
Avatar billede jpk Nybegynder
29. juli 2002 - 11:55 #15
Det er jo bare en vector af vectorer...
Du kan lave en metode til at tilføje rækker.
Avatar billede ladyhawke Novice
29. juli 2002 - 13:25 #16
Så har jeg fat i vectoren på rette sted, takt for hjælpen og de gode forklaringer :o)
Avatar billede jpk Nybegynder
29. juli 2002 - 13:29 #17
Velbekomme og selv tak...
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Kurser inden for grundlæggende programmering

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester