Arytmetyka wskaźników w tablicach

0

Witam, mam pytanie, czy przesuwanie się w taki sposob po tablicy jest poprawne:

int main()
{

    char* a = new char[6];
    a[0] = 'k';
    a[1] = 'a';
    a[2]= 'j';
    a[3] = 'a';
    a[4] = 'k';
    a[5] = '\0';
    while(*a!='\0'){
        cout<<*a;
        *a++;
    }


    return 0;
}

Czy raczej powinienem stworzyć osobny wskaźnik wskazujący na moja tablice i na nim się poruszać np. tak:

int main()
{

    char* a = new char[6];
    char* x = a;
    a[0] = 'k';
    a[1] = 'a';
    a[2]= 'j';
    a[3] = 'a';
    a[4] = 'k';
    a[5] = '\0';
    while(*x!='\0'){
        cout<<*x;
        *x++;
    }


    return 0;
}
1

Raczej ta druga opcja. Dzięki temu możesz zwolnić zarezerwowaną pamięć.

PS. x++; zamiast *x++;.

1

Czemu *x++, a nie x++? A różnica jest tylko taka, że po wykonaniu górnego kodu wskaźnik a jest ustawiony poza tablicę, a dolnego na początek tablicy, i górny kod jest krótszy o linijkę.

1

W pierwszym przykładzie a po wyjściu z pętli jest ustawiony na ostatni element i żeby zwolnić pamięć musiałbyś z powrotem ustawiać wskaźnik

a -= 5;
delete[] a;

Druga wersja jest o wiele bezpieczniejsza.

1

Ok, dziękuję. A czy używanie *x++ zamiast x++ coś zmienia ?

Różnicy w Twoim programie nie ma, bo operator++ (postfiks) ma wyższy priorytet niż operator*, więc wyrażenie

*x++

jest równoważne

*(x++)

W pierwszym przypadku inkrementujesz wskaźnik a potem zwracasz poprzednią wartość wskaźnika. W drugim przypadku inkrementujesz, a potem zwracasz poprzedni element, na który wskazywał wskaźnik. Jako że nic nie robisz z tą zwracaną wartością, to nie ma różnicy w działaniu.

Natomiast generalnie kod powinien robić to co masz na myśli, i nic więcej. Skoro Twoją intencją jest jedynie inkrementacja wskaźnika, to dlaczego wyłuskasz element i go zwracasz? Podobnie po co w ogóle cokolwiek zwracasz jak nie potrzebujesz tej wartości? Dlatego najlepiej to używać tej wersji

++x
2

Generalnie w C++ nie używa się surowych tablic kiedy ma się do dyspozycji wektory, listy, mapy itd z biblioteki standardowej. Jeśli jednak dla celów dydaktycznych chcesz je poćwiczyć, to tak:

    char *const a = new char[6];//jeśli alokuje się pamięć, to należy ją potem zwolnić. Aby to było możliwe, trzeba mieć oryginalny wskaźnik na tą pamięć, a takie użycie const spowoduje, że sobie tego wskaźnika omyłkowo nie przestawisz, bo próba w stylu a++ wywali błąd kompilacji
    a[0] = 'k';
    a[1] = 'a';
    a[2]= 'j';
    a[3] = 'a';
    a[4] = 'k';
    a[5] = '\0';
    uint offset = 0;//ja lubię tak się posługiwać wskaźnikiem
    while (*(a + offset) != '\0')
    {//stawiaj nawiasy jak C++ przykazuje, to nie java
        cout << *(a + offset);
        ++offset;
    }

//wersja z zapisem tablicowym
    cout << "\n";
    offset = 0;
    while (a[offset] != '\0')
    {//stawiaj nawiasy jak C++ przykazuje, to nie java
        cout << a[offset];
        ++offset;
    }

//gdzieś niżej w kodzie
   delete[] a;
3

Link dla twojego nauczyciela C++: Stop teaching C (when teaching C++)..

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