Gå til innhold

et simpelt arrayproblem (c++)


Anbefalte innlegg

#include <iostream>

 

void test();

 

 

int main(){

 

 //kaller funksjonen:

 test(); 

 

 //vil skrive ut verdien på plass nr 0 i arrayet jeg har definert i funk

 int x[2];

 

 //test(), dette går ikke. SPM: Hvordan sender jeg et array fra en funksjon til en annen?

 

 cout << x[0]; 

 

 return 0;

}

 

 

//Funksjoen som lager arrayet jeg skal bruke i main

void test(){

 

  //lager her et simpelt array 

 

 int x[2] = {1,2}; 

}

 

 

 

 

Min egentlige oppave er å lage en funksjon som generer en random tabell. Og så skal jeg bruke denne tabellen jeg har generert i en annen funksjon (feks main), her skal den testes/sorteres etc. Står virkelig fast etter mange mange timer med prøving! Er det noen som kunne svare på dette?

Lenke til kommentar
Videoannonse
Annonse

Hvis jeg var deg ville jeg ikke bruke array, men std::vector. Du kan ikke returnere arrayen (i normal forstand), men det lar seg gjøre med litt lureri, men du bruker jo c++ og da har man std::vector.

 

Hvis du vil/må bruke array kan du gjøre det ved å returnere en peker til en array (enten til dynamisk allokert minne eller til et området du vet er der). Du kan også sende med en peker til en array som du fyller opp og på den måten "sender" data fra funksjonen.

Den enkleste, men dårligste løsningen er å definere arrayen som en global variabel som du kan endre fra funksjonen

Det finnes sikkert flere muligheter også.

 

Lykke til og bare spør hvis det er noe mer du lurer på.

 

Problemet løst ved bruk av std::vector

 

#include <iostream>
#include <vector>

void GenArray(std::vector<int>* RandArray);

void main()
{
std::vector<int> RandomArray;
RandomArray.resize(4);//Setter hvor lang vectoren skal være.... dvs. hvor mange tall i "arrayen"
GenArray(&RandomArray);

std::vector <int>::iterator Iter;

for ( Iter = RandomArray.begin(); Iter != RandomArray.end(); Iter++ )
{
	std::cout << *Iter << std::endl;//spytter ut verdiene
}
}

void GenArray(std::vector<int>* RandArray)
{
std::vector <int>::iterator Iter;

			//Looper gjennom hele vectoren og fyller med "random"
for ( Iter = RandArray->begin(); Iter != RandArray->end(); Iter++)
	{
	*Iter = 2;//Random... funnet med terning
}
}

 

Lenke til kommentar

I C/C++ kan man ikke sende en array som en helhet til en annen funksjon; dette er fordi at arrays i C/C++ egentlig er en serie med verdier av den gitte typen og arrayen er pekeren til det første elementet. Det du vil, er å sende nettopp denne til funksjonen. Når man gjør dette, og størrelsen er ukjent for kalt funksjon, pleier man å sende med størrelsen på arrayet som et ekstra argument. (Du vil kanskje kopiere til en editor først.)

 

MERK AT forumet bytter ut '\ 0' (uten mellomrommet) med '' av en eller annen grunn. Dette må fikses i koden skulle den kompileres. PM meg hvis du vil ha fil.

 

 

/* Includes. */
#include <iostream>
using std::cout;
using std::cin;
using std::endl;

/* Prototyper. */
double sum(double elems[], int len);
float  max_of_five(float elems[5]);
double avg(double *elems, int len);
void   print_all(char *elems[], int len);
void   print_str(char str[]);
void   string_copy(char *to, char *from);
int	string_length(char *str);

int main()
{
/* Funker fint. */
double arr[] = {5.3, 6.3, 7.3};
cout << "Sum av array = " << sum(arr, 3) << endl;

/* Funker fint; men noter at det er ikke garantert
 * at max_of_five() mottar en array med størrelse 5.
 */
float arr2[] = {9.3, 8.2, 11.2, 9.9, 0.2};
cout << "Max av array 2 = " << max_of_five(arr2) << endl;

/* Funker fint; men max_of_five() sjekker bare de 5 første. */
float arr3[] = {0.2, 0.5, 0.3, 8.3, 5.6, 2.3, 9.3};
cout << "Max av array 3 = " << max_of_five(arr3) << endl;

/* Udefinert resultat, men sannsynligvis
 * runtime error; max_of_five() prøver å lese utover et
 * ureservert segment (minnet). IKKE sats på at
 * denne funker.
 */
float arr4[] = {-3.2, 0.5};
cout << "Max av array 4 = " << max_of_five(arr4) << endl;

/* Funker fint, vi tar ansvar for at avg får
 * riktig informasjon om antall elementer i arr5.
 */
double arr5[] = {0.2, 0.5, 0.7, 0.1};
cout << "Avg av array 5 = " << avg(arr5, 4) << endl;

/* arr6 er en her en array av pekere til char, men når
 * print_all mottar den, oppfatter den bare arr6 som en
 * peker til en mengde pekere til char.
 */
char *arr6[] = {"simpsons", "family guy", "futurama"};
print_all(arr6, 3);

cout << "Output fra vår print_str: ";
print_str("jodeleihihoo!\n");

char buf[64];
/* Fjern kommentering under om du får segment-feil. */
//buf[63] = '';
char *jan = "jan teigen er jo ganske kul da!"; /* "cstring"-notasjon legger
												* automatisk til en '' på slutten. */
cout
	<< "Før kopiering:" << endl
	<< "buf is >>" << buf << "<<" << endl /* Her printer vi ut hele buf, vi garenterer
										   * ikke for at det er en C-string, for vi vet
										   * ikke hva som ligger i buf når programmet
										   * allokerte minnet til det. To ting kan skje her:
										   * 1) cout finner aldri ''-byten og leser og
										   * skriver ut langt utenfor arrayet (antakelig segment-feil til slutt).
										   * 2) Det finnes (antakelig) en ''-byte i arrayet vårt og cout
										   * skriver bare ut masse garble eller ingenting.
										   */
	<< "jan is >>" << jan << "<<" << endl;
string_copy(buf, jan); /* Legg merke til at buf er en array
						* og jan er en peker til den første i en
						* en serie av char-s. For kompilatoren,
						* er dette det samme.
						*/
cout
	<< "Etter kopiering:" << endl
	<< "buf er >>" << buf << "<<" << endl
	<< "jan er >>" << jan << "<<" << endl;

/* Merk at det er forskjell på - */
char alpha[] = "masse rar tekst her som er inneholdt i et minne definert av alpha (en array)";
/* - og - */
char *omega = "dette ligger ett eller annet sted i minnet, men omega har bare pekeren til den først char-en (en peker)";
/* Begge disse er C-strings, men
 * bare alpha har alle dataene inneholdt
 * i seg. omega har bare pekeren til et
 * sted i minnet hvor dataene er lagret.
 */

/* Derfor blir - */
for (int i = 0; i < sizeof(alpha); i++)
	cout << alpha[i]; /* Printer ut hele C-stringen. */
cout << endl;
/* - riktig, men - */
for (int i = 0; i < sizeof(omega); i++)
	cout << omega[i]; /* Printer ut kun 4 første chars. */
cout << endl;
/* blir FEIL! Dette er en vanlig begynnerfeil. Grunnen
 * er at i skopet hvor alpha er definert er det
 * fortsatt en array, og sizeof vil returnere hele
 * minneområdets størrelse (i bytes). Siden størrelsen
 * på en byte og en char er den samme (i 99.9 % av tilfellene)
 * så kan en for-loop bruke sizeof til å finne ut hvor mange
 * char-s en C-string inneholder hvis det er en array.
 *
 * Grunnen til at den andre loopen feiler, er fordi sizeof finner
 * størrelsen på selve pekeren (peker-til-char) som på et 32-bit OS
 * er 4 bytes.
 *
 * Hvis du vil finne størrelsen på en C-string uansett om det er en
 * peker eller en array, kan du bruke strlen() som returnerer antall
 * char-s i stringen ekslusiv 0-terminatoren på slutten.
 * (Vår egen string_length() gjør samme jobben.)
 */

int len = string_length(alpha);
for (int i = 0; i < len; i++)
	cout << alpha[i];
cout << endl;
len = string_length(omega);
for (int i = 0; i < len; i++)
	cout << omega[i];
cout << endl;

return 0;
}

/* elems: Peker til starten på en serie med double-s.
* len: Antall double-s i elems.
*
* Sum element 0 til len ekslusiv i
* arrayet elems.
*/
double sum(double elems[], int len)
{
double sum = 0;
for (int i = 0; i < len; i++)
	sum += elems[i];
return sum;
}

/* elems: Peker til starten på en serie av 5 float-s.
*
* Finn maksverdien av verdiene i elems. Kompileren
* gjør ingen forskjell på elems[5], elems[], *elems,
* så 5 er bare for utvikleren.
*/
float max_of_five(float elems[5])
{
float max = elems[0];
for (int i = 1; i < 5; i++)
	if (elems[i] > max)
		max = elems[i];
return max;
}

/* elems: Peker til starten på en serie med double-s.
* len: Antall elementer i elems.
*
* Finn gjennomsnitt av verdiene i element 0
* til len ekslusiv. Det er kallerens ansvar å
* sørge for at programmet har allokert minnet.
* Notasjonen *elems kunne også skrives som
* elems[] eller elems[10], men siste er misvisende.
*/
double avg(double *elems, int len)
{
return sum(elems, len) / len;
}

/* elems: Peker til starten av en serie med pekere
* til starten av en serie med chars. Whew!
* len: Antall elementer i elems. (Antall pekere til
* char-pekere.)
*
* NOTE:
* En array av char-s i C/C++ kalles en C-string og
* du kan alltid anta at det siste element er
* char-en'' eller 0, når du sender denne til en
* funksjon. Det er også din jobb å sørge for at
* C-strings terminerer med '' ('' == 0) når du
* har satt sammen C-strings selv (f eks mottatt data
* over sockets eller fra fil).
*/
void print_all(char *elems[], int len)
{
/* Send pekeren til den første char-en på det i-te
 * elementet i elem (elem peker på pekere til char-s).
 * cout antar at dette er en C-string og printer ut hver
 * char etter char-en som pekes til av elems[i] til stdout.
 * Se funksjonen under.
 */
for (int i = 0; i < len; i++)
	cout << elems[i] << endl;
}

/* elems: Peker til det første elementet til en serie
* med char-s. (Kunne også skrevet char *str som argument
* her; spiller ingen rolle for kompilatoren.)
*
* NOTE:
* Trenger ikke å sende med lengden, siden det er
* antatt at den slutter med ''.
*
* Printer ut en C-string til stdout.
*/
void print_str(char str[])
{
while (*str) /* så lenge verdien til str (en char) ikke er 0 */
	cout << *(str++); /* print ut verdien til str, men først inkrement pekeren til str */
}

/* to: Pekeren til det første elementet til en serie med
* char-s.
* from: Samme som over.
*
* Kopierer en C-string fra from til to. Det er fortsatt kallerens
* ansvar å sørge for at to har nok plass.
*/
void string_copy(char *to, char *from)
{
while (*to++ = *from++); /* Jepp, dette gjør jobben. */
}

/* str: Pekeren til det første elementet til en serie med
* char-s. (En C-string altså.)
*
* Gir antall char-s i en C-string.
*/
int string_length(char *str)
{
int n = 0;
while (*str++)
	n++;
return n;
}

 

 

Sorry for at jeg skrev så lite, men skulle akkurat til å legge meg. :p

Endret av LostOblivion
Lenke til kommentar

Hvorfor gjøre alt så komplisert ?

Om jeg ikke husker 100 % feil nå (får ikke testa pga. jeg ikke har C++ på denne maskinen) kan han også gjøre det slik:

#include <iostream>

void test(int *array)
{
  array[0] = 1;
  array[1] = 2;
}
int main()
{
  int x[2];
  test(x); 
  cout << x[0]; 
  return 0;
}

Lenke til kommentar

Kanskje slik?

 

#include <iostream>

using namespace std;

void test(int* &array)
{
 if(array != null)
delete[] array;
 array = new int[2];
 array[0] = 1;
 array[1] = 2;
}

int main()
{
 int *x = NULL;
 test(x);
 cout << x[0];
 delete[] x;
 return 0;
}

 

Hvordan det gjøres kommer jo selvsagt helt an på hva en er ute etter.

Endret av GeirGrusom
Lenke til kommentar
Min egen personlige mening, men kan også ha noe med at jeg har brukt vector's mindre opp igjennom tida enn arrays :p

 

ok.... Jeg mener at du tar feil :), det å bruke array introduserer mange flere muligheter for feil. Jeg synter også at det er enklere og "renere" å bruke vector, men jeg ser at når man ikke er så erfaren med c++ kontainere så kan det virke motsatt.

 

Husk å ta i meningen din at ditt eksempel er mye mye enklere enn vector koden.

 

Dette er år 2009 kompilatorene er blitt så gode at det finnes minimalt med praktiske argumenter for å bruke arrayer.

Lenke til kommentar

Jeg bruker alltid std::vector til generelle arrays og std::list når det er heavy med pushing og popping. Jeg bruker aldri vanlige arrays. De eneste "liksom-grunnene" til å bruke C-style arrays er at man jo får litt bedre hastighet, men hvis et program må optimaliseres så til helvete at en vector eller list blir for mye overhead, så har man et design-problem i utgangspunktet.

Lenke til kommentar

Opprett en konto eller logg inn for å kommentere

Du må være et medlem for å kunne skrive en kommentar

Opprett konto

Det er enkelt å melde seg inn for å starte en ny konto!

Start en konto

Logg inn

Har du allerede en konto? Logg inn her.

Logg inn nå
×
×
  • Opprett ny...