Kullanıcının girdiği string'i diziye atama (C++)

Başlatan 0u2h4n, 02 Ağustos 2012 - 22:10:39

« önceki - sonraki »

0 Üyeler ve 1 Ziyaretçi konuyu incelemekte.

0u2h4n

Yapmak istediğim şey kullanıcı tarafından girilen isimleri diziye atamak. Bunun için aşağıdaki gibi kod yazdım ama "invalid types 'char[int]' for array subscript" hatasını verdi. Bu sorunu nasıl çözebilirim? Yardımlarınızı bekliyorum.

int main()
{
int i,n,m;
string mystr,players;

cout << "Oyuncu sayısını giriniz: ";
cin >> i;
cout << endl;
for(n=1; n<i+1; n++)
{
cout << n << ". oyuncu: ";
cin >> mystr;
for (m=0; m<=mystr.size(); m++)
{
players[m][n] = mystr[m];
}
}

}

travego0403

Ne yapmak istediğinizi anlamadım ama temel konularda biraz eksiğiniz var. Tek bir string tanımlamışsınız ama dizi olarak kullanmaya çalışıyorsunuz.

Eğer oyuncu değişkeniniz programın çalışması esnasında belirleniyorsa bu durumda bellek işlemlerine gimeniz gerekiyor. Çünkü C/C++ ta

int oyuncuSayisi;
cin>>oyuncuSayisi;
string oyuncular[oyuncuSayisi];

gibi bir kullanım söz konusu değil. Derleyici en başta ne kadarlık bir bellek ihtiyacı olduğunu bilmeli ve program başlatıldıktan sonra bellek ayrılmalı. Dediğim gibi eğer bu değişken ise bellek ayrıma, serbest bırakma gibi bellek işlemlerini incelemelisiniz ki bunu yaparken dikkatli olmalısınız. Çünkü C/C++ ın hata yapmaya en açık olan yerlerinden birisidir. Bellek sızıntısı gibi istenmeyen durumlar oluşabilir.
"Matematik bir dildir ve bu dilde şairlere fizikçi denir." Richard Feynman

0u2h4n

Benim yapmak istediğim kullanıcı tarafından girilecek birden fazla ismi sonradan da kullanabilmek. Bunun için girilen isimleri bir 2 boyutlu bir diziye atmayı düşündüm ama yapamadım. Yardımınızı beklediğim 2 sorum olacak :

1. Kullanıcının programın başında girdiği isimleri sonradan nasıl kullanabilirim?
2. Kullanıcının girdiği bu isimleri sınıfın nesnesi olarak tanımlayabilir miyim?

Erdem

#3
Alıntı yapılan: 0u2h4n - 03 Ağustos 2012 - 03:09:39
1. Kullanıcının programın başında girdiği isimleri sonradan nasıl kullanabilirim?

0u2h4n eğer girilen isimleri kelime kelime bir değişkene atmak istiyorsan vektör topluluğundan faydalanabilirsin. Vektörü C'deki dizinin karşılığı olarak düşünebilirsin. Ama içinde herhangi bir veri tipi bulundurabilir. Bu durumda kullanacağın değişken vector<string> olmuş oluyor.

Vektör gibi C++'nin standart şablon kütüphanesinde bulunan olanakları anlatan Türkçe C++ kitabı var mı bilmiyorum. Ama aşağıdaki makaleler vektör topluluğunun nasıl kullanılacağını anlatıyor.

http://acehreli.org/turkcecpp/vector_temel.html
http://acehreli.org/turkcecpp/vector_ileri.html

Eğer okunan değerleri kelime kelime bir topluluğa atmak istiyorsan bunun gibi bir program kullanabilirsin.

#include <iostream>
#include <string>
#include <sstream>
#include <iterator>
#include <vector>

int main()
{
    using namespace std;
    string cumle = "Bir 1 iki 2 uc 3 dort 4";

    istringstream giris(cumle);

    vector<string> kelimeler;
    copy(istream_iterator<string>(giris),
         istream_iterator<string>(),
         back_inserter<vector<string> >(kelimeler));

    copy (kelimeler.begin (), kelimeler.end (),
          ostream_iterator <string> (cout, "\n"));
}


Burada cümleyi hazır verdim. Ama istersen bunu kullanıcının girdiği değerleri okuyacak şekilde de değiştirebilirsin.

Alıntı yapılan: 0u2h4n - 03 Ağustos 2012 - 03:09:39
2. Kullanıcının girdiği bu isimleri sınıfın nesnesi olarak tanımlayabilir miyim?

Bundan tam emin değilim. Aslında C++ ile aktif olarak uğraşmayalı uzun zaman oldu. Artık D öğreniyorum (Biraz reklam yapalım  :D )

O yüzden sana tavsiyem bunu bana göre daha fazla C++ bilen arkadaşların olduğu ceviz.net forumlarında sorabilirsin.


Mesaj tekrarı yüzünden mesajınız birleştirildi. Bu mesajın gönderim tarihi : 04 Ağustos 2012 - 02:23:01

0u2h4n sanırım şimdi yapmak istediğini daha iyi anladım. Vektör gibi toplulukların özelliği içinde kullanıcı tanımlı değişkenleri de tutabilmesidir. Bu yüzden en mantıklısı bir oyuncu sınıfı oluşturup onu vektör topluluğunun içinde saklamak.

#include <iostream>
#include <string>
#include <vector>

using namespace std;

class Oyuncu
{
    string isim_;
    int numara_;

public:
    Oyuncu(int numara)
        : numara_(numara)
    {
        cin >> isim_;
    }
    int NumaraOgren() const { return numara_; }
    string IsimOgren() const { return isim_; }

};

typedef vector<Oyuncu> Oyuncular;
Oyuncular oyuncular;

void oyuncuOlustur(int kacTane)
{
    for (int i = 0; i < kacTane; ++i) {
        oyuncular.push_back(Oyuncu(i));
    }
}

int main()
{
    int oyuncuSayisi;
    cout << "Oyuncu sayısını giriniz: ";
    cin >> oyuncuSayisi;

    oyuncuOlustur(oyuncuSayisi);

    for (int i = 0; i < oyuncular.size(); ++i)
    {
        cout << "Ben " << oyuncular[i].NumaraOgren() << " numaralı oyuncuyum\n";
        cout << " Ismim " << oyuncular[i].IsimOgren() << '\n';
    }
}
Eğer Arch Linux tabanlı bir dağıtıma geçmek isterseniz Arcolinux D sürümünü buradan indirebilirsiniz.

Elektronik

0u2h4n

Kullanıcının girdiği ismi diziye atama işlemini yaptım. Fakat asıl yapmak istediğim programda takıldım. Puan durumu oluşturmak için eklenecek maç sonuçlarını elde etmeyi ve puan durumu oluşturma algoritmasını kuramadım. Şuana kadar yazdğım kodu ekliyorum. Devamı için ya da yaptığım hatalar için öneri bekliyorum, henüz 1 haftadır c++ ile ilgileniyorum.

#include <iostream>
#include <string>
#include <cstring>
using namespace std;

void menu(int i, string players[]);

void sonucekle(int i, string players[])
{

}

void fikstur(int i, string players[])
{
int n,m,o=0,x;

cout << endl << "Fikstür" << endl;

for (n=0; n<i; n++) {
for (m=0; m<i; m++) {
if (m==n)
continue;
else
o++;
cout << o << "." << players[n] << " - " << players[m] << endl;
}
}

cout << endl << "1.Maç Sonucu Ekle" << endl << "2.Ana Menüye Dön" << endl;
cout << "Yapmak istediğiniz işlemin numarasını giriniz: ";
cin >> x;

switch(x) {
case 1:
sonucekle(i,players);
break;

case 2:
menu(i, players);
break;
}

}

void puandurumu(int i, string players[])
{

}

void menu(int i, string players[])
{
int x;
cout << "1.Fikstür" << endl << "2.Puan Durumu" << endl;
cout << "Yapmak istediğiniz işlemin numarasını giriniz: ";
cin >> x;

switch(x) {
case 1:
fikstur(i, players);
break;

case 2:
puandurumu(i, players);
break;

default:
menu(i, players);
break;
}
}


int main()
{
int i,n;
string mystr, *players;

cout << "Oyuncu sayısını giriniz: ";
cin >> i;
cout << endl;
players = new string[i];
for(n=0; n<i; n++)
{
cout << n+1 << ".oyuncu: ";
cin >> players[n];
}

menu(i, players);

}

travego0403

Sınıflar hakkında bilginiz var ise @Erdem'in verdiği sınıf içerisine her oyuncunun sahip olduğu puanı tutan bir değişken daha ekleyiniz, başlangıç değeri sıfır olacak. Mac sonucu girildiğinde istediğiniz şekilde puanları arttırabilirsiniz. Örneğin 3'lük sistemse galip olana 3 puan, eşitlikte 1'er puan gibi. Puan durumunda ise sıralamayı bu puan değişkenine göre yapabilirsiniz.


Eğer sınıflar hakkında bir bilginiz yoksa da bir dizi daha tanımlayınız, elemanları oyuncu sayısı kadar olacak ve başlangıç değerleri sıfır. Eğer 1 ve 2 oyuncu arasında oynanan maçta 1 oyuncu kazandıysa puan[1]+=3; gibi puanını artırabilirsiniz. Puan tablosu da bu diziye göre oluşturulacak. Burada dikkat etmen gereken yer ise sıralamada yer değiştirirken hem puanları hemde isimleri yer değiştirmen gerekecektir.
"Matematik bir dildir ve bu dilde şairlere fizikçi denir." Richard Feynman

0u2h4n

Sınıfları daha iyi anlamak için sınıf kullanarak yapmak istiyorum.

Benim yazdığım kodda players diye tanımladığım string'e oyuncu isimlerini atmıştım. Erdem'im yaptığı gibi:
oyuncular[ i ].NumaraOgren() şeklinde players[ i ].NumaraOgren() kullanabilir miyim?

Yoksa vektörleri kullanarak mı yapmalıyım:

typedef vector<ClassName> Players;
Players players;

for (int i = 0; i < kacTane; ++i) {
       
           players.push_back(player(i));

}

Erdem

Alıntı yapılan: 0u2h4n - 04 Ağustos 2012 - 04:31:13
Kullanıcının girdiği ismi diziye atama işlemini yaptım. Fakat asıl yapmak istediğim programda takıldım. Puan durumu oluşturmak için eklenecek maç sonuçlarını elde etmeyi ve puan durumu oluşturma algoritmasını kuramadım.

Maalesef futbol bilgim biraz zayıf olduğu için  ne yapmak istediğini anlamadım  ;) Ama programın nasıl bir çıktı vermesini istediğini bir örnek üzerinde gösterirsen daha fazla yardımcı olmaya çalışırım.

Alıntı yapılan: 0u2h4n - 04 Ağustos 2012 - 19:46:09
Sınıfları daha iyi anlamak için sınıf kullanarak yapmak istiyorum.

Bence de bu örnek için sınıf kullanımı daha uygun  :D

Alıntı yapılan: 0u2h4n - 04 Ağustos 2012 - 19:46:09
Benim yazdığım kodda players diye tanımladığım string'e oyuncu isimlerini atmıştım. Erdem'im yaptığı gibi:
oyuncular[ i ].NumaraOgren() şeklinde players[ i ].NumaraOgren() kullanabilir miyim?

Yoksa vektörleri kullanarak mı yapmalıyım.

Evet vektörleri kullanarak daha kolay yapabilirsin. Vektörleri C'deki dizilerin C++ daki karşılığı olarak düşünebilirsin. Vektörler herhangi bir kullanıcı tanımlı türü tutabilir. Bu bir sınıf ya da yapı olabilir.

Burada dikkat etmen gereken nokta sınıf tasarımını yaparken örneğin oyuncu nesnemiz olsun. Sonra oyunculardan oluşan bir takım nesnesi oluşturmamız gerekecek. Buradaki ilişki sahip olma anlamında 'has a relationship' tir. Sonra bir lig de takımlardan oluşur. Daha sonra bir takımı da örneğin Takım galatasaray(); şeklinde oluşturabilirsin.

Bu sahip olma ilişkisine örnek olarak bir çerçeve çizmek istediğimizi düşünelim. O zaman bir çerçeve yatay ve dikey çubuklardan oluşur değil mi. O zaman sınıf tasarımını bu şekilde yapabiliriz:

#include <iostream>
using std::cout;

class YatayCubuk
{
public:
    YatayCubuk (int n)
    {
        cout << "+";
        for (int i = 0; i < n; ++i)
            cout << "-";
        cout << "+\n";

    }
};

class DikeyCubuk
{
public:
    DikeyCubuk (int n)
    {
        for (int i = 0; i < n; ++i)
            cout << "|\n";
    }
};

class Cerceve
{
public:
    Cerceve (int uzunluk, int yukseklik)
        : ust_ (uzunluk), orta_ (yukseklik), alt_ (uzunluk)
    {
    }
private:
    const YatayCubuk ust_;
    const DikeyCubuk orta_;
    const YatayCubuk alt_;
};

int main ()
{
    Cerceve (10,2);
}


Nesne yönelimli programlama olanaklarını kullanarak bu işlemin ne kadar kolay yapıldığını görebilirsin.
Eğer Arch Linux tabanlı bir dağıtıma geçmek isterseniz Arcolinux D sürümünü buradan indirebilirsiniz.

Elektronik

0u2h4n

@Erdem, @travego0403: Öncelikler yardımlarınız için teşekkürler.

Sınıflarla ve vektörlere yeteri kadar bakamadığımdan istediğim programı vektörsüz ve sınıfsız yazdım. Mutlaka bunda da hatalar vardır ama onları da zamanla düzeltirim. Yapmak istediğimi daha iyi anlamanız için kodu ekliyorum. Sınıf ve vektörle tekrar yazmaya çalışacağım. Dikkatinizi çeken, bana yardımı dokunacak eklemeler yaparsanız memnu olurum. Tekrar teşekkürler..

#include <iostream>
#include <string>
#include <cstring>
using namespace std;

void menu(int i, string players[], int points[], int gf[], int ga[]);

void sonucekle(int i, string players[], int points[], int gf[], int ga[])
{
int x,m,n,home,away,match_number=0;

cout << "Sonucunu eklemek istediğiniz maçın numarasını giriniz: ";
cin >> x;

for (n=0; n<i; n++) {
for (m=0; m<i; m++) {
if (m==n)
continue;
else
match_number++;

if (match_number == x) {
cout << players[n] << ": ";
cin >> home;
cout << players[m] << ": ";
cin >> away;

gf[n] += home;
gf[m] += away;
ga[n] += away;
ga[m] += home;

if (home > away) {
points[n] += 3;
} else if (home < away) {
points[m] += 3;
} else {
points[n] += 1;
points[m] += 1;
}
}
}
}

menu(i, players, points, gf, ga);
}

void fikstur(int i, string players[], int points[], int gf[], int ga[])
{
int n,m,match_number=0,x;

cout << endl << "Fikstür" << endl;

for (n=0; n<i; n++) {
for (m=0; m<i; m++) {
if (m==n)
continue;
else
match_number++;
cout << match_number << "." << players[n] << " - " << players[m] << endl;
}
}

cout << endl << "1.Maç Sonucu Ekle" << endl << "2.Ana Menüye Dön" << endl;
cout << "Yapmak istediğiniz işlemin numarasını giriniz: ";
cin >> x;

switch(x) {
case 1:
sonucekle(i, players, points, gf, ga);
break;

default:
menu(i, players, points, gf, ga);
break;
}

}

void puandurumu(int i, string players[], int points[], int gf[], int ga[])
{
int n;

for (n=0; n<i; n++)
{
cout << n+1 << "." << players[n] << '\t' << points[n] << '\t' << gf[n] << '\t' << ga[n] << '\t' << ga[n] - gf[n] << endl;
}

menu(i, players, points, gf, ga);
}

void menu(int i, string players[], int points[], int gf[], int ga[])
{
int x;
cout << endl << "1.Fikstür" << endl << "2.Puan Durumu" << endl;
cout << "Yapmak istediğiniz işlemin numarasını giriniz: ";
cin >> x;

switch(x) {
case 1:
fikstur(i, players, points, gf, ga);
break;

case 2:
puandurumu(i, players, points, gf, ga);
break;

default:
menu(i, players, points, gf, ga);
break;
}
}


int main()
{
int i,n;
string mystr, *players;

cout << "Oyuncu sayısını giriniz: ";
cin >> i;
int points[i], gf[i], ga[i];
cout << endl;
players = new string[i];
for(n=0; n<i; n++)
{
cout << n+1 << ".oyuncu: ";
cin >> players[n];
points[n]=0;
gf[n]=0;
ga[n]=0;
}

menu(i, players, points, gf, ga);

}

Erdem

Mesela bir Takım sınıfı olabilir. Bu takımın oynadığı maç sayısı, kazandığı maç sayısı, atılan, yenen goller ve maçyap gibi üye işlevleri olabilir. Sonra bu sınıf  toplam puanını tutabilir.  Gene takımda oyuncular olabilir.

class Takım
{
    /* .. */
private:
    vector<Oyuncu> oyuncular;
};


Sonra fikstür oluştur işlevi takımlar arasından rastgele bir fikstür oluşturabilir. Her takım kendi puan durumunu tutacağı için puanları göster işlevi de takımların isimlerini ve puanlarını en yüksekten en düşüğe sıralayarak gösterebilir.

Kısacası bu biraz senin hayal gücüne kalmış. İstediğin gibi geliştirebilirsin  :D
Eğer Arch Linux tabanlı bir dağıtıma geçmek isterseniz Arcolinux D sürümünü buradan indirebilirsiniz.

Elektronik

0u2h4n

#10
Alıntı yapılan: Erdem - 05 Ağustos 2012 - 00:35:24

class Takım
{
    /* .. */
private:
    vector<Oyuncu> oyuncular;
};



Bu kodlarda yazdığın Oyuncu ve oyuncular tam olarak ne oluyor ?


Mesaj tekrarı yüzünden mesajınız birleştirildi. Bu mesajın gönderim tarihi : 05 Ağustos 2012 - 06:00:36

@Erdem: İlk verdiğin örnekten yararlanarak kodu sınıf ve vektörlerle tekrar yazdım. Fakat sınıf içindeki "pts, w, d, l, gf, ga, gd" değişkenlerinin başlangıç değerlerini sıfırlayamadım.

#include <iostream>
#include <string>
#include <vector>
using namespace std;

class Team
{
string name;
int player_no;
int pts, w, d, l, gf, ga, gd;

public:
    Team(int a)
        : player_no(player_no)
    {
    cout << a << ".oyuncu: ";
    cin >> name;
    }
    int NumaraOgren() const { return player_no; }
    string IsimOgren() const { return name; }

int points (int a) { return pts += a; }
int wins (int a) { return w += a; }
int draws (int a) { return d += a; }
int losses (int a) { return l += a; }
int goalscored (int a) { return gf += a; }
int goalagainst (int a) { return ga += a; }
int goaldifference (int a) { return gd += a; }

};

typedef vector<Team> Players;
Players players;

void menu(int i);

void sonucekle(int i)
{
int x,m,n,home,away,match_number=0;

cout << "Sonucunu eklemek istediğiniz maçın numarasını giriniz: ";
cin >> x;

for (n=0; n<i; n++) {
for (m=0; m<i; m++) {
if (m==n)
continue;
else
match_number++;

if (match_number == x) {
cout << players[n].IsimOgren() << ": ";
cin >> home;
cout << players[m].IsimOgren() << ": ";
cin >> away;

players[n].goalscored(home);
players[n].goalagainst(away);
players[m].goalscored(away);
players[m].goalagainst(home);

players[n].goaldifference(home-away);
players[m].goaldifference(away-home);

if (home > away) {
players[n].points(3);
players[n].wins(1);
players[m].losses(1);
} else if (home < away) {
players[m].points(3);
players[m].wins(1);
players[n].losses(1);
} else {
players[n].points(1);
players[m].points(1);
players[n].draws(1);
players[m].draws(1);
}
}
}
}

menu(i);
}

void fikstur(int i)
{
int n,m,match_number=0,x;

cout << endl << "Fikstür" << endl;

for (n=0; n<i; n++) {
for (m=0; m<i; m++) {
if (m==n)
continue;
else
match_number++;
cout << match_number << "." << players[n].IsimOgren() << " - " << players[m].IsimOgren() << endl;
}
}

cout << endl << "1.Maç Sonucu Ekle" << endl << "2.Ana Menüye Dön" << endl;
cout << "Yapmak istediğiniz işlemin numarasını giriniz: ";
cin >> x;

switch(x) {
case 1:
sonucekle(i);
break;

default:
menu(i);
break;
}
}

void puandurumu(int i)
{
int n;

cout << "Puan Durumu" << endl;
cout << "Players" << '\t' << "Pts" << '\t' << "W" << '\t' << "D" << '\t' << "L"
<< '\t' << "GF" << '\t' << "GA" << '\t' << "GD" << endl;

for (n=0; n<i; n++)
{
cout << n+1 << "." << players[n].IsimOgren() << '\t' << players[n].points(0) << '\t' << players[n].wins(0)
<< '\t' << players[n].draws(0) << '\t' << players[n].losses(0) << '\t' << players[n].goalscored(0)
<< '\t' << players[n].goalagainst(0) << '\t' << players[n].goaldifference(0) << endl;
}

menu(i);
}

void menu(int i)
{
int x;

cout << endl << "1.Fikstür" << endl << "2.Puan Durumu" << endl;
cout << "Yapmak istediğiniz işlemin numarasını giriniz: ";
cin >> x;

switch(x) {
case 1:
fikstur(i);
break;

case 2:
puandurumu(i);
break;

default:
menu(i);
break;
}
}

int main()
{
int i,n;

cout << "Oyuncu sayısını giriniz: ";
cin >> i;

for(n=0; n<i; n++)
{
players.push_back(Team(n+1));
}

menu(i);

}


@Erdem: Kodlarda sınıf içerisinde mantığını anlamadan tamamen senin örneğine göre kullandığım kod var. Bu kodu main fonksiyonunda çağrıldığı kısmı ile birlikte açıklar mısın?
public:
    Team(int a)
        : player_no(player_no)
    {
    cout << a << ".oyuncu: ";
    cin >> name;
    }
    int NumaraOgren() const { return player_no; }
    string IsimOgren() const { return name; }

for(n=0; n<i; n++)
{
players.push_back(Team(n+1));
}

Erdem

Alıntı yapılan: 0u2h4n - 05 Ağustos 2012 - 02:11:43
Alıntı yapılan: Erdem - 05 Ağustos 2012 - 00:35:24

class Takım
{
    /* .. */
private:
    vector<Oyuncu> oyuncular;
};



Bu kodlarda yazdığın Oyuncu ve oyuncular tam olarak ne oluyor ?

Burada Oyuncu bir sınıf. oyuncular ise içinde Oyuncu bulunduran bir vektör topluluğu. Bir vektörün ne olduğuna gelince onu da ufak bir örnekle göstermeye çalışayım. Kod içinde açıklamalar var:

#include <iostream>
#include <vector>

using namespace std;

int main ()
{
    // -------------------------------------------------------
    //                      VEKTÖRLER
    // -------------------------------------------------------
   
    // Vektör tek uçlu bir dinamik dizi
    // gerçeklemesidir. Vektör rastgele erişime izin
    // verir. Yani operator [] işlecini kullanarak belirli
    // bir sıradaki elemana erişebilirsiniz. Vektörün en
    // sonuna eleman eklemek ve çıkarmak çok hızlıdır. Ancak
    // vektörün --başına ya da ortasına-- eleman eklemek
    // yavaştır çünkü tüm elemanların sırayı bozmadan
    // kaydırılmaları gerekir.
    //                        vektör
    //          ---------------------------------
    //          |  |   |  |  |  |  |  |  |  |  | -->
    //          ---------------------------------

   
    // vektör'e ilk değer atanmamıştır. Bu yüzden varsayılan
    // kurucu (default constructor) boş bir vektör topluluğu
    // oluşturur.
   
    vector <int> sayilar;

    // push_back üye işlevi tüm ardışık topluluklarda
    // mevcuttur

    for (int i = 1; i <= 6; ++i)
    {
        sayilar.push_back (i);
    }

    // size üye işlevi topluluktaki elemanların sayısını
    // döndürür.

    // Bu işlev tüm topluluk sınıflarında mevcuttur
    // (vektör, ÇBK, liste, map, multimap, set, multiset)

    for (int i = 0; i < sayilar.size (); ++i)
    {
        cout << sayilar [i] << " ";
    }
    cout << "\n";
   
    // Alt küme operatörü operator [] ile vektörün herhangi
    // bir elemanına erişebiliriz.

    // Vektörler --rastgele erişime-- izin verir.
    cout << "Vektörün ikinci elemanı: " << sayilar [1] << '\n';
       
}


Alıntı Yap
İlk verdiğin örnekten yararlanarak kodu sınıf ve vektörlerle tekrar yazdım. Fakat sınıf içindeki "pts, w, d, l, gf, ga, gd" değişkenlerinin başlangıç değerlerini sıfırlayamadım.

İlkönce w, d vs.. gibi sihirli değişken isimlerinden kaçınmak gerekir. Bunun yerine değişken isimlerini uzun uzun yazmak kodun okunabilirliği açısından iyi bir programcılık deneyimidir.

Ayrıca sınıfın üye değişkenlerini belirtmek için değişkenin hemen sonuna bir alt çizgi ekleyebilirsin. players_ gibi ..

class Player
{
    int no_;
public:
    Player(int no)
        : no_(no)
    {}
};


class Team
{
    int gamesPlayed_;
    int goalsScored_;
    string name_;
    vector<Player> players_;

public:
    Team(string name)
        :name_(name),
         gamesPlayed_(0),
         goalsScored_(0)
    {
        /*
          bu şekilde de kullanabiliriz
          goalsScored_ = 0;
        */
    }
};


Burada ilklendirmeyi initializer list denilen ilklendirme listesinden : hemen sonra yapabileceğin gibi kurucu işlevin küme parantezleri arasında da yapabilirsin.

Yazdığın sonuçEkle ve fikstür işlevlerine baktığımda daha temelde çok eksiklikler olduğunu görüyorum. Demek istediğim bizim burada sınıfları yazmamızın amacı zaten bu işlevlerden kurtulmak  ;) Yani kodumuzun daha basit, okunabilir olması.

Eğer özellikle C++ öğrenmen gerekiyorsa İngilizce bildiğini de düşünerek sana tavsiyem Accelerated C++ kitabını alıp okumandır.

http://amzn.com/020170353X

Eğer Amazon'dan alışveriş yapma imkanın yoksa pandora gibi bazı yayınevleri yabancı teknik kitapları getiriyorlar.

Daha önce bu mesajda da bahsettiğim gibi C++'nın en son standardı olan C++11 ile gelen yeniliklerin hepsi D dilinde zaten var. Hatta bazı olanaklar D'de daha iyi. O yüzden eğer C++ öğrenmek için özel bir neden yoksa direkt D dilini öğrenmeni tavsiye ederim.

D konusunda yazılmış Türkçe bir kitap:

http://www.ddili.org/ders/d/index.html

D dili forumları:

http://www.ddili.org/forum/

Alıntı Yap
Kodlarda sınıf içerisinde mantığını anlamadan tamamen senin örneğine göre kullandığım kod var. Bu kodu main fonksiyonunda çağrıldığı kısmı ile birlikte açıklar mısın?
public:
    Team(int a)
        : player_no(player_no)
    {
    cout << a << ".oyuncu: ";
    cin >> name;
    }
    int NumaraOgren() const { return player_no; }
    string IsimOgren() const { return name; }

for(n=0; n<i; n++)
{
players.push_back(Team(n+1));
}


Buradaki oyuncuOlustur() işlevi istediğimiz sayıda oyuncuyu oluşturur ve vektör topluluğuna atar. Buradaki push_back sadece arkasına ekleme anlamındadır. Eğer yukarıda eklediğim vektör örneğinin açıklamalarına bakarsan daha iyi görebilirsin. Vektör sadece bir ucundan eleman ekleyip çıkarabileceğimiz bir topluluktur.
Eğer Arch Linux tabanlı bir dağıtıma geçmek isterseniz Arcolinux D sürümünü buradan indirebilirsiniz.

Elektronik

sem

Alıntı yapılan: travego0403 - 03 Ağustos 2012 - 00:58:31
Ne yapmak istediğinizi anlamadım ama temel konularda biraz eksiğiniz var. Tek bir string tanımlamışsınız ama dizi olarak kullanmaya çalışıyorsunuz.

Eğer oyuncu değişkeniniz programın çalışması esnasında belirleniyorsa bu durumda bellek işlemlerine gimeniz gerekiyor. Çünkü C/C++ ta

int oyuncuSayisi;
cin>>oyuncuSayisi;
string oyuncular[oyuncuSayisi];

gibi bir kullanım söz konusu değil. Derleyici en başta ne kadarlık bir bellek ihtiyacı olduğunu bilmeli ve program başlatıldıktan sonra bellek ayrılmalı. Dediğim gibi eğer bu değişken ise bellek ayrıma, serbest bırakma gibi bellek işlemlerini incelemelisiniz ki bunu yaparken dikkatli olmalısınız. Çünkü C/C++ ın hata yapmaya en açık olan yerlerinden birisidir. Bellek sızıntısı gibi istenmeyen durumlar oluşabilir.


http://forum.ubuntu-tr.net/index.php?topic=16724.msg205379#msg205379

Şuradan konuşmuştuk eskiden =) Bu durum C99 standartları ile düzeltilmişti yani güncellenmişti bir değişiklik mi var acaba C++ ve C ile bu konu arasında?
".NET çemberinden geçen lirisist etkisi bir 'Volcano', bir yüzüm Java bir yüzüm Badalamenti Don Tano"
----------------------------------------------------------------------------------------------------------------------
"Her yer ölüm yine, burası dünya
Derken ölüm bile bu nasıl dünya?
Benden ölüm dile, batıyor gün yine
Burası dünya?

Erdem

Alıntı Yap
Eğer oyuncu değişkeniniz programın çalışması esnasında belirleniyorsa bu durumda bellek işlemlerine gimeniz gerekiyor. Çünkü C/C++ ta

int oyuncuSayisi;
cin>>oyuncuSayisi;
string oyuncular[oyuncuSayisi];

gibi bir kullanım söz konusu değil. Derleyici en başta ne kadarlık bir bellek ihtiyacı olduğunu bilmeli ve program başlatıldıktan sonra bellek ayrılmalı. Dediğim gibi eğer bu değişken ise bellek ayrıma, serbest bırakma gibi bellek işlemlerini incelemelisiniz ki bunu yaparken dikkatli olmalısınız. Çünkü C/C++ ın hata yapmaya en açık olan yerlerinden birisidir. Bellek sızıntısı gibi istenmeyen durumlar oluşabilir.

Ben burada herhangi bir yasal olmayan kullanım görmüyorum.

    int oyuncusayisi;
    cin >> oyuncusayisi;
    string oyuncular[oyuncusayisi];


Yerel değişkenlerin ilklendirilmemiş olması belki yasal olmayan bir kullanım olarak düşünülebilir. Ancak ilklendirilmemiş yerel değişkenleri giriş akımından okutmak yasaldır.

Ayrıca new ile dinamik olarak bellek ayrılmadığı için bellek sızıntısı olması da düşünülemez.

Ama C++'de diziler yerine vektör kullanmak daha doğal ve uygun bir yoldur.

    vector<string> oyuncu;
Eğer Arch Linux tabanlı bir dağıtıma geçmek isterseniz Arcolinux D sürümünü buradan indirebilirsiniz.

Elektronik

travego0403

Evet, eskiden bu şekildeki bir kod derlenmiyordu. Dizilerin boyutunun belli olması gerekiyordu diye hatırlıyorum. Şimdi denedim ve derlenebiliyor. Standartları takip etmediğim için böyle bir yanlışa düşmüşüm. Ya da kaynak olarak kullandığım kitap eski basım olduğu için. :) Bellek sızıntısını bellek işlemleri hakkında söylemiştim. Bu işlemlerde new ve delete işlemleri.
"Matematik bir dildir ve bu dilde şairlere fizikçi denir." Richard Feynman

0u2h4n

#15
Alıntı yapılan: Erdem - 05 Ağustos 2012 - 00:35:24
Burada Oyuncu bir sınıf. oyuncular ise içinde Oyuncu bulunduran bir vektör topluluğu.

vektör tanımı Team sınıfının içinde yapılmış. bu vektörde ayrı bir Oyuncu sınıfının içinde mi bulunuyor. Yani 2 tane sınıfımız mı var Team ve Oyuncu adlarında.

Alıntı yapılan: Erdem - 05 Ağustos 2012 - 00:35:24
class Player
{
    int no_;
public:
    Player(int no)
        : no_(no)
    {}
};


class Team
{
    int gamesPlayed_;
    int goalsScored_;
    string name_;
    vector<Player> players_;

public:
    Team(string name)
        :name_(name),
         gamesPlayed_(0),
         goalsScored_(0)
    {
        /*
          bu şekilde de kullanabiliriz
          goalsScored_ = 0;
        */
    }
};


Buradaki name_(name) gamesPlayed_(0), goalsScored_(0) değişkenleri public içinde kullanacaksak niye tanımlamalarını private olarak yaptık.

Aşağıdaki kullanımı c++ çalıştığım http://www.cplusplus.com/doc/tutorial/ kaynakta göremedim. Bu kullanımdan biraz bahsedebilir misiniz?

    Team(string name)
        :name_(name),
         gamesPlayed_(0),
         goalsScored_(0)

Alıntı yapılan: Erdem - 05 Ağustos 2012 - 00:35:24
Yazdığın sonuçEkle ve fikstür işlevlerine baktığımda daha temelde çok eksiklikler olduğunu görüyorum. Demek istediğim bizim burada sınıfları yazmamızın amacı zaten bu işlevlerden kurtulmak

Sınıflar yardımıyla bu işlevlerden nasıl kurtulacağımı bulamadığım için öyle yazdım.

Erdem

Alıntı yapılan: 0u2h4n - 06 Ağustos 2012 - 15:56:53
Yani 2 tane sınıfımız mı var Team ve Oyuncu adlarında.

Evet iki tane sınıfımız var. Takım sınıfında bulunan oyuncuları C++'da gelenek olduğu üzere çıkış akımlarını kullanarak şu şekilde yazdırabilirdik:

#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
#include <iterator>


class Player
{
    std::string name_;
public:
    Player(std::string name)
        :name_(name)
    {}
    friend std::ostream& operator << (std::ostream& stream, Player const &player)
    {
        stream << player.name_;
        return stream;
    }
};

class Team
{
    int gamesPlayed_;
    int goalsScored_;
    std::string name_;
    std::vector<Player> players_;

public:
    Team(std::string name)
        :gamesPlayed_(0),
         goalsScored_(0),
         name_(name)
    {}

    void addPlayer(const Player& player)
    {
        players_.push_back(player);
    }

    inline const std::vector<Player> & getPlayers() const { return players_; }
    friend std::ostream & operator<< (std::ostream &, Team const &);
};


std::ostream &operator<<(std::ostream & os, Team const & team)
{
    const std::vector<Player> & players = team.getPlayers();
    std::copy(players.begin(), players.end(),
              std::ostream_iterator<Player>(os, "\n"));
    return os;

}


int main()
{
    Team galatasaray("Galatasaray");
    galatasaray.addPlayer(Player("Hakan Sukur"));
    galatasaray.addPlayer(Player("Hasan Sas"));
    std::cout << galatasaray;
}


Alıntı yapılan: 0u2h4n - 06 Ağustos 2012 - 15:56:53
Buradaki name_(name) gamesPlayed_(0), goalsScored_(0) değişkenleri public içinde kullanacaksak niye tanımlamalarını private olarak yaptık.

Bunun nedeni nesne yönelimli programlamanın ilkelerinden sarma (encapsulation) gereği sınıfa ait üye değişkenlerin sadece sınıf içinden ve arkadaş işlevler üzerinden erişilmesini istediğimiz için yazdık. Bunu şöyle basitçe örnekleyebiliriz. Örneğin bir banka hesabı programımız olsun. Programı kullanan kullanıcımız banka bakiyelerini değiştirememeli, sadece bakiyesini görüntüleyebilmeli, eğer hesabında para varsa para çekebilmeli vs..

Alıntı yapılan: 0u2h4n - 06 Ağustos 2012 - 15:56:53
Aşağıdaki kullanımı c++ çalıştığım http://www.cplusplus.com/doc/tutorial/ kaynakta göremedim. Bu kullanımdan biraz bahsedebilir misiniz?

    Team(string name)
        :name_(name),
         gamesPlayed_(0),
         goalsScored_(0)


Burada çok önemli olmasa da derleyici üyelerin ilklenme sıraları ile ilgili bir uyarı veriyor. Yani burada üstte yazdığım örnekte olduğu gibi name_(name) en sonda olacak. Burada yapılan da basitçe

gamesPlayed_ = 0;
goalsScored_ = 0;
name_ = name;


atamalarını yapmak. Böylece ortalıkta geçersiz üye değişken kalmamış oluyor.

C++ konusunda şu ücretsiz olarak internetten okunabilen kitap gayet güzel bir kitaptır:

http://www.relisoft.com/book/

Alıntı yapılan: 0u2h4n - 06 Ağustos 2012 - 15:56:53
Sınıflar yardımıyla bu işlevlerden nasıl kurtulacağımı bulamadığım için öyle yazdım.

Söylemek istediğim yolun başında olduğuna göre ya C++'ı doğru bir şekilde öğreten bir kaynakla işe başla, ya da daha iyisi (Şimdi satışa geçebilirim :D ) D dilini öğren demek istemiştim.

D öğrenmeye başladıktan sonra  bana C++ çok külfetli gelmeye başladı  :D
Eğer Arch Linux tabanlı bir dağıtıma geçmek isterseniz Arcolinux D sürümünü buradan indirebilirsiniz.

Elektronik

0u2h4n

Alıntı yapılan: Erdem - 07 Ağustos 2012 - 02:41:33

C++ konusunda şu ücretsiz olarak internetten okunabilen kitap gayet güzel bir kitaptır:

http://www.relisoft.com/book/

Bu kitabın seviyesi nedir? Bitirdiğimde ne kadar öğrenmiş olurum.

Alıntı yapılan: Erdem - 07 Ağustos 2012 - 02:41:33
Söylemek istediğim yolun başında olduğuna göre ya C++'ı doğru bir şekilde öğreten bir kaynakla işe başla, ya da daha iyisi (Şimdi satışa geçebilirim :D ) D dilini öğren demek istemiştim.

D öğrenmeye başladıktan sonra  bana C++ çok külfetli gelmeye başladı  :D

Ben öncelikle C++ öğrenmek istiyorum :D. Sonra gerekirse D öğrenirim. Zaten C++'tan sonra kolay gelir  :)

Erdem

Alıntı yapılan: 0u2h4n - 07 Ağustos 2012 - 15:06:38
Bu kitabın seviyesi nedir? Bitirdiğimde ne kadar öğrenmiş olurum.
Başlangıç düzeyi diyorlar.
Eğer Arch Linux tabanlı bir dağıtıma geçmek isterseniz Arcolinux D sürümünü buradan indirebilirsiniz.

Elektronik