Liczenie średniej ocen - w jaki sposób pętla ma zigonorować ocenę mniejszą od 1 i większą od 6?

0

Uczę się programowania w C++ i napotkałem ścianę. Piszę prosty program, który będzie zliczał średnią z zadanej ilości ocen. Do swojego kodu dodałem ifa, który sprawdza, czy podana ocena jest z zakresu od 1 do 6, w przypadku większej, bądź mniejszej liczby wyskoczy komunikat o takim błędzie, a następnie powróci do poprzedniej linii. Na końcu zlicza sumę i średnią z tych ocen. Jednakże zlicza sumę i średnią, nawet z liczby która nie pasuje do zadanego ifa (np wpisując jako jedną z ocen "100", bierze tą "setkę" pod uwagę). Jeśli ktoś może pomóc - to bardzo bym prosił, po uzyskaniu odpowiedzi można usunąć wątek, co by nie zaśmiecać forum.

Oto mój kod:

#include <iostream>

using namespace std;

int ile;
float oceny=1;
float suma=0, srednia;

int main()
{
    cout << "Z ilu ocen policzyc srednia?" << endl;
    cout << "Podaj liczbe: ";
    cin>>ile;

    int *tablica;
    tablica = new int [ile];

    for (int i=0; i<ile; i++)
    {
        cout << "Podaj " << i+1 << " ocene: ";
        cin >> oceny;
        if (oceny<=0||oceny>6)
            {
                cout <<"Podaj ocene z zakresu od 1 do 6!" << endl;
                i--;
            }
        suma = suma + oceny;
    }
    //cout << suma;
    srednia = suma/ile;
    cout << "Srednia z podanych ocen wynosi: " << srednia;

    delete [] tablica;

    return 0;
}
2

Trochę źle kombinujesz, ale jesteś całkiem blisko ;-)

const unsigned int MAKSYMALNA_LICZBA_OCEN = 6;
unsigned int liczbaWprowadzonychOcen = 0;

while (liczbaWprowadzonychOcen < MAKSYMALNA_LICZBA_OCEN) {
  int ocena;

  cout << "Podaj " << liczbaWprowadzonychOcen+1 << " ocene: ";
  cin >> ocena;

  if (ocena < 1 || ocena > 6) {
    cout << "Blad: Ocena musi zawierac sie w zakresie <1,6>." << endl;
    continue;
  }

  sumaOcen += ocena;
  liczbaWprowadzonychOcen += 1;
}
2

Łatka w postaci else:

if (oceny<=0||oceny>6)
{
    cout <<"Podaj ocene z zakresu od 1 do 6!" << endl;
    i--;
}
else
    suma = suma + oceny;

Dzięki temu suma zostanie zwiększona tylko wtedy, gdy podana liczba posiada wartość z zadanego przedziału. No i ten for nie pasuje do tego zadania, bo nie wiadomo ile razy użytkownik poda złą liczbę, więc nie wiadomo ile iteracji powinno być wykonanych. Użyj innej pętli, np. while.

0

Matko, jakie to było oczywiste.. Dzięki, aż mi głupio! I od razu mam następne pytanie - dlaczego nie pasuje tutaj pętla for? W przypadku dopisania "else" wszystko działa jak powinno, pętla wykonuje się tyle razy ile wynosi ilość ocen.

1

dlaczego nie pasuje tutaj pętla for?

Zwyczajowo w przypadku pętli for iterator (czyli w Twoim przypadku zmienna i) nie jest modyfikowany wewnątrz samej pętli (w przeciwieństwie do Twojego kodu) - i tego też się mniej-więcej spodziewa lustrując kod.

Dlatego właśnie kiedy jednak występuje potrzeba modyfikacji iteratora, lepiej jest zastosować inną konstrukcję (while / do while), aby dać do zrozumienia, że tu dzieje się coś więcej ;-)

Dochodzi też kwestia tego, że w Twoim kodzie przy każdej iteracji robisz i++, które czasem wykluczasz poprzez i--, czego powód nie jest do końca oczywisty / jasny na początku - w przypadku pętli while dekrementacja byłaby zbędna, a zatem i kod analizowałoby się szybciej.

0
Mefix napisał(a):

I od razu mam następne pytanie - dlaczego nie pasuje tutaj pętla for?

Typowe zastosowanie pętli for to wykonanie tego samego fragmentu kodu określoną ilość razy. Liczba iteracji z reguły znana jest z góry, dlatego patrząc na kod można się spodziewać, że tak właśnie działa. Modyfikując wartość iteratora wewnątrz pętli nie jest zbrodnią (w końcu taka możliwość jest wspierana), jednak to nieco utrudnia analizę kodu i jego zrozumienie.

W przypadku dopisania "else" wszystko działa jak powinno, pętla wykonuje się tyle razy ile wynosi ilość ocen.

Działa jak powinno, ale zawiera zbędne rzeczy. Jedną z nich jest macierz tablica, która w ogóle nie jest używana.

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