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

Tablica-dlaczego mogę wpisać więcej szufladek niż jest zadeklarowane?

Object Storage Arubacloud
0 głosów
644 wizyt
pytanie zadane 6 lutego 2017 w C i C++ przez PawelS Nowicjusz (240 p.)

#include <iostream>
using namespace std;

int n;
int tab [10];
int main()
{
    cout<<"Ile tablica ma zawierac elementow: ";
    cin>>n;

    for (int i=0; i<n; i++)
    {
        cout<<"podaj wartosc elementu "<<i;
        cin>>tab[i];
    }

    return 0;
}

Na początku chciałem zaznaczyć, że jestem kompletnie początkujący. Jestem na etapie piątego odcinka o tablicach (Kurs C++ odc. 5: Tablice, ciąg Fibonacciego) Pana Mirosława. Nie rozumiem jednej rzeczy: skoro deklaruje, że tablica "tab[10]" ma zawierać 10 szufladek to jakim cudem mogę w pętli for stworzyć warunek, w którym wartość elementów tablicy przekracza 10 szufladek. Przykład: Wpisuje, że tablica ma zawierać 15 elementów i mogę wtedy wypisać w konsoli 15 wartości elementów tablicy, mimo, że w 5 linijce zadeklarowałem, że int tab[10]. Zastanawia mnie dlaczego tak się dzieję. Może popełniłem jakąś gafę, może czegoś nie zauważyłem, może nie zrozumiałem do końca informacji zawartych w filmiku na temat tablic. Proszę nie wieszać na mnie psów :) Jestem początkujący i mimo, że szukałem informacji na ten temat nic nie znalazłem.

4 odpowiedzi

+1 głos
odpowiedź 6 lutego 2017 przez koczurekk Gaduła (3,420 p.)

Przypadek, raz zadziała, raz wysypie ci program po zmianie linii na drugim końcu programu. Bo tak wgl to zadeklarowałeś tą tablicę jako statyczną, więc na 100% uszkodziłeś jakieś dane swojego programu, tylko na razie nie wiadomo jakie.

Np. u mnie strasznie rzeczy dzieją się w takiej sytuacji:

#include <iostream>

int tab1[4] {0};
int tab2[4] {0};

int main() {
	for(auto i = 0u; i < 10; ++i) {
		tab2[i] = 8;
	}

	std::cout << tab1[1] << std::endl; //Ups?
}
+1 głos
odpowiedź 6 lutego 2017 przez morele123 Gaduła (4,790 p.)
Ponieważ w C++ dane, które są przechowywane można sobie wyobrazić jako taką dużą tablicę. Jeżeli zrobisz takie coś: int a[2] , b , c; To wówczas Gdy odwołasz się do a[3] to odwołasz się do zmiennej b, do a[4] to c. Jeżeli jednak zrobisz takie coś: int a[2], int b, int c. To w takim przypadku gdy odwołasz się do a[3] to są dwie opcje albo będzie to jedna z twoich zadeklarowanych zmiennych, albo będzie to jakaś inna losowa zmienna, która nawet nie jest w twoim programie. A co do używania tego faktu, to przeważnie programy i tak dostają pewien obszar w pamięci, którym mogą dysponować i gdy odwołamy się do nieistniejącej zmiennej w ten sposób to nic złego się nie stanie.
komentarz 6 lutego 2017 przez koczurekk Gaduła (3,420 p.)
"A co do używania tego faktu, to przeważnie programy i tak dostają pewien obszar w pamięci, którym mogą dysponować i gdy odwołamy się do nieistniejącej zmiennej w ten sposób to nic złego się nie stanie."

Niestety zmienne statyczne są w środku tego obszaru i trudno czegoś nie popsuć.
komentarz 6 lutego 2017 przez morele123 Gaduła (4,790 p.)
Miałem na myśli ingerencję w inne programy naszego systemu operacyjnego. (O ile dobrze pamiętam bez otwierania programu w naszym programie nie da się ingerować w jego zmienne, ale mogę się mylić, bo specem od c++ to ja nie jestem)
komentarz 6 lutego 2017 przez koczurekk Gaduła (3,420 p.)
A no tak, zwłaszcza że procesy mają własną wirtualną przestrzeń adresową losowo rozlokowaną w pamięci.
+1 głos
odpowiedź 6 lutego 2017 przez draghan VIP (106,230 p.)

Ludzie piszą o modelu pamięci i o crashowaniu "programu na drugim końcu", a nikt nie wspomniał o rzeczywistej przyczynie problemu.

Możesz tak zrobić, ponieważ język C++ nie przewiduje mechanizmu do automatycznego sprawdzania zakresu tablic. Programista sam musi pilnować, żeby nie nadpisać jakichś "cudzych" danych przy posługiwaniu się "gołymi" tablicami.

I mowa tutaj o rdzeniu języka - bo biblioteka standardowa ma do zaoferowania kilka fajnych i bezpiecznych kontenerów, jak np. std::vector, który posiada metodę std::vector::at(), która działa jak operator indeksowania, a w razie przekroczenia zakresu rzuca wyjątkiem. Kontener std::vector jest również przystosowany do używania iteratorów, co pozwala tworzyć pętle zakresowe, gdzie nie podajesz explicite liczby elementów, tylko każesz wykonać pętlę "dla wszystkich elementów". Mały przykład:

#include <vector>
#include <iostream>

int main()
{
    int n;
    std::cout<<"Ile elementow? ";
    std::cin>>n;

    std::vector<int> tab(n); // tworzysz wektor o nazwie tab, który zawiera n elementów typu int

    for(int i = 0; i < n; ++i) // spróbuj zmienić zakres pętli na większy, żeby wyjść poza tablicę
    {
         std::cin>> tab.at(i);
    }

    for(auto& element : tab) // pętla zakresowa - "dla każdego elementu wektora tab"
    {
         std::cout<<element<<' ';
    }
    return 0;
}

Wektory można rozszerzać w trakcie działania programu, zaś tablic nie - ale to już taka informacja poza konkursem, bo nie o to pytałeś. ;)

komentarz 6 lutego 2017 przez niezalogowany
Wlasnie liczylem na taka odpowiedz, bo szczerze mowiac wiedzialem jak to rozwiazac, ale nie wiedzialem czemu tak sie dzieje. Teraz wiem i dziekuje. Mimo wszystko STL czy rzucanie wyjatkami to troche duzo jak dla osoby ktora uczy sie o tablicach statycznych ;d
komentarz 6 lutego 2017 przez draghan VIP (106,230 p.)

Mimo wszystko STL czy rzucanie wyjatkami to troche duzo jak dla osoby ktora uczy sie o tablicach statycznych ;d

Nie wiem, czy za dużo - wiedzy nigdy za wiele, a korzystanie chociażby z takiego std::vector nic Cię praktycznie nie kosztuje. ;) Oczywiście nie zachęcam do porzucenia nauki tablic na rzecz kontenerów z std - wręcz odwrotnie: żeby ze starcia wyjść zwycięsko, należy dobrze poznać przeciwnika. Tak więc życzę miłej nauki, a obsługi kontenerów naucz się w niedalekim czasie, polecam. ;)

0 głosów
odpowiedź 6 lutego 2017 przez niezalogowany
Zadeklaruj tablice i zmienna n lokalnie, a twoje przewidywania na temat dzialania programu beda dobre. Wtedy jesli bedziesz chcial odczytac cos z poza tablicy to pokaze ci jakis syf ktore jest aktualnie przechowywany pod ta komorka pamieci. Podandto jesli chciallbys ustalac rozmiar tablicy to poczytaj o dynamicznie alokowanej tabilcy badz o modyfikatorze const.
Pozdrawiam :)

Podobne pytania

+2 głosów
1 odpowiedź 337 wizyt
pytanie zadane 10 marca 2021 w JavaScript przez Kalindoreks Użytkownik (620 p.)
0 głosów
1 odpowiedź 569 wizyt
pytanie zadane 8 listopada 2017 w C i C++ przez dominiv2604 Początkujący (350 p.)
–1 głos
1 odpowiedź 675 wizyt
pytanie zadane 4 stycznia 2016 w C i C++ przez haloalo Nowicjusz (140 p.)

92,555 zapytań

141,403 odpowiedzi

319,557 komentarzy

61,940 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

Kolejna edycja największej imprezy hakerskiej w Polsce, czyli Mega Sekurak Hacking Party odbędzie się już 20 maja 2024r. Z tej okazji mamy dla Was kod: pasjamshp - jeżeli wpiszecie go w koszyku, to wówczas otrzymacie 40% zniżki na bilet w wersji standard!

Więcej informacji na temat imprezy 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!

...