Εργαστήριο Τεχνολογίας Λογισμικού
+2 votes
296 views

Καλησπέρα. Με τη φόρα που πήρα στις ασκήσεις έρχονται και οι απορίες. Άλλος ένας προβληματισμός. Λύνω την άσκηση 11.21 του βιβλίου όπου ζητάει να φτιαχτεί ένα πρόγραμμα που θα διαβάζει βαθμολογίες 3 μαθημάτων σε 10 μαθητές, θα τις καταχωρίζει σε πίνακα, θα υπολογίζει το μέσο όρο κάθε μαθητή και θα εμφανίζει το πλήθος που πέτυχε και απέτυχε. Τώρα, προσπαθώντας να γράψω τον κώδικα όρισα private και public μέλη μιας κλάσης αλλά όταν φτάνω στο δια ταύτα, δηλαδή πχ. στην εισαγωγή πρώτου μαθήματος ("Εισαγωγή πρώτου μαθήματος για φοιτητές"), το μέλος ma8ima_1 στο cin >> stnts[i].ma8ima_1; , το θεωρεί "inaccessible"! Τι πάει στραβά; Ευχαριστώ

// χώρος ονομάτων
using namespace std;

const size_t NO_STUDENT{ 10 };

// Κλάση student
class student {
private:
	int ma8ima_1{};
	int ma8ima_2{};
	int ma8ima_3{};
public:
	student() {};
	student(float a, float b, float c) : ma8ima_1(a), ma8ima_2(b), ma8ima_3(c) {}
	float getaverage() { return (ma8ima_1 + ma8ima_2 + ma8ima_3) / 3.0; }
} stnts[NO_STUDENT];

int main()
{
	//Εισαγωγή πρώτου μαθήματος για φοιτητές
	cout << "dwse ba8mous sto prwto ma8ima" << endl;
	for (int i = 0; i < NO_STUDENT; ++i)
		cin >> stnts[i].ma8ima_1;

	//Εισαγωγή δεύτερου μαθήματος για φοιτητές
	cout << "dwse ba8mous sto deutero ma8ima" << endl;
	for (int i = 0; i < NO_STUDENT; ++i)
		cin >> stnts[i].ma8ima_2;

	//Εισαγωγή τρίτου μαθήματος για φοιτητές
	cout << "dwse ba8mous sto trito ma8ima" << endl;
	for (int i = 0; i < NO_STUDENT; ++i)
		cin >> stnts[i].ma8ima_3;

	//εκτύπωση του πίνακα των αντικειμένων φοιτητές με τα 3 μαθήματα στον καθένα
	for (int i = 0; i < NO_STUDENT; ++i) {
		cout << stnts[i].ma8ima_1 << '\n';
		cout << stnts[i].ma8ima_2 << '\n';
		cout << stnts[i].ma8ima_3 << '\n';
	}

	int count1{}, count2{};

	//Υπολογισμός μέσου όρου κάθε φοιτητή
	for (int i = 0; i < NO_STUDENT; ++i) {
		const float av{ stnts[i].average() };

		if (av < 9.5) {
			cout << i + 1 << " apetuxe\n";
			++count1;
		}
		else
			if (av > 18.5) {
				cout << i + 1 << " petuxe\n";
				++count2;
			}
	}

	//εκτύπωση ποιοι απέτυχαν και ποιοι πέτυχαν
	cout << "apetuxan: " << count1 << " foitites" << " se pososto  " << count1 / (NO_STUDENT + 0.0) * 100.0 << "%\n";
	cout << "petuxan: " << count2 << " foitites" << " se pososto  " << count2 / (NO_STUDENT + 0.0) * 100.0 << "%\n";
	return 0;
}
in progintro by (820 points) | 296 views

1 Answer

+1 vote

Πρόσεξε λίγο εδώ:

 cout << "dwse ba8mous sto prwto ma8ima" << endl;
    	for (int i = 0; i < NO_STUDENT; ++i)
    		cin >> stnts[i].ma8ima_1;

Στο cin >> stnts[i].ma8ima_1;:
Το νόημα των private members είναι το να μην μπορούν να τα διαχειριστούν άλλοι εκτός της ίδιας της κλάσης (δηλαδή, κώδικας των μεθόδων της).

Για να δουλέψει το παράδειγμά σου μπορείς να δημιουργήσεις συναρτήσεις get/set για τις private τιμές, πχ:

void setMathima1(int a) { mathima1 = a; }
int getMathima1() { return mathima1; }

και κάθε φορά που επιθυμείς να διαβάσεις/γράψεις σε αυτές να καλείς την αντίστοιχη μέθοδο.

Επίσης, ακόμα πιο σωστό θα ήταν να χρησιμοποιήσεις τους constructors που δέχονται τα μαθήματα ως παραμέτρους, και να κατασκευάζεις απευθείας τον μαθητή με όλους τους βαθμούς του.
πχ:

cin >> a >> b >> c;
student mathitis(a, b, c);

Κάτι τελευταίο: ο υπολογισμός του μέσου όρου του κάθε μαθητή εξαρτάται από τους βαθμούς του μαθητή, επομένως θα ταίριαζε πολύ να δημιουργήσεις μια μέθοδο στην κλάση student, όπως float calculateAverageGrade(), που να υπολογίζει και να επιστρέφει τον μέσο όρο.
Οπότε εν τέλει να το χρησιμοποιείς με αυτό τον τρόπο:

cout << student1.calculateAverageGrade() << endl;

το οποίο μου φαίνεται πιο καθαρό, και σου μειώνει πολύ τις γραμμές κώδικα εκτός της κλάσης student :D

by (3.0k points)
edited by
0

Καλημέρα και ευχαριστώ για την απάντηση και την ενασχόληση. Λάθος μου! Είχα βάλει κατα λάθος την set σε operator cout (το οποίο προφανώς δε δουλεύει αφού ειναι void) αντι να βάλω get και επίσης δεν είχα βάλει get στην εκτύπωση. Τώρα το τρέχει τον κώδικα κανονικά, ωστόσο, όταν φτάνει στην εκτύπωση, μου βγάζει άλλα αντί άλλων! Εκεί διαπιστώνω ότι μου εμφανίζει όλο μηδενικά και όχι τις τιμές που έχω θέσει εγώ στο cin, άρα κατ' επέκταση βγαίνει και μηδέν ο μέσος όρος κάθε φοιτητή και άρα το αποτέλεσμα είναι 100% αποτυχία ότι βαθμούς και αν βάλω σε όλους τους φοιτητές.

Ο κώδικας είναι:

// Class student
class student {
private:
	int ma8ima_1{};
	int ma8ima_2{};
	int ma8ima_3{};
public:
	void set_ma8ima_1(int a) { ma8ima_1 = a; }
	int get_ma8ima_1() { return ma8ima_1; }
	void set_ma8ima_2(int b) { ma8ima_2 = b; }
	int get_ma8ima_2() { return ma8ima_2; }
	void set_ma8ima_3(int c) { ma8ima_3 = c; }
	int get_ma8ima_3() { return ma8ima_3; }
	student() {};
	student(float a, float b, float c) : ma8ima_1(a), ma8ima_2(b), ma8ima_3(c) {}

	float average() { return (ma8ima_1 + ma8ima_2 + ma8ima_3) / 3.0; }
} stnts[NO_STUDENT];

int main()
{
	int a, b, c;
	//Βαθμοί πρ΄του μαθήματος
	cout << "dwse ba8mous sto prwto ma8ima" << endl;
	for (int i = 0; i < NO_STUDENT; ++i) {
		cin >> a;
		a = stnts[i].get_ma8ima_1();
	}

	//Βαθμοί δεύτερου μαθήματος
	cout << "dwse ba8mous sto deutero ma8ima" << endl;
	for (int i = 0; i < NO_STUDENT; ++i) {
		cin >> b;
		b = stnts[i].get_ma8ima_2();
	}

	//Βαθμοί τρίτου μαθήματος
	cout << "dwse ba8mous sto trito ma8ima" << endl;
	for (int i = 0; i < NO_STUDENT; ++i) {
		cin >> c;
		c = stnts[i].get_ma8ima_3();
	}

	//Εκτύπωση μαθημάτων φοιτητών
	for (int i = 0; i < NO_STUDENT; ++i) {
		cout << a << '\n';
		cout << b << '\n';
		cout << c << '\n';
	}
0

Αν ο κωδικας σου ειναι αυτό που μας έστειλες, λογικό μου φαίνεται. Δεν αλλάζεις ποτέ τις τιμές των a,b,c όταν τα τυπώνεις, αρα καθε φορά τυπωνεις τα ιδια αποτελέσματα.

0

Δεν υποτίθεται όμως ότι τα a, b, c αλλάζουν εφόσον τους έχω αναθέσει κάθε φορά να λαμβάνουν τιμές stnts[i].get_ma8ima_i(); Επίσης δοκίμασα και το παρακάτω αλλά πάλι το ίδιο βγάζει:

//Εκτύπωση μαθημάτων φοιτητών
	for (int i = 0; i < NO_STUDENT; ++i) {
		cout << stnts[i].get_ma8ima_1() << '\n';
		cout << stnts[i].get_ma8ima_2() << '\n';
		cout << stnts[i].get_ma8ima_3() << '\n';
	}

Τι ακριβώς χάνω σε σκεπτικό που δεν πρέπει και δεν έχω ενσωματώσει;

0

Αν ακολουθήσεις αυτά που σου είπα πριν, θα δουλευει. Η αληθεια ειναι καθε φορα κανεις αλλαγες, τις οποιες δεν ειχα προσεξει. Θα στα ξαναγραψω μια φορα μαζεμενα.

Εχεις μια private μεταβλητη. Αυτο σημαινει οτι ειναι προσβάσιμη μονο απο την ιδια την κλάση, κανεναν αλλο και για κανενα λογο.
Αν θελεις να κανεις αλλαγες στην μεταβλητη, προσθετεις ενα getter και ενα setter οπως εχεις κανει. Ο getter μας επιστρεφει την μεταβλητή και ο setter την αλλάζει.

Τωρα εσυ στο προγραμμα σου, σε καθε επαναληψη εχεις γραψει και κατι διαφορετικο που δεν βγαζει νοημα.

for (int i = 0; i < NO_STUDENT; ++i){
	cin >> a;
   cout << stnts[i].set_ma8ima_1(a);
}

Αυτο είναι λάθος γιατι προσπαθεις να τυπωσεις το αποτελεσμα μια void συναρτησης (δηλαδη το τιποτα), οποτε δεν κανει καν compile.

for (int i = 0; i < NO_STUDENT; ++i) {
	cin >> a;
	a = stnts[i].get_ma8ima_1();
}

Εδω αναθετεις στο a το αποτελεσμα της get_ma8ima_1(), δηλαδη αναθετεις στο a την τιμη της private μεταβλητης, κατι το οποιο δεν εχεις ορισει. Αρα τελικα δεν αλλαζεις ποτε την τιμη της μεταβλητης ma8ima_1.

Αυτό που θέλεις είναι:

int grade;
cin >> grade;
stnts[i].set_Ma8ima_1(grade);

για να θεσεις τιμη στην μεταβλητη του μαθηματος, και

int c;
c = stnts[i].get_Ma8ima_1();
cout << c << '\n';

για να την παρεις και να την τυπωσεις.

0

Τέλεια! Τώρα το έπιασα, τα διόρθωσα και λειτουργεί μια χαρά! Ευχαριστώ και πάλι για όλα!

301 questions

289 answers

288 comments

770 users