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

Program przypisuje wartość do zmiennej, choć go nie prosiłem

VPS Starter Arubacloud
0 głosów
324 wizyt
pytanie zadane 2 listopada 2016 w C i C++ przez marcingrychtol Obywatel (1,490 p.)
edycja 2 listopada 2016 przez marcingrychtol

Cześć wszystkim :)

Zaczynam dopiero swoje boje z programowaniem, uczę się wg kursu C++ Pana Zelenta na kanale Youtube.

Jestem obecnie na etapie tablic. Chciałem trochę rozbudować program "dzienniczek ucznia", tak aby liczył średnią ważoną z podanych ocen. Pół godziny wczoraj spędziłem nad rzeczą która wykracza poza moje granice logiki. Do rzeczy.

Program z jakiegoś powodu przypisuje zmiennej wartość znikąd, choć zmienną zadeklarowałem jako zero. Co ciekawe, po przestawieniu kolejności deklaracji zmiennych, przypisuje już normalnie zero, jak trzeba. Nie wiem, czy ma to związek z tym, że jedna zmienna jest tablicą 3x100.

Wkleję screeny, żeby pokazać o co mi chodzi. Oczywiście kod jest pewnie do zrefaktoryzowania, ale polecę dalej z nauką, bo czasami mając większą wiedzę człowiek robi rzeczy kompletnie inaczej :)

Wklejam kolejno kod działający błędnie, a później poprawny. Z góry dzięki za pomoc i wyjaśnienie.

https://drive.google.com/open?id=0Bw3BHVEg9BgDWGlkRkdNZVV4eU0

https://drive.google.com/open?id=0Bw3BHVEg9BgDemdWWHUzbkdrTTg

EDIT: forum wkleja w bardzo małej rozdzielczości, więc daję linki do dysku google.

#include <iostream>

using namespace std;
int dzi[3][100], suma1=0, suma2=0;
float  srednia1, srednia2;
int main()
{

    for (int i=0; i<100; i++)
      {
        cout<<"Podaj "<<i+1<<" ocene: ";
        cin>>dzi[1][i];

        cout<<"Podaj wage: ";
        cin>>dzi[2][i];

        dzi[3][i]=dzi[1][i]*dzi[2][i];

        //cout<<dzi[1][i]<<endl;
        //cout<<dzi[2][i]<<endl;
        //cout<<dzi[3][i]<<endl;

        cout<<suma1<<endl;

        suma1+=dzi[2][i];
        //cout<<"Suma wag: "<<suma1<<endl;

        suma2+=dzi[3][i];
        //cout<<"Suma ocen: "<<suma2<<endl;



        srednia1=suma2*100/suma1;
        srednia2=suma2/suma1;
        cout<<"Twoja srednia to: "<<srednia2<<"."<<srednia1-(srednia2*100)<<endl<<endl;
      }


    return 0;
}

 

4 odpowiedzi

+2 głosów
odpowiedź 2 listopada 2016 przez draghan VIP (106,230 p.)
wybrane 11 lutego 2017 przez marcingrychtol
 
Najlepsza

Tablice indeksuje się od zera. O ile dzi[1] oraz dzi[2] są poprawne, to odwoływanie się do dzi[3] da efekt sięgnięcia poza tablicę. Stąd też nadpisanie zmiennych, które znajdują się w obszarze pamięci zaraz za Twoją tablicą.

komentarz 2 listopada 2016 przez marcingrychtol Obywatel (1,490 p.)
Tak, faktycznie było o tym... Ba, nawet rozumiem czemu wartość zależała od kolejności deklaracji :) Wielkie dzięki
+1 głos
odpowiedź 2 listopada 2016 przez Sinnley Stary wyjadacz (12,810 p.)
Nazwa zmiennej jest jedynie aliasem jego adresu. Podobnie jak nazwa witryny jest tylko aliasem dla jej adresu ip.

I tak jak serwer DNS tłumaczy przeglądarce nazwe onet.pl na 213.180.141.140 tak kompilator tłumaczy nazwe zmiennej na jej adres w pamięci. Odwołując się do elementu tablicy który nie istniał (poprzez niewłaściwą numeracje, tablica 3 elementowa ma elementy o numerach 0, 1 oraz 2) odwołałeś się do miejsca w pamięci w którym była zmienna suma1 - i do niej przypisałeś wartość.
–1 głos
odpowiedź 2 listopada 2016 przez Ehlert Ekspert (212,630 p.)

W pętli używając cin musimy czyścić bufor!

//windows
std::cin.clear();
std::cin.sync();

//linux
std::cin.clear();
std::cin.ignore( 1000, '\n' );
komentarz 2 listopada 2016 przez marcingrychtol Obywatel (1,490 p.)
Fajnie, spróbuję. Niestety, nie rozumiem.

Dlaczego tak się dzieje?

Jak bufor wpływa na zmienne?

Gdzie to wpisać? W pętli? Przed wprowadzeniem danych, czy po?
komentarz 2 listopada 2016 przez unknown Nałogowiec (39,560 p.)
sync nie służy do czyszczenia bufora!
–1 głos
odpowiedź 2 listopada 2016 przez manjaro Nałogowiec (37,390 p.)

Dlatego wszędzie tyle się trąbi aby nie używać zmiennych globalnych. Wyrzuć zmienne globalne i zadeklaruj je w mainie a wszystko będzie prawidłowo:

#include <iostream>

using namespace std;

int main() {

    int dzi[3][100], suma1=0, suma2=0;
    float  srednia1, srednia2;


    for (int i=0; i<100; i++)
      {
        cout<<"Podaj "<<i+1<<" ocene: ";
        cin>>dzi[1][i];

        cout<<"Podaj wage: ";
        cin>>dzi[2][i];

        dzi[3][i]=dzi[1][i]*dzi[2][i];

        //cout<<dzi[1][i]<<endl;
        //cout<<dzi[2][i]<<endl;
        //cout<<dzi[3][i]<<endl;

        cout<<suma1<<endl;

        suma1+=dzi[2][i];
        //cout<<"Suma wag: "<<suma1<<endl;

        suma2+=dzi[3][i];
        //cout<<"Suma ocen: "<<suma2<<endl;



        srednia1=suma2*100/suma1;
        srednia2=suma2/suma1;
        cout<<"Twoja srednia to: "<<srednia2<<"."<<srednia1-(srednia2*100)<<endl<<endl;
      }


    return 0;
}

 

komentarz 2 listopada 2016 przez marcingrychtol Obywatel (1,490 p.)
Tak zrobię.

Jednak dalej mnie to nie satysfakcjonuje, gdyż chciałbym zrozumieć mechanizm powstawania takich kwiatków. Co czytać, gdzie szukać? Jakieś słowa kluczowe? Jakieś naprowadzenie?

Podobne pytania

+1 głos
2 odpowiedzi 1,202 wizyt
0 głosów
2 odpowiedzi 397 wizyt
pytanie zadane 22 grudnia 2021 w C# przez Code_ Użytkownik (520 p.)
0 głosów
1 odpowiedź 726 wizyt
pytanie zadane 17 marca 2020 w C i C++ przez ResCrove Obywatel (1,700 p.)

92,451 zapytań

141,261 odpowiedzi

319,073 komentarzy

61,853 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!

...