do funcji całą tablice

0

Przepraszam że was tak męczę. Tym razem mam problem często niestety omijany przez różne tutoriale. Czyli jako hm składnik funkcji chciałbym wrzucić tablice:

void street::rentStreet(player& p1, player& p2)
{
     p1.money -= rent[houses];
     p2.money += rent[houses]; //street ma zmienną owner i chciałbym >> p2 zastąpić p[owner]
     if ( p1.money <= 0 ) { cout << ":("; }
}

tak próbowałem:

void street::rentStreet(player& p[], int n)
{
     p[n].money -= rent[houses];
     cout << "Money substracted. ";
     p[owner].money += rent[houses];
     if ( p1.money <= 0 ) { cout << "\nYou are about to bankruptcy. If you won't collect enough money till the end of turn you will loose.."; }
}

Pozdrawiam,
Unico

2

Jest to w każdym tutorialu: void street::rentStreet(player p[], int n)

0

albo użyj klasy vector:

#include <vector>
//...
void street::rentStreet(vector<player*>& p)
0

Dobra poradziłem sobie. Dzięki za pomoc :)

0

Nie rozumiem problemu. Raz, że jest vector, dwa że tablica jest przekazywana zawsze przez referencje. Czyli wystarczy:

void foo(int * tab, int size)
{
  for(int i = 0; i < size; i++)
  {
    cout << *(tab + i) << endl; //to samo co: cout << tab[i], ale z tym dodawaniem działa szybciej
  }
}

//wywołanie:
int tab[] = {1, 2, 3};
foo(tab, 3);

Generalnie:
tab[0] = &tab

0

tab[0] = &tab - pomylił mi się zapis. Nazwa tablicy jest równocześnie adresem zerowego jej elementu. A więc: &tab[0] = tab jest prawdą.
Co do kwestii szybkości... teraz nie mogę tego znaleźć, ale w Symfonii C++ była gdzieś taka informacja. Chodziło o to, że przy zapisie tab[x], w każdej iteracji trzeba obliczać pozycję od początku. To oznacza, że tab[2] - daje nam dwie operacje (przejście z elementu 0 na 1 i 1 na 2). Natomiast kolejna iteracja daje nam już trzy operacje: przejście z elementu 0 na 1, z 1 na 2 i z 2 na 3. Jeśli chodzi o zapis: tab + 3, to mamy tylko jedną operację. Być może to kwestia kompilatora i optymalizacji. Ale mimo wszystko sądzę, że pętla nr 3 zadziała najszybciej:

int tab[100];

//pętla 1
for(int i = 0; i < 100; i++)
  tab[i] = 0;

//pętla 2
for(int i = 0; i < 100; i++)
  *(tab + i) = 0;

//pętla 3
int * p = tab;
for(int i = 0; i < 100; i++)
  *(p++) = 0;
 

I jeszcze jedno - co jest złego w postinkrementacji licznika pętli?

0

Nazwa tablicy jest... nazwa tablicy. To, ze jest implicit konwersja miedzy nia a jakimkolwiek adresem to inna kwestia.

w każdej iteracji trzeba obliczać pozycję od początku.

Dla mnie to jakas abstrakcja. I nie tylko dla mnie swoja droga, kompilatory tez tak mysla. [Za pozno dzis dla mnie na szukanie w standardzie :)]

sądzę, że pętla nr 3 zadziała najszybciej

Petla 3 akurat zadziala najwolniej z tych wszystkich.

I jeszcze jedno - co jest złego w postinkrementacji licznika pętli?

Standardowe dzialaie post-in/de-krementacji:
#Stworzenie kopii obiektu
#In/de-krementacja prawdziwego obiektu
#Zwrocenie kopii obiektu

Standardowe dzialanie pre-in/de-krementacji:
#In/de-krementacja obiektu
#Zwrocenie obiektu

Przy czym dla zwyklych int'ow to w gruncie rzeczy nie ma znaczenia, problem pojawia sie, gdy iterator jest wiekszy, wtedy czeste-bezsensowne tworzenie go moze byc klopotliwe.

2

dla każdego kompilatora, który ma normalne optymalizacje to bez różnicy. Zapis łatwiejszy w czytaniu jest lepszy bo jest łatwiejszy w czytaniu i kompilator ma łatwiej przy optymalizacjach niż przy zabawie ze wskaźnikami.

Swoją drogą najszybciej robi się tak:

int* k = poczatek + ile_elementow;
for (int* p = poczatek; p != k; p++)
{
  *p = costam;
}

ale powtórze jeszcze raz: dla kompilatora z optymalizacjami jest to bez różnicy i prawie zawsze wygeneruje ten sam kod, więc lepiej używać najłatwiejszego w czytaniu zapisu

0
Juhas napisał(a):

Co do kwestii szybkości... teraz nie mogę tego znaleźć, ale w Symfonii C++ była gdzieś taka informacja.

Ja również czytałem symfonię i nic takiego sobie nie przypominam. Pamiętam, było wyjaśniane, że tab[i] to tak naprawdę *(tab + i) i że tablica jest zbiorem kolejno ułożonych elementów, a zapis tablicowy jest pobraniem elementu przesuniętego o i pozycji. Po to jest zapis tablicowy, żeby z niego korzystać.

2

W teorii najlepsze wyniki powinno dać to co podał @krwq w poście wyżej dla tego że w porównaniu do wersji od @krwq:

  • wersja 3 ma dodatkową inkrementacje p++
  • wersja 2 ma dodatkowe dodawanie tab + i
  • wersja 1 jest teoretycznie tym samym co wersja 2 i ma ukryte dodawanie.
    Tylko że jest to teoria która ma się nijak do praktyki np na procesorach Intel, ponieważ użycie wersji 1 powoduje że procesor to "rozumie" i cashuje dane tablicy.
    Więc na nowszych procesorach intela wersja 1 wygrywa.

1 użytkowników online, w tym zalogowanych: 0, gości: 1