Wektory+funkcje

 
Napisz nowy tematOdpowiedz do tematu    Forum programistyczne Programmers Zone Strona Główna -> C/C++
Autor Wiadomość
bartek4833
~user




Dołączył: 04 Kwi 2008
Posty: 216


PostWysłany: 12-03-10 02:01 Zacytuj zaznaczone Odpowiedz z cytatem

Witamm

Mam szybkie pytanie: Dlaczego te dwie funkcje sie nie widza, wpisuje dane ale nie wyswietlaja sie i czy w ogole dozwolone jest ze za parametr funkcji mozna dac wektor?. Podaje kod:

c++:
void Wyswietl(vector<Pracownik>czlowiek)
{
    for(int i = 0; i < czlowiek.size(); ++i)
    {
        cout<<czlowiek[i].imie<<"\n";
        cout<<czlowiek[i].nazwisko<<"\n";
        cout<<czlowiek[i].staz_pracy<<"\n";
        cout<<czlowiek[i].stawka<<"\n";
    }
}

void dodaj(vector<Pracownik>czlowiek)
{
    char im[60];
    char naz[60];
    cout<<"Podaj imie: ";
    cin>>im;
    cout<<"Podaj nazwisko: ";
    cin>>naz;
   
    czlowiek.push_back(Pracownik(im, naz));

}

Powrót do góry
Zobacz profil autora Wyślij prywatną wiadomość
winuser
~user




Dołączył: 21 Cze 2008
Posty: 464
Skąd: Mikołów
Pomógł: 45

PostWysłany: 12-03-10 04:07 Zacytuj zaznaczone Odpowiedz z cytatem

Mam kilka zasrzeżeń do twojego kodu. Ale o tym potem, najpierw pierwsza rzecz która mi się rzuciła w oczy twója próba dodania elementu do tego wektora która jest troszkę dziwna. Powinieneś sobie utworzyć lokalną zmienną w funkcji `dodaj`, wypełnić jej pola i na końcu dodać do wektora tak jak zrobiłem to ja. Zwracania struktur w funkcjach należy unikać ponieważ marnujesz pamięć i czas procesora. O wiele lepiej skorzystać już ze wskaźników lub referencji. Odnośnie twojego pytania czy funkcje mogą przyjmować takie argumenty, to owszem funkcje mogą przyjmować jako swoje argumenty dowolny typ zmiennej (o ile został wcześniej zdefiniowany), a więc może być to nawet funkcja która przyjmuje jako argument wskaźnik na inną funkcję.

Jeśli już stosujesz przekazywanie kontenerów jako argumenty, należy skorzystać z referencji na dany obiekt aby nie tworzyć niepotrzebnie dodatkowej kopii w tym przypadku wektora i nie marnować pamięci oraz czasu procesora. Moża też przekazać jako wskaźnik (też dobre rozwiązanie) albo tak jak robisz to ty (złe rozwiązanie). Dodatkowo w funkcji takiej jak `Wyswietl` która służy tylko do pokazywania zawartości, argument powinien być stałą referencją, aby uniknąć głupich błędów i być pewnym że w tej funkcji nie modyfikujesz tego kontenera (w przypadku większych funkcji nie jest widoczne na pierwszy rzut oka czy coś modyfikujesz dlatego jest to utrudnienie).

c++:
#include <iostream>
#include <vector>

using namespace std;

typedef struct
{
    string imie;
    string nazwisko;
    int staz_pracy;
    int stawka;
}Pracownik;

void Wyswietl(const vector<Pracownik>& czlowiek) ;
void dodaj(vector<Pracownik>& czlowiek);

int main(int argc, char* argv[])
{
    vector<Pracownik> czlowiek;
    dodaj(czlowiek);
    Wyswietl(czlowiek);
    return 0;
}

void Wyswietl(const vector<Pracownik>& czlowiek)
{
    for(unsigned int i = 0; i < czlowiek.size(); ++i)
    {
        cout<<czlowiek[i].imie<<"\n";
        cout<<czlowiek[i].nazwisko<<"\n";
        cout<<czlowiek[i].staz_pracy<<"\n";
        cout<<czlowiek[i].stawka<<"\n";
    }
}

void dodaj(vector<Pracownik>& czlowiek)
{
    Pracownik prac;
    cout<<"Podaj imie: ";
    cin>>prac.imie;
    cout<<"Podaj nazwisko: ";
    cin>>prac.nazwisko;

    czlowiek.push_back(prac);
}



Użytkownik otrzymał punkt pomocy za ten post.

_________________
Na twoje problemy http://msdn.microsoft.com/en-us/default.aspx

Programowanie W C++ & C http://www.cprogramming.com/
Powrót do góry
Zobacz profil autora Wyślij prywatną wiadomość Wyślij email Odwiedź stronę autora Numer GG Tlen
hobson
+Przyjaciel P-ZONE




Dołączył: 21 Gru 2006
Posty: 1574

Pomógł: 266

PostWysłany: 12-03-10 09:32 Zacytuj zaznaczone Odpowiedz z cytatem

Nieco rozwijając i komentując wypowiedź poprzednika:


  • "Dlaczego te dwie funkcje sie nie widza" - nie istnieje nic takiego, jak "widzenie się" przez funkcje

  • "wpisuje dane ale nie wyswietlaja sie" - poczytaj o przekazywaniu argumentów do funkcji przez wartość i zastosuj się do uwag winusera co do przekazywania kontenera przez referencję.

  • "i czy w ogole dozwolone jest ze za parametr funkcji mozna dac wektor" - jak najbardziej, tylko trzeba to robić z głową. Jak? O tym powiedział winuser.

  • Dodawanie obiektu tymczasowego do kontenera jest wg mnie dobre, problem będzie dopiero, gdy klasa Pracownik będzie miała tak dużo pól, że jej konstruktor będzie musiał przyjmować dużo argumentów.

  • Na współczesnych kompilatorach, gdzie zdecydowana większość implementuje RVO, zwracanie struktur z funkcji nie jest niczym złym wg mnie.

  • Do przechowywania tekstów dużo lepiej nadają się obiekty std::string, niż tablice znaków. Co się stanie, jeśli użytkownik poda nazwisko dłuższe, niż 60 znaków?



Użytkownik otrzymał punkt pomocy za ten post.

_________________
Pamiętaj o znacznikach [syntax="c++"] [/syntax]
Pamiętaj o interpunkcji i ortografii
---
Pomóz mi uczynić te teksty lepszymi:
std::vector Algorytmy standardowe Mój program uruchamia się i zaraz znika. Masz uwagi? pomysły na ulepszenie ich? napisz maila lub PW!
Powrót do góry
Zobacz profil autora Wyślij prywatną wiadomość Wyślij email Numer GG
bartek4833
~user




Dołączył: 04 Kwi 2008
Posty: 216


PostWysłany: 12-03-10 15:11 Zacytuj zaznaczone Odpowiedz z cytatem

Dzieki za odp, ale mam jeszcze jedno pytanie, jak bd z funkcja dodaj jezeli w mojej klasie napisze konstruktor parametryczny, jak wtedy bede mogl sie odniesc do skladnikow klasy? np.

c++:
Pracownik(const char *const im, const char *const naz):
             staz_pracy(0), stawka(2000)
         {
             imie = new char[60];
             nazwisko = new char[60];
             strcpy(imie, im);
             strcpy(nazwisko, naz);
         }

Powrót do góry
Zobacz profil autora Wyślij prywatną wiadomość
winuser
~user




Dołączył: 21 Cze 2008
Posty: 464
Skąd: Mikołów
Pomógł: 45

PostWysłany: 12-03-10 15:20 Zacytuj zaznaczone Odpowiedz z cytatem

Nie rozumiem do końca o co tobie chodzi. Jeśli już uparłeś się na ten char* to niech chociaż będzie odporny na buffer overflow. Czyli funkcja strlen i tworzysz tablice char o rozmiarze takim jak zwroci ci strlen. Odwoływać się możesz do tych pól nazwisko i imie poprzez odpowiednie metody dostępowe - w tym przypadku JakasMetoda()

c++:
class Pracownik
{
        public:
       
                Pracownik(const char *const im, const char *const naz): staz_pracy(0), stawka(2000)
                {
                        imie = new char[strlen(im) + 1];
                        nazwisko = new char[strlen(naz) + 1
                        strcpy(imie, im);
                        strcpy(nazwisko, naz);
                }
                ~Pracownik()
                {
                        if(imie != 0) delete [] imie;
                        if(nazwisko != 0) delete [] nazwisko;
                }
                char* JakasMetoda()
                {
                        return imie;
                }
               
        private:
                char* imie;
                char* nazwisko;
};



Użytkownik otrzymał punkt pomocy za ten post.

_________________
Na twoje problemy http://msdn.microsoft.com/en-us/default.aspx

Programowanie W C++ & C http://www.cprogramming.com/
Powrót do góry
Zobacz profil autora Wyślij prywatną wiadomość Wyślij email Odwiedź stronę autora Numer GG Tlen
hobson
+Przyjaciel P-ZONE




Dołączył: 21 Gru 2006
Posty: 1574

Pomógł: 266

PostWysłany: 12-03-10 15:20 Zacytuj zaznaczone Odpowiedz z cytatem


  1. Nie rozumiem pytania, i nie rozumiem, co ma przedstawiać przykład. Co to znaczy 'bd'?
  2. Istnienie konstruktora parametrycznego nie ma żadnego wpływu na to, jak odnosić się do składników klasy.
  3. Twój przykład będzie działał źle, jeśli ktoś poda imię lub nazwisko użytkownika dłuższe, niż 59 znaków.
  4. Twój konstruktor spowoduje wyciek pamięci, jeśli gdziekolwiek w nim (oprócz pierwszej linijki) nastąpi wyjątek.
  5. Oba powyższe problemy by rozwiązało użycie obiektów klasy std::string jako składowych imie i nazwisko.




Użytkownik otrzymał punkt pomocy za ten post.

_________________
Pamiętaj o znacznikach [syntax="c++"] [/syntax]
Pamiętaj o interpunkcji i ortografii
---
Pomóz mi uczynić te teksty lepszymi:
std::vector Algorytmy standardowe Mój program uruchamia się i zaraz znika. Masz uwagi? pomysły na ulepszenie ich? napisz maila lub PW!
Powrót do góry
Zobacz profil autora Wyślij prywatną wiadomość Wyślij email Numer GG
bartek4833
~user




Dołączył: 04 Kwi 2008
Posty: 216


PostWysłany: 12-03-10 16:14 Zacytuj zaznaczone Odpowiedz z cytatem

Chodzilo mi o te metody dostepowe. A nie moge uzyc std::string bo w zad pisze o tablicy znakow Wink dzieki wielkie za rady Smile
Powrót do góry
Zobacz profil autora Wyślij prywatną wiadomość
hobson
+Przyjaciel P-ZONE




Dołączył: 21 Gru 2006
Posty: 1574

Pomógł: 266

PostWysłany: 12-03-10 16:23 Zacytuj zaznaczone Odpowiedz z cytatem

bartek4833 napisał:
A nie moge uzyc std::string bo w zad pisze o tablicy znakow

Rozumiem. W takim razie mam nadzieję, że masz też powiedziane o konieczności istnienia destruktora, operatora przypisania i konstruktora kopiującego Smile

bartek4833 napisał:
Chodzilo mi o te metody dostepowe.

Zadbaj w takim razie o const-correctness - najlepiej będzie, gdy metoda gettera będzie opatrzona specyfikatorem const, oraz zwróci wskaźnik na stały ciąg znaków.

Dodatkowo, przy użyciu operatora delete nie ma konieczności sprawdzania, czy wskaźnik nie wskazuje na NULL.


Użytkownik otrzymał punkt pomocy za ten post.

_________________
Pamiętaj o znacznikach [syntax="c++"] [/syntax]
Pamiętaj o interpunkcji i ortografii
---
Pomóz mi uczynić te teksty lepszymi:
std::vector Algorytmy standardowe Mój program uruchamia się i zaraz znika. Masz uwagi? pomysły na ulepszenie ich? napisz maila lub PW!
Powrót do góry
Zobacz profil autora Wyślij prywatną wiadomość Wyślij email Numer GG
bartek4833
~user




Dołączył: 04 Kwi 2008
Posty: 216


PostWysłany: 12-03-10 16:28 Zacytuj zaznaczone Odpowiedz z cytatem

Dobra, zrozumialem, jeszcze raz dzieki Wink
Powrót do góry
Zobacz profil autora Wyślij prywatną wiadomość
Wyświetl posty z ostatnich:   
Napisz nowy tematOdpowiedz do tematu    Forum programistyczne Programmers Zone Strona Główna -> C/C++ Wszystkie czasy w strefie EET (Europa)
Strona 1 z 1

 
Skocz do:  
Nie możesz pisać nowych tematów
Nie możesz odpowiadać w tematach
Nie możesz zmieniać swoich postów
Nie możesz usuwać swoich postów
Nie możesz głosować w ankietach

Mapa
Powered by phpBB © 2001, 2005 phpBB Group

 Polecane strony