[C++] dynamiczne alokowanie pamięci+ wskaźniki

Awatar użytkownika
alchem
Użytkownik
Użytkownik
Posty: 252
Rejestracja: 10 cze 2014, o 19:10
Płeć: Mężczyzna
Lokalizacja: Wrocław
Podziękował: 83 razy
Pomógł: 5 razy

[C++] dynamiczne alokowanie pamięci+ wskaźniki

Post autor: alchem »

Robię sobie program, który wylosuje pseudo losowe liczby z jakiegoś przedziału:
Mam taki kod(tak wiem że liczby mogą się powtórzyć, wiem jak to zrobić aby się nie powtrzały ale nie w tym problem):

Kod: Zaznacz cały

#include <iostream>
#include <cstdlib>
#include <time.h>

using namespace std;

void losowe_liczby (int  *wskaz, int ile,int przedzial, int a)
{
  srand(time(NULL));

     for(int i =0; i<ile; i++)
    {
      *wskaz = rand() % przedzial + a;
       wskaz ++;
    }


    for(int i = 0; i < ile; i++)
    {
      cout<< *wskaz <<" "<<endl;
      wskaz++;

    }

}




int main()
{
    cout <<"Program wylosuje okreslona ilosc licz bez powtorzen"<<endl<<endl;
    cout << "Podaj 'a' i 'b' aby okreslic przedzial [a...b]: " ;
    int a,b;
    cin >>a >> b;
    cout<< endl << "Liczby maja byc bez powtorzen a wiec nie moze ich byc wiecej niz: "<< b-a<<endl<<endl;
    int przedzial= b-a;
    cout <<"Podaj ile liczb z tego przedzialu chcesz wylosowac: " ;
    int ile;
    cin>>ile;

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

   losowe_liczby (wskaznik,  ile, przedzial, a);

   delete [] tablica;

    return 0;
}

Jednak program nie działa, w tablicach są jakieś liczby ale nie są one modulo a dla większych indeksów są tam zera, może mi ktoś powiedzieć w czym tkwi problem?
pasman
Użytkownik
Użytkownik
Posty: 171
Rejestracja: 26 lut 2016, o 17:32
Płeć: Mężczyzna
Lokalizacja: Łódź
Podziękował: 1 raz
Pomógł: 14 razy

[C++] dynamiczne alokowanie pamięci+ wskaźniki

Post autor: pasman »

alchem pisze: wskaz ++;

co się stanie gdy zmienisz to na:

Kod: Zaznacz cały

wskaz += sizeof(int);
Afish
Moderator
Moderator
Posty: 2828
Rejestracja: 15 cze 2008, o 15:45
Płeć: Mężczyzna
Lokalizacja: Seattle, WA
Podziękował: 3 razy
Pomógł: 356 razy

[C++] dynamiczne alokowanie pamięci+ wskaźniki

Post autor: Afish »

alchem, modyfikujesz wskaźnik przy zapisywaniu liczb i dalej przy odczytywaniu, co powoduje błąd.
pasman, to nie pomoże, za to może wprowadzić niezdefiniowane zachowanie.
Awatar użytkownika
alchem
Użytkownik
Użytkownik
Posty: 252
Rejestracja: 10 cze 2014, o 19:10
Płeć: Mężczyzna
Lokalizacja: Wrocław
Podziękował: 83 razy
Pomógł: 5 razy

[C++] dynamiczne alokowanie pamięci+ wskaźniki

Post autor: alchem »

No tak sizeof(int) = 4, ale z tego co wiem, to wtedy przeskoczę o 4 "szufladki" a nie do kolejnej "szulfadki". Z tego co zrozumiałem i widziałem w tutorialach to dodając 1 do wskaźnika przeskakuje on do kolejnej zmiennej poprzez dodatnie 4(bo int), przez co komputer od razu wie że kolejny nr szufladki jest po prostu większy o 4.

Zresztą tak czy siak zamiana

Kod: Zaznacz cały

wskaz ++;
na

Kod: Zaznacz cały

wskaz += sizeof(int);
nic nie pomogła, jedynie przy niektórych liczbach program wysypuje.

-- 31 mar 2016, o 20:13 --
Afish pisze:alchem, modyfikujesz wskaźnik przy zapisywaniu liczb i dalej przy odczytywaniu, co powoduje błąd.
Możesz bardziej rozwinąć ten wniosek, bo nie do końca to rozumiem.

Dlaczego go modyfikuje? Chce przypisać wartość do *wskaznik( co jest adresem tablica[0] czyli pracuje na tej zmiennej poprzez wskaźnik, mam racje?) wartość, która zostaje pseudo losowo wygenerowana.
Afish
Moderator
Moderator
Posty: 2828
Rejestracja: 15 cze 2008, o 15:45
Płeć: Mężczyzna
Lokalizacja: Seattle, WA
Podziękował: 3 razy
Pomógł: 356 razy

[C++] dynamiczne alokowanie pamięci+ wskaźniki

Post autor: Afish »

Kod: Zaznacz cały

void losowe_liczby (int  *wskaz, int ile,int przedzial, int a)
{
  srand(time(NULL));

     for(int i =0; i<ile; i++)
    {
      *wskaz = rand() % przedzial + a;
       wskaz ++; <------ tutaj modyfikujesz pierwszy raz
    }


    for(int i = 0; i < ile; i++)
    {
      cout<< *wskaz <<" "<<endl;
      wskaz++; <------ a tutaj drugi raz, no ale tutaj ten wskaźnik już przy pierwszym obrocie jest poza tablicą, więc są śmieci

    }

}
Awatar użytkownika
alchem
Użytkownik
Użytkownik
Posty: 252
Rejestracja: 10 cze 2014, o 19:10
Płeć: Mężczyzna
Lokalizacja: Wrocław
Podziękował: 83 razy
Pomógł: 5 razy

[C++] dynamiczne alokowanie pamięci+ wskaźniki

Post autor: alchem »

Tyle że je zmodyfikowałem tutaj to wiem
Ale dlaczego je tu modyfikuje?

Kod: Zaznacz cały

wskaz++;
nie oznacza tego że po przypisaniu już jakiejś wartości, przechodzę na tablica[1] poprzez wskaźnik operacją

Kod: Zaznacz cały

wskaz++;
?
Afish
Moderator
Moderator
Posty: 2828
Rejestracja: 15 cze 2008, o 15:45
Płeć: Mężczyzna
Lokalizacja: Seattle, WA
Podziękował: 3 razy
Pomógł: 356 razy

[C++] dynamiczne alokowanie pamięci+ wskaźniki

Post autor: Afish »

No tak, modyfikujesz wskaźnik i wskazujesz na kolejny element tablicy. To teraz zastanów się, gdzie będzie wskazywał wskaźnik w pierwszej pętli, a gdzie w drugiej.
Awatar użytkownika
alchem
Użytkownik
Użytkownik
Posty: 252
Rejestracja: 10 cze 2014, o 19:10
Płeć: Mężczyzna
Lokalizacja: Wrocław
Podziękował: 83 razy
Pomógł: 5 razy

[C++] dynamiczne alokowanie pamięci+ wskaźniki

Post autor: alchem »

Kod: Zaznacz cały


void losowe_liczby (int  *wskaz, int ile,int przedzial, int a)
{
  srand(time(NULL));

     for(int i =0; i<ile; i++)
    {
      *wskaz = rand() % przedzial + a;
      cout<< *wskaz <<" "<<endl;
       wskaz ++;
    }

}

I śmiga, chodzi o to że w 2 pętli juz dla i=0 wskaźnik wychodził poza tablice i działo się coś... coś dziwnego, bo skoro wskazywałem na indeksy w tablicy, które już nie istnieją to program sam je sobie "dorabiał" i wpisywał tam przypadkowe liczby?

Nie rozumiem jeszcze tego stwierdzenia:
a tutaj drugi raz, no ale tutaj ten wskaźnik już przy pierwszym obrocie jest poza tablicą, więc są śmieci
Dlaczego już przy pierwszym obrocie jest poza tablicą? Miałeś na myśli że po zakończeniu pętli wszystkie miejsca w tablicy są zajęte?
Afish
Moderator
Moderator
Posty: 2828
Rejestracja: 15 cze 2008, o 15:45
Płeć: Mężczyzna
Lokalizacja: Seattle, WA
Podziękował: 3 razy
Pomógł: 356 razy

[C++] dynamiczne alokowanie pamięci+ wskaźniki

Post autor: Afish »

alchem pisze: I śmiga, chodzi o to że w 2 pętli juz dla i=0 wskaźnik wychodził poza tablice i działo się coś... coś dziwnego, bo skoro wskazywałem na indeksy w tablicy, które już nie istnieją to program sam je sobie "dorabiał" i wpisywał tam przypadkowe liczby?
Technicznie wyjaśnienie jest nieprecyzyjne i niepoprawne, ale intuicyjnie można to tak wytłumaczyć.
alchem pisze:Dlaczego już przy pierwszym obrocie jest poza tablicą? Miałeś na myśli że po zakończeniu pętli wszystkie miejsca w tablicy są zajęte?
Nie, miałem na myśli fakt, że pierwsza pętla przesuwa wskaźnik za koniec tablicy.
Awatar użytkownika
alchem
Użytkownik
Użytkownik
Posty: 252
Rejestracja: 10 cze 2014, o 19:10
Płeć: Mężczyzna
Lokalizacja: Wrocław
Podziękował: 83 razy
Pomógł: 5 razy

[C++] dynamiczne alokowanie pamięci+ wskaźniki

Post autor: alchem »

Eh.. jeszcze jestem za głupi żeby to jakoś pojąć do końca.
A co do kodu jest ona stylowo poprawnie napisany, czy lepiej by było to zrobić bardziej "profesjonalnie"?
Afish
Moderator
Moderator
Posty: 2828
Rejestracja: 15 cze 2008, o 15:45
Płeć: Mężczyzna
Lokalizacja: Seattle, WA
Podziękował: 3 razy
Pomógł: 356 razy

[C++] dynamiczne alokowanie pamięci+ wskaźniki

Post autor: Afish »

1. Załączanie time.h w C++ to słaby pomysł, lepiej użyć ctime
2. using namespace std; przez wielu zostałoby uznane za zbrodnię.
3. Nie weryfikujesz rozmiaru tablicy przed utworzeniem, co będzie, gdy podasz tam liczbę ujemną?
4. Zwracanie zera z maina to też słaby pomysł, inny system operacyjny może wymagać innej wartości.
5. NULL też wygląda staro, od paru lat jest nullptr albo po prostu zero.
6. Formatowanie jest fatalne. Nierówne wcięcia, masa zbędnych pustych linii, spacje w dziwnych miejscach, klamerki niezgodne z konwencją C++.
Awatar użytkownika
alchem
Użytkownik
Użytkownik
Posty: 252
Rejestracja: 10 cze 2014, o 19:10
Płeć: Mężczyzna
Lokalizacja: Wrocław
Podziękował: 83 razy
Pomógł: 5 razy

[C++] dynamiczne alokowanie pamięci+ wskaźniki

Post autor: alchem »

Klamerki niezgodne z konwencją C++
Możesz powiedzieć co masz na myśli?
Afish
Moderator
Moderator
Posty: 2828
Rejestracja: 15 cze 2008, o 15:45
Płeć: Mężczyzna
Lokalizacja: Seattle, WA
Podziękował: 3 razy
Pomógł: 356 razy

[C++] dynamiczne alokowanie pamięci+ wskaźniki

Post autor: Afish »

W C++ zwykło umieszczać się klamrę otwierającą blok w tej samej linii, co instrukcja (if/while/funkcja itp).
Awatar użytkownika
alchem
Użytkownik
Użytkownik
Posty: 252
Rejestracja: 10 cze 2014, o 19:10
Płeć: Mężczyzna
Lokalizacja: Wrocław
Podziękował: 83 razy
Pomógł: 5 razy

[C++] dynamiczne alokowanie pamięci+ wskaźniki

Post autor: alchem »

Jak patrzę to jednak często ludzie używają klamer tak:

Kod: Zaznacz cały

for(;;)
{


}
Czy to na tutorial'ach, na różnych stronach, czy nawet u mnie na wykładzie, no ale nic.
Biblioteki i innych również używam z tutoriali czy stron.
Jutro dokończę ten program i postaram się go "uporządkować".
Polecasz jakieś źródła czy też książki, z których mógłbym bez obaw czerpać wiedzę będą pewnym że nie łapie złych nawyków?
Afish
Moderator
Moderator
Posty: 2828
Rejestracja: 15 cze 2008, o 15:45
Płeć: Mężczyzna
Lokalizacja: Seattle, WA
Podziękował: 3 razy
Pomógł: 356 razy

[C++] dynamiczne alokowanie pamięci+ wskaźniki

Post autor: Afish »

Osobiście uczyłem się z Praty, zarówno C jak i C++. Poza tym książki Meyersa są polecane, ale nie czytałem ich, więc nie mogę się wypowiedzieć. Na pewno uważaj na kursy w sieci, bo niestety większość z nich nie uczy poprawnie i tylko utrwala masę mitów, a niestety C i C++ to języki, w których wyjątkowo łatwo zrobić sobie krzywdę.
ODPOWIEDZ