subscript requires array or pointer type

Odpowiedz Nowy wątek
2014-12-13 16:38
0

Siema

Problem jest taki: robię prosty program do losowania bez powtórzeń, który ma mieć w funkcji main 3 elementy: tablicę, wartość początkową przedziału i wartość końcową przedziału. Chcę żeby było jak najmniej argumentów do wysłania, żeby potem tą funkcje wsadzić do mojej prywatnej biblioteczki.
Argumenty (int tablica[0], int wartoscPoczatkowa, int wartoscKoncowa) wysyłam do funkcji i tam zmuszam rand() żeby mi losował tylko te liczby Z ZADANEGO PRZEDZIAŁU oraz KTÓRE SIĘ NIE POWTARZAJĄ.

Problem: nie mogę zainicjalizować ani oryginalnej tablicy (w domyśle zewnętrznej) wartościami, ani nawet mając tablicę wewnętrzną ("tablicaWewnetrzna[e]") inicjalizując nią tablicę zewnętrzną ("tablicaZewn").

W visualu tylko "e" w " tablicaZewn[e]" jest podkreślone na czerwono, natomiast "e" w "tablicaWewnetrzna[e]" NIE JEST PODKREŚLONE.
Błąd: error C2109: subscript requires array or pointer type

Gdyby opis był niejasny, napiszę dokładniej co jest nie tak.

Robię jakiś tutorial z ccp0x, nie chcę być odsyłany do jakiegoś tutoriala, tylko chcę zostać nakierowany na rozwiązanie (inaczej mówiąc, chcę zmusić się do znalezienia rozwiązania).

    for (int e=0; e<*wsk_iloEle ; e++)
    {
        tablicaZewn[e] = tablicaWewnetrzna[e];
        cout << "Element\t\t" << e << "\ttablicy ma wartosc:\t" << tablicaZewn[e] << endl; 
    }
edytowany 1x, ostatnio: kvsanagi, 2014-12-13 16:40

Pozostało 580 znaków

2014-12-13 17:28
kq
0

Pokaż kod, ciężko inaczej powiedzieć.

Przy okazji:

  1. rand to zło http://channel9.msdn.com/Even[...]/2013/rand-Considered-Harmful
  2. jeśli przedział nie jest znacząco większy od ilości liczb, które losujesz, to lepiej po prostu pomieszać wartości kontenera zawierającego wszystkie wartości z przedziału.

Pozostało 580 znaków

2014-12-13 18:01
0
void losujBezPowtorzen(int tablicaZewn, int poczatekPrzedzialu, int koniecPrzedzialu, int *wsk_iloEle, int *wsk_sumEle)
{
    srand(time(NULL));
    *wsk_iloEle = (koniecPrzedzialu - poczatekPrzedzialu) +1;
    int stash; //na wyniki losowania
    int tablicaWewnetrzna[1000];
    for (int b=0 ; b<*wsk_iloEle ; b++)
    {
wroc:
        //randomuj i zapisz do stash
        stash = ((rand() % *wsk_iloEle) + poczatekPrzedzialu);
        //pomin dla 0 elementu, bo on sie nigdy nie powtarza
        if(b!=0)        
            //przejdz tablicę i sprawdz czy stash gdzies sie nie powtorzyl, zawsze o 1 petla mniej niz wynosi "b"
            for(int d=0; d<b ; d++)
            {
                if(stash == tablicaWewnetrzna[d])goto wroc;     //wróć do "wroc:" bez zmiany parametru "b"
            }
        //jezeli doszedles tutaj, inicjalizuj tablice wartością ze stash
         tablicaWewnetrzna[b] = stash; 
 
    }
 
    for (int e=0; e<*wsk_iloEle ; e++)
    {
        tablicaZewn[e] = tablicaWewnetrzna[e];
        cout << "Element\t\t" << e << "\ttablicy ma wartosc:\t" << tablicaZewn[e] << endl; 
    }
 
    return;
}
 
int _tmain(int argc, _TCHAR* argv[])
{   
    int poczatekPrzedzialu, koniecPrzedzialu;
    cout <<"Wprowadz poczatek i koniec przedzialu,\npamietaj ze max. rozmiar tablicy to 1000,\na wiec nie elementow nie moze byc >1000" << endl;
    cout <<"Wprowadz poczatek przedzialu: ";
    cin >> poczatekPrzedzialu;
    cout <<"\nWprowadz koniec przedzialu: ";
    cin >> koniecPrzedzialu;
 
    int tablica[1000];
    //inicjalizacja tablicy, bo strzela fochy
    for (int c=0; c<1000 ; c++)
    {
        tablica[c] = c;
    }
    //zmienna i wskaznik do niej, tak zeby po wyjsciu z funkcji miec w niej zapisane zmiany
    int iloscElementow;
    int *wsk_iloEle = &iloscElementow;
    //jak wyzej tylko ze do sumy elementow
    int sumaElementow;
    int *wsk_sumEle = &sumaElementow;
    //funkcja wlasciwa
    losujBezPowtorzen(tablica[0], poczatekPrzedzialu, koniecPrzedzialu, wsk_iloEle, wsk_sumEle);
 
    _getch();
    return 0;
}

Wiem, goto to zło, rand zło, tablica nie dynamiczna, wszystko zło. Ja się tylko uczę i chcę żeby po wsadzeniu tablicy do funkcji, ona mi wypluła tablicę z zainicjalizowanymi wartościami z zakresu od x do y, bez powtórzeń. To jest tylko ten jeden jedyny błąd, pierwszy raz coś takiego mi wyskakuje. Kumpel mówił, że nie trzeba wskaźnika do tablicy, więc nie dawałem.

edytowany 1x, ostatnio: kvsanagi, 2014-12-13 18:03

Pozostało 580 znaków

2014-12-13 18:10
kq
0
int tablicaZewn,

to jest liczba, nie tablica.tablicaZewn[e] = tablicaWewnetrzna[e];

 A tutaj traktujesz to jako tablicę.

Dla przykładu, wyjaśnij znaczenie:
```cpp
42[4]

Podpowiedź: nie ma.

deklarację funkcji zmień na

void losujBezPowtorzen(int* tablicaZewn, int poczatekPrzedzialu, int koniecPrzedzialu, int *wsk_iloEle, int *wsk_sumEle)

i wywołaj losujBezPowtorzen(tablica, poczatekPrzedzialu, koniecPrzedzialu, wsk_iloEle, wsk_sumEle);


 Jeśli reszta jest ok, to będzie działać.

Dodatkowo:
1. jeśli już koniecznie musisz używać `rand` zamiast wygodniejszych i lepszych odpowiedników z C++, `srand` wykonuj raz na początku programu,
2. spójrz na punkt 2 mojego poprzedniego posta,
3. po co w ogóle jest ta tablica wewnetrzna? Nie lepiej od razu operować na zewnętrznej? (pomijając powyższe punkty)

Pozostało 580 znaków

2014-12-13 19:15
0

Wielkie dzięki, działa. Skończyłem program, na samym dole jest cały kod, bez komentarzy bo raczej tylko zaciemniają sprawę. Po odpaleniu programu bardzo ładnie tekst jest sformatowany (widać gdzie się jakie funkcje zaczynają).

  1. Zmieniłem przy wywołaniu funkcji "tablica[0]" na "tablica", a w definicji funkcji dodałem gwiazdkę (int* tablicaZewn). Ale dalej nie wiem czemu to był błąd, wcześniej też wysyłałem tablice do funkcji i nie było problemów.
  2. Usunąłem podział na 2 tablice, od teraz funkcja operuje bezpośrednio na oryginalnej tablicy (ten podział tak naprawdę miał być rozwiązaniem na to, że pojawiał się ten błąd, który mam w tytule tego tematu)
  3. srand() poszedł na początek main.
  4. "jeśli przedział nie jest znacząco większy od ilości liczb, które losujesz, to lepiej po prostu pomieszać wartości kontenera zawierającego wszystkie wartości z przedziału."
    Nie wiem co masz na myśli mówiąc "pomieszać wartości kontenera". Jakby co doszedłem max. do wskaźników w Symfonii, nie ruszałem jeszcze klas.

# Program ma za zadanie wypisać wszystkie liczby z zadanego przedziału, bez powtórzeń, oraz podać liczbę elementów w przedziale oraz ich sumę (nazwaną przeze mnie sumą kontrolną).

# Program jest podzielony na dwie części: pierwsza BEZ losowania dodaje wszystkie elementy, wiedząc, że każdy następny element jest tylko o +1 większy od poprzedniego (zwykłe sumowanie), potem podawanie liczby elementow i sumy kontrolnej.

# Druga część to właściwe losowanie oparte o rand(). Wymuszam, aby program losował tylko z zadanego przedziału i nigdy się nie powtarzał. Musiałem tu użyć goto, bo uznałem że tak naprawdę w tym przypadku to najłatwiejsze rozwiązanie.

# Można zauważyć, że w FUNKCJI KONTROLNEJ wartości elementów są uszeregowane rosnąco (dla 100-105: 100,101,102,103,104,105) czyli 6 elementów, od najmniejszego do największego.

# W FUNKCJI LOSUJĄCEJ, natomiast wartości są już randomowo uszeregowane, bo są wynikiem losowania. Żadna wartość się nie powtarza.

# Program jest zrobiony tak, żeby FUNKCJA LOSUJĄCA mogła zostać w przyszłości (po okrojeniu z liczby elementów i sumy kontrolnej) wklejona bezpośrednio do programu, w którym będę testować algorytmy sortujące. Czyli wyląduje w mojej prywatnej biblioteczce. ^^

// 3 wrzesnia 2014 2023.cpp : Defines the entry point for the console application.
//
 
#include "stdafx.h"
#include <iostream>         //std:cout + cin
#include <conio.h>          //_getch()
#include <string>           //string
#include <fstream>          //tworzenie nowego pliku
#include <cstdlib>          //pseudolosowe liczby calkowite
#include <ctime>            //time();
using namespace std;
 
void funkcjaKontrolna(int k_poczatek, int k_koniec)
{
    cout << "FUNKCJA KONTROLNA, bez losowania, jej wyniki musza byc takie same jak w funkcji wlasciwej" << endl;
    const int iloscElementow = (k_koniec - k_poczatek) +1;      
    int tablicaKontrolna[1000];
    for (int a=0 ; a<iloscElementow ; a++)          
    {
        tablicaKontrolna[a] = k_poczatek;
        k_poczatek++;
        cout << "\tElement\t\t" << a << "\ttablicy ma wartosc:\t" << tablicaKontrolna[a] << endl;
    }
    int suma = 0;
    for(int a=0; a<iloscElementow ; a++)
    {
        suma = suma + tablicaKontrolna[a];
    }
    cout << "\tIlosc elementow przedzialu to:\t\t\t\t" << iloscElementow << endl;
    cout << "\tSuma wartosci elementow tablicy to:\t\t\t" << suma << "\n\n";
    return;
}
 
void losujBezPowtorzen(int* tablicaZewn, int poczatekPrzedzialu, int koniecPrzedzialu, int *wsk_iloEle, int *wsk_sumEle)
{   
    cout << "FUNKCJA WLASCIWA, losuje w oparciu o rand()" << endl;
    *wsk_iloEle = (koniecPrzedzialu - poczatekPrzedzialu) +1;
    int stash;
    for (int b=0 ; b<*wsk_iloEle ; b++)
    {
wroc:
        stash = ((rand() % *wsk_iloEle) + poczatekPrzedzialu);
        if(b!=0)        
            for(int d=0; d<b ; d++)
            {
                if(stash == tablicaZewn[d])goto wroc;   
            }
         tablicaZewn[b] = stash; 
         cout << "\tElement\t\t" << b << "\ttablicy ma wartosc:\t" << tablicaZewn[b] << endl; 
    }
    int sumaa = 0;
    for (int c=0 ; c<*wsk_iloEle ; c++)
    {
        sumaa = sumaa + tablicaZewn[c];
    }
    *wsk_sumEle = sumaa;
    cout << "\tIlosc elementow przedzialu:\t\t\t\t" << *wsk_iloEle << endl;
    cout << "\tSuma wartosci elementow tablicy:\t\t\t" << *wsk_sumEle << endl;
 
    return;
}
 
int _tmain(int argc, _TCHAR* argv[])
{   
    cout << "******************************************\n\n\tkvsnagi prodakszyns prezents:\n\trandom function without repeating\n\n******************************************\n\n\n" ;
 
    srand(time(NULL));
    int poczatekPrzedzialu, koniecPrzedzialu;
    cout <<"FUNKCJA MAIN\n\tWprowadz poczatek i koniec przedzialu,\n\tpamietaj ze max. rozmiar tablicy to 1000,\n\ta wiec nie elementow nie moze byc >1000" << endl;
    cout <<"\n\tWprowadz poczatek przedzialu:\t";
    cin >> poczatekPrzedzialu;
    int kontrola=0;
    do
    {
        kontrola = 0;
        cout <<"\tWprowadz koniec przedzialu:\t";
        cin >> koniecPrzedzialu;
        if(poczatekPrzedzialu > koniecPrzedzialu || poczatekPrzedzialu == koniecPrzedzialu)
        {
            cout << "\tKoncowa wartosc przedzialu musi byc wieksza niz poczatkowa wartosc." << endl;
            kontrola = 1;
        }
    }
    while(kontrola==1);
    cout << endl;
 
    funkcjaKontrolna(poczatekPrzedzialu, koniecPrzedzialu);
 
    int tablica[1000];
    int iloscElementow;
    int *wsk_iloEle = &iloscElementow;
    int sumaElementow;
    int *wsk_sumEle = &sumaElementow;
    losujBezPowtorzen(tablica, poczatekPrzedzialu, koniecPrzedzialu, wsk_iloEle, wsk_sumEle);
 
    _getch();
    return 0;
}
 
edytowany 1x, ostatnio: kvsanagi, 2014-12-13 19:26

Pozostało 580 znaków

2014-12-13 19:23
kq
1
  1. Zmieniłem przy wywołaniu funkcji "tablica[0]" na "tablica", a w definicji funkcji dodałem gwiazdkę (int* tablicaZewn). Ale dalej nie wiem czemu to był błąd, wcześniej też wysyłałem tablice do funkcji i nie było problemów.

tablica[0] to pierwszy element tablicy - liczba (int), a nie tablica, więc nie przekazywałeś tablicy, tylko wartość jej pierwszego elementu. To na pewno w kursie jest (tablice/wskaźniki).

Nie wiem co masz na myśli mówiąc "pomieszać wartości kontenera". Jakby co doszedłem max. do wskaźników w Symfonii, nie ruszałem jeszcze klas.

Masz kontener, np. std::vector, albo nawet zwykłą tablicę zawierającą liczby z zadanego przedziału (powiedzmy 40-45). Pomieszaj jego zawartość. Koniec, masz kontener z losowymi wartościami z zakresu, bez powtórzeń.

int tab[6] = {40, 41, 42, 43, 44, 45};
pomieszaj(tab);
// tab zawiera np. {42, 45, 44, 40, 41, 43}
 

Pomieszać możesz std::shuffle


edytowany 1x, ostatnio: kq, 2014-12-13 19:24

Pozostało 580 znaków

Odpowiedz
Liczba odpowiedzi na stronę

1 użytkowników online, w tym zalogowanych: 0, gości: 1, botów: 0