Panel użytkownika
Nazwa użytkownika:
Hasło:
Nie masz jeszcze konta?

[C++] Liczby pierwsze i dziwne zjawisko z tablicami.

Ostatnio zmodyfikowano 2014-04-01 23:30
Autor Wiadomość
BrutalxD
Temat założony przez niniejszego użytkownika
[C++] Liczby pierwsze i dziwne zjawisko z tablicami.
» 2014-03-31 22:28:21
Napisałem program, który znajduje liczby pierwsze metodą Sita Erastotenesa, następnie, za pomocą tablicy która została utworzona, liczby pierwsze bliźniacze (p-liczba pierwsze. liczba bliźniacza to taka, że obie p i p+2 są pierwsze). Liczby bliźniacze wypisuje mi dobrze, ale tablice z wszystkimi liczbami pierwszymi w jakiś sposób zmienia. Proszę o pomoc. Oto kod :
C/C++
#include<iostream>
#include<cmath>


using namespace std;
void wypisz( unsigned tablica[], unsigned zakres )
{
    for( unsigned i = 0; i < zakres; i++ )
         cout << i + 1 << ". " << tablica[ i ] << " " << endl;
   
}

void blizniaczex( unsigned pierwsze[], unsigned zakresP, unsigned blizniacze[], unsigned & zakresB )
{
    for( unsigned i = 0; i < zakresP; i++ )
    {
        if( pierwsze[ i ] + 2 == pierwsze[ i + 1 ] && i + 1 != zakresP )
        {
            blizniacze[ zakresB ] = pierwsze[ i ];
            zakresB++;
        }
    }
}
void wypisz_blizniacze( unsigned blizniacze[], unsigned zakresB )
{
    cout << endl << "BLIZNIACZE: " << endl;
    for( unsigned i = 0; i < zakresB; i++ )
    {
        cout << i + 1 << ". " << endl;
        cout << blizniacze[ i ] << " i " << blizniacze[ i ] + 2 << endl;
    }
    if( zakresB == 0 )
         cout << "Nie ma Blizniaczych" << endl;
   
}
int main()
{
    unsigned n;
    cout << "n = ";
    cin >> n;
    bool pierwsze[ n + 1 ];
    for( unsigned i = 2; i <= sqrt( n ); i++ )
    {
        if( pierwsze[ i ] != true )
        for( unsigned j = 2 * i; j <= n; j += i )
             pierwsze[ j ] = true; // wykluczam wielokrotnosci
       
    }
    unsigned zakresP = 0, zakresB = 0;
    unsigned Tpierwsze[ zakresP ], blizniacze[ zakresB ]; //Tpierwsze zawiera wszystkie pierwsze z zakresu 2-n
    for( unsigned i = 2; i <= n; i++ )
    if( pierwsze[ i ] != true )
    {
        Tpierwsze[ zakresP ] = i;
        zakresP++;
    }
    wypisz( Tpierwsze, zakresP ); // tu normalnie
    cout << endl;
    blizniaczex( Tpierwsze, zakresP, blizniacze, zakresB );
    wypisz_blizniacze( blizniacze, zakresB );
    wypisz( Tpierwsze, zakresP ); // tu zmiana
    return 0;
}
P-107536
Monika90
» 2014-03-31 23:03:48
C/C++
cin >> n;
bool pierwsze[ n + 1 ];
Rozmiar tablicy nie może być określony przez zmienną (może za kilka lat będzie mógł być, ale na razie nie może)

C/C++
if( pierwsze[ i ] != true )
Odczyt wartości z tablicy, która jest niezainicjalizowana.

C/C++
unsigned zakresP = 0, zakresB = 0;
unsigned Tpierwsze[ zakresP ], blizniacze[ zakresB ];
Znów: zakresP i zakresB to zmienne, na dodatek równe zero, każdy dostęp do tablic będzie poza zakresem.
P-107543
BrutalxD
Temat założony przez niniejszego użytkownika
» 2014-04-01 00:14:54
Robiłem trochę programów z zapisem "cin >> n; unsigned tab[n];" i w żadnym poprzednim nie występował owy błąd, mogłem bez problemu manewrować takimi tablicami. Program dużo by stracił na uniwersalności, jeśli nie stosowałoby się takiego zapisu.

"Niezainicjalizowana" szukałem w słownikach i nie znalazłem takiego słowa => nie wiem o co chodzi.

Nie przekracza w żadnym przypadku, bo zarówno zakresP jak i zakresB są zwiększane. Dowodem na to jest chociażby to, że działa wypisywanie liczb pierwszych, ponadto jeżeli tworzę funkcję na liczby pierwsze Germain (2p+1 jest pierwsza, gdzie p=L.pierwsza) to wszystko zostaje w takim samym porządku jak było, mimo że działam na tablicy Tpierwsze, tylko w bliźniaczych coś się psuje.
Kod na Germain:
C/C++
bool CzyByla( unsigned tab[], unsigned liczba, unsigned zakres )
{
    if( zakres == 0 )
         return false;
   
    for( unsigned i = 0; i < zakres; i++ )
    if( liczba == tab[ i ] )
         return true;
   
    return false;
}

void Germainx( unsigned Tpierwsze[], unsigned zakresP, unsigned Germain[], unsigned & zakresG, unsigned n )
{
    unsigned liczba;
    for( unsigned i = 0; i < zakresP; i++ )
    {
        liczba =( Tpierwsze[ i ] * 2 + 1 );
        if( liczba <= n )
        if( CzyByla( Tpierwsze, liczba, zakresP ) == true )
        {
           
            Germain[ zakresG ] = liczba;
            zakresG++;
        }
    }
   
}
P-107546
Monika90
» 2014-04-01 00:27:48
Robiłem trochę programów z zapisem "cin >> n; unsigned tab[n];" i w żadnym poprzednim nie występował owy błąd, mogłem bez problemu manewrować takimi tablicami. Program dużo by stracił na uniwersalności, jeśli nie stosowałoby się takiego zapisu.
Jak chcesz to używaj sobie takiego zapisu, ale wiedz, że nie jest to standardowe C++.

"Niezainicjalizowana" szukałem w słownikach i nie znalazłem takiego słowa => nie wiem o co chodzi.
Może faktycznie nie ma takiego słowa, ale w j. angielskim jest uninitialized. Zastanów się, co poniższy program wyświetli na ekranie:
C/C++
#include <iostream>
int main()
{
    double x;
    std::cout << x;
}

Nie przekracza w żadnym przypadku, bo zarówno zakresP jak i zakresB są zwiększane.
Więc wg Ciebie, taki program:
C/C++
#include <iostream>
int main()
{
    unsigned x = 0;
    std::cout << x;
    ++x;
}
nie wydrukuje zera, bo x jest zwiększane.
P-107547
Adik80
» 2014-04-01 12:00:08
"cin >> n; unsigned tab[n];" nie jest zgodne ze standardem c++, ale jest dostepne w C++ jako rozszerzenie w gcc, ale tablica raz utworzona nie zmienia rozmairu, czyli tak jak pisala Monika, inicujac tablice rozmairem 0, kazde uzycie jej z indexem wiekszym od zera oznacza ze piszesz po pamieci.
P-107558
BrutalxD
Temat założony przez niniejszego użytkownika
» 2014-04-01 17:11:00
1. Nie wiem co wyświetli, bo nic nie przypisałem tej zmiennej ani nie wskazałem na adres. Pewnie jakiegoś randoma.
2.Wg mnie ten program wyświetli zero, a jeśli by się ją wypisało po inkrementacji to by program zwrócił 1., dla mnie takie deklarowanie tablic pozwala na idealne wpasowanie się w zapotrzebowanie programu. Nie ma tutaj miejsca w tablicy które nie przechowałoby niepotrzebnych wartości.
A jeśli chodzi o surfowanie po pamięci, to nie robię tego losowo. Przeanalizujcie to i spróbujcie zgadnąć co otrzymamy na ekranie.
C/C++
#include<iostream>
#include<cmath>

using namespace std;

int main()
{
    unsigned licznik = 0, tab[ licznik ], liczba;
    for( unsigned i = 0; i < 5; i++ )
    {
        cin >> liczba;
        tab[ licznik ] = liczba;
        licznik++;
    }
    for( unsigned j = 0; j < 5; j++ )
    {
        cout << endl << tab[ j ] << endl;
    }
    return 0;
}
 
P-107565
Adik80
» 2014-04-01 18:35:33
To jest niezdefiniowane zachowanie i zalezy jak gcc to implementuje, ale napewno nie robisz tego co myslisz ze robisz. Raz utworzona tablica nie zwiekszy swojej pojemnosci (jest to zreszta fizycznie niemozliwe jesli popatrzysz jak za tworzone zmienne na stosie)
P-107577
BrutalxD
Temat założony przez niniejszego użytkownika
» 2014-04-01 21:24:12
Jakto, przecież rozmiar tablicy został zwiększony, gdybym nie zwiększał licznika to nie miałbym dostępu do poszczególnych elementów . Na początku tablica może przechowywać 1 element na koniec 5, nie gubiąc tych wcześniej wprowadzonych. To oznacza, że nie tworzę za każdym razem nowej tablicy tylko program pozwala wprowadzać wartości póki nie przekroczę granicy, a że nigdy to nie następuje to nie ma żadnym zgrzytów.
P-107591
« 1 » 2
  Strona 1 z 2 Następna strona