Claire
(Claire)
4 Styczeń 2014 15:51
#1
Witam :)
Moje C++ narazie raczkuje, więc proszę Was o pomoc.
Poniższy program wysypuje mi się w momencie generowania tablicy. Co jest źle?
#include <iostream>
#include <stdlib.h>
#include <cmath>
#include <time.h>
using namespace std;
class ciag
{
int n;
int* tab;
public:
ciag() : n(0) {};
ciag(int a) : n(a)
{
tab=new int [a];
};
~ciag()
{
free (tab);
}
friend istream& operator>> (istream&, ciag&);
friend ostream& operator<< (ostream&, ciag&);
}A, B, C, D;
istream& operator>> (istream &in, ciag &A)
{
int a;
cout << "Podaj dlugosc ciagu: ";
in >> A.n;
cout << endl << "Czy chcesz, aby program wygenerowal ciag? 1/0 ";
cin >> a;
if(a==0)
{
cout << "Podaj wyrazy ciagu: ";
for(int i=0; i<A.n; i++)
{
cout << "A[" << i+1 << "] = ";
in >> A.tab[i];
cout << endl;
}
}
else
{
srand((unsigned)time(NULL));
for(int i=0; i<A.n; i++)
{
A.tab[i]=(rand()%100);
in >> A.tab[i];
}
}
return in;
}
ostream& operator<< (ostream &out, ciag &A)
{
if(A.n>0)
{
out << "|";
for(int i=0; i<A.n-1; i++)
{
out << A.tab[i] << ", ";
}
out << A.tab[A.n-1] << "| " << endl;
}
else
{
out << "Ciag zerowy";
}
return out;
}
int main()
{
cin >> A;
cout << A;
system("pause");
}
177
(Copycona)
4 Styczeń 2014 16:34
#2
Jak new[] , to nie free, tylko delete[] .
Każda instancja tej klasy, która została zadeklarowana wykonała konstruktor domyślny. Ten u Ciebie do zmiennej “n” wpisał 0, natomiast “tab” nadal jest niezainicjalowane.
Sama modyfikacja składowej n nic tu nie daje, gdyż nie wiąże się to z przydzieleniem pamięci na ciag. Nadal składowa “tab” jest niezainicjalizowana. Dalej w kodzie piszesz po pamięci, której nie masz, w miejsce zupełnie losowe.
Claire
(Claire)
4 Styczeń 2014 17:24
#3
Ok, zmieniłam to wszystko i cin, cout działa, ale nadal nie losuje mi ciągu. Co teraz?
#include <iostream>
#include <cmath>
#include <time.h>
#include <math.h>
using namespace std;
class ciag
{
int n;
int* tab;
public:
ciag() : n(0)
{
tab=new int [n];
};
friend istream& operator>> (istream&, ciag&);
friend ostream& operator<< (ostream&, ciag&);
}C, D;
istream& operator>> (istream &in, ciag &A)
{
int a;
cout << "Podaj dlugosc ciagu: ";
cin >> A.n;
cout << endl << "Czy chcesz, aby program wygenerowal ciag? 1/0 ";
cin >> a;
if(a==0)
{
cout << "Podaj wyrazy ciagu: ";
for(int i=0; i<A.n; i++)
{
cout << "A[" << i+1 << "] = ";
in >> A.tab[i];
cout << endl;
}
}
else
{
srand((unsigned)time(NULL));
for(int i=0; i<A.n; i++)
{
A.tab[i]=(rand()%100);
in >> A.tab[i];
}
}
return in;
}
ostream& operator<< (ostream &out, ciag &A)
{
if(A.n>0)
{
out << "|";
for(int i=0; i<A.n-1; i++)
{
out << A.tab[i] << ", ";
}
out << A.tab[A.n-1] << "| " << endl;
}
else
{
out << "Ciag zerowy";
}
return out;
}
int main()
{
cin >> D;
cout << D;
system("pause");
return 0;
}
xm2
(xm2)
4 Styczeń 2014 17:52
#4
Generujesz ciąg w ten sposób:
for(int i=0; i<A.n; i++)
{
A.tab[i]=(rand()%100);
in >> A.tab[i];
}
Druga linia nie jest poprawna i przedewszystkim zbędna. Zakomentować i ma działać.
BTW Kodowanie takiej logiki w przeciążeniu operatora jest złem i trochę brakuje logiki, żeby zakopać w niej generator ciągu. Lepiej wynieść to na zewnątrz. Chyba, że tak Wam kazali, ale jeżeli tak Wam kazali, to jest mi przykro z tego powodu
177
(Copycona)
4 Styczeń 2014 17:57
#5
No raczej nie. Przecież problem z pisaniem po pamięci której nie ma nadal występuję.
Claire
(Claire)
4 Styczeń 2014 18:05
#6
xm2 - skoro przeciążam >>, to zwraca mi właśnie to “in”. Inaczej co ma zwrócić? Tak mi się wydaje…
177 - W takim razie jak to naprawić?
@edit : Zrobiłam funkcję losującą osobno, nie w przeciążeniu >> i jest ok, losuje i wypisuje. 177 - nadal jest błąd?
class ciag
{
int n;
int* tab;
public:
ciag()
{
n=0;
tab=new int [n];
};
void wylosuj(int);
friend istream& operator>> (istream&, ciag&);
friend ostream& operator<< (ostream&, ciag&);
};
void ciag::wylosuj(int a)
{
n=a;
srand((unsigned)time(NULL));
for(int i=0; i<n; i++)
tab[i]=rand()%100;
}
istream& operator>> (istream &in, ciag &A)
{
cout << "Podaj dlugosc ciagu: ";
in >> A.n;
cout << "Podaj wyrazy ciagu: ";
for(int i=0; i<A.n; i++)
{
cout << "A[" << i+1 << "] = ";
in >> A.tab[i];
cout << endl;
}
return in;
}
ostream& operator<< (ostream &out, ciag &A)
{
if(A.n!=0)
{
out << "|";
for(int i=0; i<A.n-1; i++)
{
out << A.tab[i] << ", ";
}
out << A.tab[A.n-1] << "| " << endl;
}
else
{
out << "Ciag zerowy";
}
return out;
}
int main()
{
ciag C, D;
C.wylosuj(10);
//cin >> D;
cout << C;
system("pause");
return 0;
}
177
(Copycona)
4 Styczeń 2014 18:24
#7
xm2 nie miał na myśli tego, co ten operator zwraca, tylko co robi.
Najprościej: wykonaj new[] dopiero jak będzie znana długość ciągu. W tym przykładzie ta informacja jest dostępna dopiero po 3 instrukcji w operator>>.
Claire
(Claire)
4 Styczeń 2014 22:45
#8
Ok, dziękuję Wam.
Mam do tego programu dopisane sortowanie szybkie. Jak widać, programistką nie będę Ale mam niedługo kolokwium, więc proszę Was jeszcze o zobaczenie co tu się psuje.
void sort(ciag A, int a, int b)
{
int i, j, x, y;
i=a; j=b; x=A.tab[(i+j)/2];
while(i<=j)
{
while((i<b)&&(A.tab[i]<x)) i++;
while((j>a)&&(A.tab[j]>x)) j++;
if(i<=j)
{
y=A.tab[i]; A.tab[i]=A.tab[j]; A.tab[j]=y;
}
if(j>a) sort(A, a, j);
if(i<b) sort(A, i, b);
}
}
kostek135
(kostek135)
5 Styczeń 2014 00:10
#9
Prościej ci go będzie zrozumieć, jeżeli rozbijesz go na dwa etapy: podział i wywołanie rekursywne “połówek”. Tu masz przykładowy kod: http://www.algorytm.org/algorytmy-sortowania/sortowanie-szybkie-quicksort/quick-1-c.html