• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

W indeksie tablicy sumują się wartości - odcinek 5 kursu Pana Mirka

VPS Starter Arubacloud
0 głosów
198 wizyt
pytanie zadane 3 listopada 2017 w C i C++ przez Fergus Obywatel (1,010 p.)

Witam,

Dla celów testowych pozwoliłem sobie nieco zmodyfikować program do wyliczania średniej z ocen, który Pan Mirek omawiał w odcinku 5. kursu C++. Wydrukowałem w konsoli indeksy tablicy spoza zadeklarowanego zakresu tablicy oceny. W indeksie 6. tablicy

oceny[5]

sumują się podane kolejno oceny. Nie potrafię dojść do tego dlaczego tak się dzieje. Proszę o pomoc.

#include <iostream>

using namespace std;

float oceny[5]; float suma=0, srednia;

int main()
{
    for(int i=0; i<5; i++)
    {
        cout << endl << "Podaj " << i+1 << " ocene: ";
        cin >> oceny[i];
        suma += oceny[i];

        cout << oceny[0] << endl;
        cout << oceny[1] << endl;
        cout << oceny[2] << endl;
        cout << oceny[3] << endl;
        cout << oceny[4] << endl;
        cout << oceny[5] << endl; //<--dlaczego w tym indeksie tablicy sumują się podane kolejno oceny?
        cout << oceny[6] << endl;
        cout << oceny[7] << endl;
        cout << oceny[8] << endl;
        cout << oceny[9] << endl;
    }

    srednia = suma / 5;
    cout << endl << "srednia = " << srednia;

    return 0;
}

Fergus

komentarz 3 listopada 2017 przez cz3ran Stary wyjadacz (13,380 p.)
Ostatnia iteracja:

Podaj 5 ocene: 6 1 3 4 5 6 0 0 0 0 0

Na moje jest tam 0 ;P

2 odpowiedzi

0 głosów
odpowiedź 3 listopada 2017 przez Bondrusiek Maniak (61,370 p.)

Witam,

zauważ że tablica jest 5 elementowa

float ocena[5]

W pętli odwołujesz się do indexów większych niż 4(bo tablice indeksujemy od 0)

        cout << oceny[5] << endl; //<--dlaczego w tym indeksie tablicy sumują się podane kolejno oceny?
        cout << oceny[6] << endl;
        cout << oceny[7] << endl;
        cout << oceny[8] << endl;
        cout << oceny[9] << endl;

 

komentarz 3 listopada 2017 przez Fergus Obywatel (1,010 p.)

Zgadza się, odwołuję się do indeksów spoza zadeklarowanej tablicy, jednak tyko w indeksie oceny[5] sumują się wartości, natomiast dla oceny[6] i wyżej na wyjściu mamy wartość 0. To mnie zastanawia. Dlaczego akurat w oceny[5] jest suma?

komentarz 3 listopada 2017 przez Bondrusiek Maniak (61,370 p.)

U mnie jest normalnie. Zauważ że zmienna ocena[5] jest pierwszym elementem, który wychodzi poza zakres. Natomiast zmienna suma jest pośrednio używa tą zmienną więc kompilator być może bierze wartość pamięci suma i przypisuje go do ocena[5] w tej pętli. Wydaje mi się że to zachowanie jest zależne od platformy.

Ja używam: MinGW 4.7

komentarz 3 listopada 2017 przez Fergus Obywatel (1,010 p.)
Dzięki za wyjaśnienia. To chyba faktycznie kwestia kompilatora. W każdym bądź razie zaskoczyło mnie to, nie ukrywam.
0 głosów
odpowiedź 3 listopada 2017 przez TenGumis Gaduła (3,440 p.)
Myślę że na tym etapie umiejętności programowania bedzie trochę ciężko to zrozumieć. Wynika to ze sposobu alokacji pamięci na zmienne w kodzie maszynowym po skopilowaniu programu.

Tłumacząc to jakoś prosto. Alokując tablicę C++ gwarantuje ci że będzie ona wpamięci komputera w jednym kawałku. Czyli znając adres w pamięci (inaczej miejsce w którym jest zapisana wartość ocena[0]) możemy z łatwością stwierdzić że ocena[2] leży o 2 miejsca dalej w pamięci. Skoro tablicę alokujemy w taki wposób to dlaczego by nie zadeklarować tak zmiennych? Tak też stwierdził ktoś piszący kompilator i to dlaczego ocena[5] i suma to ta sama zmienna jest już jasne. Ponieważ zadeklarowałeś zmienną bezpośrednio po tablicy. Zauważ też że prawdopodobmie w ocena[6] jest policzona średnia :D

 

UWAGA!

W tym tłumaczeniu użyłem wielu skrótów myślowych. Poza nie zawsze musi tak być. Tzn to zachowanie jest zależne od architektury komputera/ systemu operacyjnego/ wersji kompilatora. Jesli masz jeszcze jakieś pytania w tym temacie to pytaj. Może będę potrafił odpowiedzieć.
komentarz 3 listopada 2017 przez Fergus Obywatel (1,010 p.)

Dzięki za wyjaśnienia, jednak w oceny[6] i dalszych spoza zadeklarowanej tablicy mamy 0. Suma jest tylko w indeksie oceny[5]. Efekt sumowania wartości w indeksie oceny[5] znika gdy w kodzie zrobimy kosmetyczną poprawkę, czyli to o czym pisałeś. Deklaruję więc zmienną suma przed deklaracją tablicy i już nie ma tego efektu.

#include <iostream>

using namespace std;

float suma=0, srednia;
float oceny[5];

Mimo wszystko moim skromnym zdaniem kolejność deklaracji zmiennych nie powinna mieć znaczenia dla kompilatora, bo mamy w tym momencie zupełnie nieoczekiwany dla programisty efekt (w moim przypadku wynikający z braku wiedzy) - wrzucenie zsumowanej wartości do indeksu tablicy. Dobrze, że to nie program sterujący rakietami balistycznymi, bo narobiłbym niezłego bajzlu ;-)

komentarz 6 listopada 2017 przez TenGumis Gaduła (3,440 p.)

Mimo wszystko moim skromnym zdaniem kolejność deklaracji zmiennych nie powinna mieć znaczenia dla kompilatora, bo mamy w tym momencie zupełnie nieoczekiwany dla programisty efekt

Ale to nie jest żaden błąd po stronie języka/kompilatora. Zauważ że nie powineneś korzystać z oceny[5] bo jest to już poza zakresem który zadeklarowałeś. Ty powinieneś używać jedynie oceny[0] - oceny[4] . Komórka oceny[5] po prostu nie istnieje natomiast język c++ nie sprawdza tego. Kod może się nie skompilować jeśli nie istnieje taka zmienna albo tablica, ale nie sprawdza  czy indeks jaki podejemy mieści się w zadeklarowanym przedziale. Jest to spowodowane optymalizacją wydajności. W innych językach jak np. Java takie zachowanie nie miało by miejsca. 

komentarz 6 listopada 2017 przez TenGumis Gaduła (3,440 p.)
float suma=0, srednia;
float oceny[5];

Jest szansa że teraz niektóre kompilatory pozwolą skompilować:

cout<<oceny[-2]<<endl;
i również wypisze się nam suma :D

komentarz 6 listopada 2017 przez Fergus Obywatel (1,010 p.)
W porządku, dzięki za wyjaśnienia :)   po prostu byłem zaskoczony takim zachowaniem się programu.

Podobne pytania

0 głosów
1 odpowiedź 187 wizyt
pytanie zadane 5 marca 2017 w C i C++ przez Dziobakanto Nowicjusz (150 p.)
0 głosów
2 odpowiedzi 810 wizyt
pytanie zadane 21 września 2015 w C i C++ przez niezalogowany
0 głosów
2 odpowiedzi 241 wizyt

92,453 zapytań

141,262 odpowiedzi

319,088 komentarzy

61,854 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj.

Akademia Sekuraka

Akademia Sekuraka 2024 zapewnia dostęp do minimum 15 szkoleń online z bezpieczeństwa IT oraz dostęp także do materiałów z edycji Sekurak Academy z roku 2023!

Przy zakupie możecie skorzystać z kodu: pasja-akademia - użyjcie go w koszyku, a uzyskacie rabat -30% na bilety w wersji "Standard"! Więcej informacji na temat akademii 2024 znajdziecie tutaj. Dziękujemy ekipie Sekuraka za taką fajną zniżkę dla wszystkich Pasjonatów!

Akademia Sekuraka

Niedawno wystartował dodruk tej świetnej, rozchwytywanej książki (około 940 stron). Mamy dla Was kod: pasja (wpiszcie go w koszyku), dzięki któremu otrzymujemy 10% zniżki - dziękujemy zaprzyjaźnionej ekipie Sekuraka za taki bonus dla Pasjonatów! Książka to pierwszy tom z serii o ITsec, który łagodnie wprowadzi w świat bezpieczeństwa IT każdą osobę - warto, polecamy!

...