Wypełnianie tablicy liczbami od 1 do 5

0

Chcę wypełnić tablicę 5 elementową kolejnymi liczbami począwszy od 1.

Czyli powinienem uzyskać tablicę:
indeks: 0 1 2 3 4
wartość: 1 2 3 4 5

Mój kod:

int t[5];  //tablica

for (int a=0; a<5 ; )
{
     t[a]=++a; 
}

A tablica po jego wykonaniu ma taką zawartość (są to kolejne elementy tablicy):

1118312
1
2
3
4

Dlaczego element o indeksie 0 nie jest wypełniony?

Przecież ta pętla powinna działać tak:

  1. Inicjalizacja zmiennej a i przypisanie jej wartości 0 (a=0).
  2. Sprawdza warunek ( 0<5), jest spełniony. (a=0)
  3. Wykonuje ciało pętli: t[0]=1; Na początku a=0, więc w indeksie wpisuje 0. Następnie
    zwiększa o 1 zmienną a (czyli 0+1=1) i przypisuje wartość zmiennej a, czyli a=1 i teraz ta
    nowa (zwiększona) wartość zostaje pobrana przez operator przypisana i co za tym idzie
    wpisana do zmiennej tablicy o indeksie 0, czyli t[0] = 1;
  4. Sprawdzenie warunku 1<5 - spełniony.
  5. Ciało pętli: t[1]=2 i dalej znowu będzie sprawdzał warunek, itd.

Nawet jak wpisałem taki kod (dodałem wyświetlanie zawartości zmiennej a przez operacji na tablicy i po owej operacji:

int t[5];

for (int a=0; a<5 ; )
{
    cout<<a<<"\t"; t[a]=++a; cout<<a<<endl;
}

To program wypisał (liczba z lewej to wartość przed wykonaniem operacji na tablicy t, zaś ten po prawej stronie to wartość po wykonaniu wspomnianej operacji:

0 1
1 2
2 3
3 4
4 5

A zawartość tablicy po wykonaniu tej pętli
wyświetlona kodem:

 cout<<endl<<endl;
cout<<t[0]<<endl;
cout<<t[1]<<endl;
cout<<t[2]<<endl;
cout<<t[3]<<endl;
cout<<t[4]<<endl;

jest taka:

48799848
1
2
3
4

1

Skąd wiesz, w którym momencie zostanie zwiększone a?

0

Dlaczego element o indeksie 0 nie jest wypełniony?

Ponieważ kompilator doszedł do wniosku, że efektywniej będzie najpierw skompilować prawą stronę (++a), a potem wykonać przypisanie.
To co robisz to jest undefined behaviour, więc równie dobrze mógłby sformatować komputer :P

Dlaczego nie zrobisz tego po ludzku:

for (size_t a=0; a<5; a++)
{
 t[a] = a+1; 
}
0

Zaktualizowałem post pierwszy.

0

Po pierwsze co ma oznaczać " Ponieważ kompilator doszedł do wniosku, że efektywniej będzie najpierw skompilować prawą stronę (++a), a potem wykonać przypisanie.", bo nie rozumiem.
Przecież nawet w książkach jest napisane, że najpierw zwiększa zmienną, następnie przypisuje tą zwiększoną wartość tej zmiennej i następnie dopiero tą wartość pobiera do np. przypisania czy jakiejś funkcji (w zależność od kodu). Wobec czego nie rozmiem o co tu chodzi?

A skąd wiem kiedy a jest zwiększane napisałem poniżej postu pierwszego. Przecież nawet książkach do c++ jest napisane jak działa inkrementacja i dekrementacja.

Co jest błędnego w moim kodzie?

0

Wersja C:

for (unsigned i=0, a=1; i<5; i++, a++)
   t[i] = a; 

Wersja C++

struct IncGenerator {
    int current_;
    IncGenerator (int start) : current_(start) {}
    int operator() () { return current_++; }
};

std::generate_n( t, 5, IncGenerator(1) );

Wersja C++ 11 (lambda)

static int nextValue = 1;
generate_n(t, 5, [] { return nextValue++; }); 

Wersja C++ 11 (iota, od VS 2012)

std::iota(t, t+5, 1);
0

No ale jak wpisałem taki kod (dodałem wyświetlanie zawartości zmiennej a przez operacji na tablicy i po owej operacji:

int t[5];

for (int a=0; a<5 ; )
{
    cout<<a<<"\t"; t[a]=++a; cout<<a<<endl;
}

To program wypisał (liczba z lewej to wartość przed wykonaniem operacji na tablicy t, zaś ten po prawej stronie to wartość po wykonaniu wspomnianej operacji:

0 1
1 2
2 3
3 4
4 5

To by wychodziło,że wykonywał zgodnie z moim opisem, czyli:

  1. Inicjalizacja zmiennej a i przypisanie jej wartości 0 (a=0).
  2. Sprawdza warunek ( 0<5), jest spełniony. (a=0)
  3. Wykonuje ciało pętli: t[0]=1; Na początku a=0, więc w indeksie wpisuje 0. Następnie
    zwiększa o 1 zmienną a (czyli 0+1=1) i przypisuje wartość zmiennej a, czyli a=1 i teraz ta
    nowa (zwiększona) wartość zostaje pobrana przez operator przypisana i co za tym idzie
    wpisana do zmiennej tablicy o indeksie 0, czyli t[0] = 1;
  4. Sprawdzenie warunku 1<5 - spełniony.
  5. Ciało pętli: t[1]=2 i dalej znowu będzie sprawdzał warunek, itd.

A zawartość tablicy po wykonaniu tej pętli
wyświetlona kodem:

 cout<<endl<<endl;
cout<<t[0]<<endl;
cout<<t[1]<<endl;
cout<<t[2]<<endl;
cout<<t[3]<<endl;
cout<<t[4]<<endl;

jest taka:

48799848
1
2
3
4

Dlaczego element o indeksie 0 zostało pominięty przez pętlę (i zamiast mieć wartość 1, to ma 48799848)? Co jest sprzeczne z tym z tym co program wypisał wcześniej.
Przecież przy wyświetlaniu wartości zmiennej a widać, że na początku ma ona wartość 0 (iteracja pierwsza) i taka powinna być przypisana do indeksu, a później jako wartość tablicy powinna zostać przypisana zwiększona wartość zmiennej a o 1. Później ta zwiększona wartość powinna być sprawdzona w warunku, itd. To czemu program wyświetlił co innego, a wykonał co innego?

0

Twoja linijka:

cout<<a<<"\t"; t[a]=++a; cout<<a<<endl;

wykonuje się tak:

cout << a;
cout << "\t"; 
++a;
t[a] = a; 
cout << a;
cout << endl;

Nie łącz kilku instrukcji w jedną linijkę bo zaciemniasz sobie sam kod.

0

To ja mam jedno pytanie czy kompilator w c++ wykonuje instrukcje w kolejności w jakiej zostały zapisane, czy w jakiś inny sposób?
Bo dotąd sądziłem, że kompilator w c++ wykonuje instrukcje w kolejności w jakiej mu je zapisałem. Przecież w c++ mamy wolny styl zapisu kodu.

To w jaki sposób, w jakiej kolejności instrukcje są wykonywane przez kompilator w linii? Bo myślałem,że pokolei za wyjątkiem priorytetów operatorów.

2
qws napisał(a):

To ja mam jedno pytanie czy kompilator w c++ wykonuje instrukcje w kolejności w jakiej zostały zapisane, czy w jakiś inny sposób?
Bo dotąd sądziłem, że kompilator w c++ wykonuje instrukcje w kolejności w jakiej mu je zapisałem. Przecież w c++ mamy wolny styl zapisu kodu.

Póki wynik jest taki sam kompilator może pomieszać co tylko chce w kodzie. Oczywiście musi to być też zgodne ze standardem języka. Są teź optymalizacje, które zrywają z kompatybilnością ze standardami i nawet nie muszą dawać takich samych wyników (np. ffast-math).

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