Dlaczego uzyskuje dwa razy więcej niż powinienem gdy sumuje dowolne cyfry tym sposobem

0

Dlaczego uzyskuje dwa razy więcej niż powinienem gdy sumuje dowolne cyfry tym sposobem:

#include <iostream>

using namespace std;

float liczba[4];
float suma;
float srednia;

int main()
{
    cout << "dawaj 5 liczb z , :" << endl;
    for(int i=0; i<=4; i++)
        cin>>liczba[i];
    for(int l=0; l<=4; l++)
       suma=suma+liczba[l];
       cout<<suma<<endl;
    srednia=suma/5;
    cout<<srednia;
    return 0;
}
4

Masz UB, zapisujesz 5 liczb do tablicy 4-elementowej. Po poprawieniu działa poprawnie:

#include <iostream>

using namespace std;

float liczba[5];
float suma;
float srednia;

int main()
{
    cout << "dawaj 5 liczb z , :" << endl;
    for (int i = 0; i <= 4; i++)
        cin >> liczba[i];
    for (int l = 0; l <= 4; l++)
        suma = suma + liczba[l];
    cout << suma << endl;
    srednia = suma / 5;
    cout << srednia;
    return 0;
}

https://wandbox.org/permlink/eWJVbHTPfObIOrWN

PS: lektura konieczna:

2

Definiujesz tablice czteroelementową, float liczba[4];, a Wczytujesz do niej pięć liczb, for(int i=0; i<=4; i++), czyli UB.

0

Swoją drogą wie ktoś dlaczego ten błąd z zarezerwowaniem za małej o 1 tablicy poskutkował podwojeniem każdej możliwej sumy liczb? to dość ciekawe, myślałem że w takich sytuacjach program po prostu nie zadziała.

2

Niestety, w C++ masz UB zamiast błędu/wyjątku związanego z dostępem poza zakresem tablicy. Strzelam, że w pamięci zmienna globalna suma jest pod adresem, pod jakim byłby 5 element tablicy liczba, czyli bezpośrednio za nią. Wobec tego liczba[4] odnosi się do suma. Na przykład:

0x100 liczba[0]
0x104 liczba[1]
0x108 liczba[2]
0x10C liczba[3]
0x110 suma

Wobec tego, przy wejściu 1 2 3 4 5 (tak jak w moim przykładzie), po wczytaniu pierwszych czterech

0x100 liczba[0]  1
0x104 liczba[1]  2
0x108 liczba[2]  3
0x10C liczba[3]  4
0x110 suma       0

Wczytanie piątej nadpisałoby suma:

0x100 liczba[0]  1
0x104 liczba[1]  2
0x108 liczba[2]  3
0x10C liczba[3]  4
0x110 suma       5

Teraz pierwsze cztery iteracje dodawania są dość oczywiste - do suma (o wartości 5) dodajesz kolejne elementy tablicy, czyli po pierwszych czterech iteracjach pamięć wygląda tak:

0x100 liczba[0]  1
0x104 liczba[1]  2
0x108 liczba[2]  3
0x10C liczba[3]  4
0x110 suma      15

Ostatnia iteracja to suma += liczba[4], czyli suma += suma, czyli suma *= 2

0x100 liczba[0]  1
0x104 liczba[1]  2
0x108 liczba[2]  3
0x10C liczba[3]  4
0x110 suma      30

Przy czym musisz zauważyć, że UB to UB i wcale nie ma gwarancji, że tak będzie się to zachowywać.

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