wskaźniki a tablice wielowymiarowe

0

Witam mam taki problem zrobiłem program (dopiero się uczę) który do tablicy wielowymiarowej wpisuje wartości a później chce zobaczyć wartość z jakiegoś położenia(Inny użytkownik mi pomógł) i normalnie przez wpisanie np. tab[2][2] działa wypisuje poprawna wartość. Jak robię to na wskaźnikach nie chce działać.

#include <iostream>
#include <stdlib.h>

using namespace std;

int main()
{
    int index = 3;
    int index1 = 1;
    int number = 0;
    int i,j;
    int tab[index][index1];
    int *wsk;

    wsk = &tab[i][j];

    for ( i = 0  ; i < index ; i++)
    {
        for ( j = 0 ; j < index1 ; j++ )
        {
            cout << "podaj liczbe: ";
            cin >> number;

            tab[i][j] = number;
            cout << "tab[" << i << "][" << j << "] = " << number << endl;
            system("clear");
        }
    }
    //cout << tab[2][0] << endl;
    cout << "podaj 'i'' i 'j'" << endl;
    cin >> i;
    cin >> j;

    cout << *wsk[i][j] << endl;

    return 0;
}
 
0

Źle to robisz, przeczytaj jakiś kurs?

1

Wskaźnik int* można indeksować tak jakby był tablicą, ale jednowymiarową.

Jeżeli masz tablicę

int tab[2][2] = {{1,2},{3,4}};

to pod wskaźnikiem

int *wsk = &tab[0][0];

możesz zobaczyć cztery inty dwuwymiarowej tablicy, które kolejno ułożone są w pamięci: wsk[0]==1, wsk[1]==2, wsk[2]==3, wsk[3]==4.

Ale nie zadziała to jak dwuwymiarowa tablica.

4
Azarien napisał(a):

Wskaźnik int* można indeksować tak jakby był tablicą, ale jednowymiarową.

Jeżeli masz tablicę

int tab[2][2] = {{1,2},{3,4}};

to pod wskaźnikiem

int *wsk = &tab[0][0];

możesz zobaczyć cztery inty dwuwymiarowej tablicy, które kolejno ułożone są w pamięci: wsk[0]==1, wsk[1]==2, wsk[2]==3, wsk[3]==4.

Ale nie zadziała to jak dwuwymiarowa tablica.

Absolutnie nie! To jest undefined behavior (5.7/5 w C++14, 6.5.6/8 w C11, przekroczenie rozmiaru tablicy przy dodawniu wskaźnik + offset).

A co do tematu - chcesz mieć tablice wielowymiarowe? Użyj normalnej tablicy jednowymiarowej i odpowiednio zaimplementuj dostępy do niej, tak aby "udawała" tablicę wielowymiarową. Każda inna droga to droga pod górę i, mimo że usilnie uczy się jej wszędzie, prowadzi donikąd.

1

Wiedziałem że zaraz ktoś się przyczepi że UB, ale nie ma racji.

Nie wiem co to jest "5.7/5", w C++14 punkt 5.7 to “Additive operators”, a w C11 nie ma takiego punktu.
A stare standardy są stare.

#include <stdio.h>

int main()
{
  int tab[2][2] = {{1,2},{3,4}};
  int *wsk = &tab[0][0];

  printf("%d %d %d %d\n", wsk[0], wsk[1], wsk[2], wsk[3]);
}

Nie ma przekroczenia tablicy. Tablica ma cztery elementy typu int, i jest gwarantowana ich ciągłość w pamięci.
Wskaźnik nie odnosi się do elementów poza tablicą. Ponieważ elementy tablicy są typu int, a wskaźnik jest typu int*, jego dereferencja nie łamie zasad “strict aliasing”.

6
Azarien napisał(a):

Wiedziałem że zaraz ktoś się przyczepi że UB, ale nie ma racji.

Nie wiem co to jest "5.7/5", w C++14 punkt 5.7 to “Additive operators”, a w C11 nie ma takiego punktu.
A stare standardy są stare.
...

Nie ma przekroczenia tablicy. Tablica ma cztery elementy typu int, i jest gwarantowana ich ciągłość w pamięci.
Wskaźnik nie odnosi się do elementów poza tablicą. Ponieważ elementy tablicy są typu int, a wskaźnik jest typu int*, jego dereferencja nie łamie zasad “strict aliasing”.

Na takie farmazony mam tylko jedną odpowiedź:

1

Nie mogę namierzyć źródła, ale pamiętam wypowiedź experta, że w takich sytuacjach bezpieczne jest użyć "reinterpret_cast<>"

Znalazłem. Tablica dwuwymiarowa

for( std::size_t i = 0; i < sizeof( tab ) / sizeof( int ); ++i )
         std::cout << * reinterpret_cast < const int *>( reinterpret_cast < const char *>( & tab ) + i * sizeof( int ) ) << ' '; 
1
Endrju napisał(a):

Na takie farmazony mam tylko jedną odpowiedź:

Miałem nadzieję że rzucisz jakimś akapitem ze standardu. Ale widzę że nie ma kontrargumentu i zaczęło się obrzucanie błotem.

Tablica int[2][2] ma gwarantowaną ciągłość elementów. Wyjechania poza zaalokowaną tablicę również nie ma.

Ponadto int* to int*, nie pamięta na jakich rozmiarów i o ilu wymiarach tablicy element wskazuje. Jeżeli wsk = &tab[0][0], to wsk+3 = &tab[1][1].

Element tablicy był intem, dereferencja następuje do inta, nie ma złamania zasady strict aliasing.

3

@Azarien: 5.7/5: If both the pointer operand and the result point to elements of the same array object, or one past the last element of the array object, the evaluation shall not produce an overflow; otherwise, the behavior is undefined.

1

@Azarien: Element *(a+3) dla a[2][2] nie jest elementem spoza tablicy a? a jest niczym innym jak tablicą tablic. Czyli tablicą. Dwuelementową. Której elementy są tablicami. A Ty odwołujesz się do trzeciego elementu tablicy dwuelementowej.

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