Array vs tablica w stylu C

0

Witam,
czytam o tablicach w C++, natrafiłem na takie coś:
http://cpp0x.pl/dokumentacja/standard-C++11/array/1146
"Tablice utworzone przy pomocy niniejszego szablonu posiadają taką samą wydajność jak tablice utworzone tradycyjnym zapisem C++, jednak są one bezpieczniejsze i wygodniejsze w użyciu."

i moje pytanie brzmi, dlaczego są bezpieczniejsze ? dlaczego są łatwiejsze w użyciu skoro odnosi się do nich tak samo ( tablica[i] ) ?

6

Koronny przykład jest już w kodzie w tym linku: chociażby dlatego, że istnieje tam metoda, która zwraca rozmiar tablicy i trudniej się pomylić i wyjść poza jej zakres.

3

Bo mają bajery. Można poza tradycyjnym sposobem jechać po niej iteratorem, dostać od niej jej rozmiar, pierwszy element , ostatni element. Klasycznie w tablicy musisz to sam obsługiwać, sam, się martwić. http://en.cppreference.com/w/cpp/container/array

4

Trochę zgadywanie "co autor miał na myśli", ale wygodniejsze bo są różne metody typu .empty(), .size(), przeciążone operatory, a bezpieczniejsze bo np. istnieje metoda .at(), która sprawdza czy indeks jest prawidłowy.

3

Wygodne jest też przekazywanie do funkcji obiektu, a nie wskaźnika na pierwszy element.
Dzięki temu w funkcji można używać pętli opartej na zakresie, czego nie da się zrobić ze zwykłą tablicą.

0

Dziękuję za szybką pomoc, przekonaliście mnie : D

0

Mam jednak problem z przekazaniem tablicy array od funkcji, kod:

#include <iostream>
#include <array>

int arrayTab ( int tab[],int i );

int main()
{
    using namespace std;
//  array<int,6> tablica {0,1,2,3,4,5};
    int tablica[6] = {0,1,2,3,4,5};

    cout << arrayTab(tablica,3);

}

int arrayTab ( int tab[],int i ){
return tab[i];
}
 

dla zwykłej działa, dla array nie działa, jak przekazać taką tablicę do funkcji?

2

No, bo array to tak naprawdę klasa, która opakowuje tę tablicę. Przekaż do funkcji coś takiego const array<int, 6>& tab

http://ideone.com/gpW9nB

5

Przecież std::array to szablon klasy a nie tablica. Nie możesz jej przekazać jako int *. Jest kilka możliwości.

  • Możesz przekazywać wskaźnik, który zwróci .data() ale wtedy tracisz wszystko, co daje std::array.
  • Możesz przekazywać po prostu tablicę o określonym rozmiarze i typie jak napisał @grzesiek51114.
  • Możesz używać funkcji szablonowych:
template<typename T, std::size_t N>
U foo(const std::array<T, N> &array)
  • Możesz też przekazywać iteratory do początku i końca tablicy (kontenera), tak jak robią to funkcje z biblioteki standardowej C++. To ostatnie rozwiązanie, dobrze zaimplementowane, pozwala Ci używać takiej funkcji niezależnie od kontenera.
0

Kilka przykładów:

#include <iostream>
#include <array>
#include <iterator>
#include <algorithm>

void printArray(const std::array<int, 6>& tablica) {
    for (auto const& elem : tablica)
        std::cout << elem << ' ';
    std::cout << '\n';
}

template <class C, class T>
void printArray(const C& coll) {
    std::copy(coll.cbegin(), coll.cend(), std::ostream_iterator<T>(std::cout, " "));
    std::cout << '\n';
}

void printArray(std::array<int, 6>::const_iterator& begin, std::array<int, 6>::const_iterator& end) {
    std::for_each(begin, end, [](auto const& elem) { std::cout << elem << ' '; });
    std::cout << '\n';
}

int main()
{
    std::array<int, 6> tablica{ 0,1,2,3,4,5 };
    printArray(tablica);
    printArray<std::array<int, 6>, int>(tablica);
    printArray(tablica.cbegin(), tablica.cend());
} 
0

I ponownie dziękuję za pomoc : )

0

Możesz przekazywać wskaźnik, który zwróci .data() ale wtedy tracisz wszystko, co daje std::array.

Jeśli funkcja z jakiejś biblioteki wymaga int*, to trzeba tak zrobić i nie zastanawiać się.

3

@carlosmay:

Endrju napisał(a)

To ostatnie rozwiązanie, dobrze zaimplementowane, pozwala Ci używać takiej funkcji niezależnie od kontenera

Trzymając się tego, takie iteratory powinny być przekazywane jako szablonowy argument.

template <class BeginIt, class EndIt>
U foo (BeginIt first1, EndIt last1)
0

Witam,
czytam o tablicach w C++, natrafiłem na takie coś:
http://cpp0x.pl/dokumentacja/standard-C++11/array/1146
"Tablice utworzone przy pomocy niniejszego szablonu posiadają taką samą wydajność jak tablice utworzone tradycyjnym zapisem C++, jednak są one bezpieczniejsze i wygodniejsze w użyciu."

i moje pytanie brzmi, dlaczego są bezpieczniejsze ? dlaczego są łatwiejsze w użyciu skoro odnosi się do nich tak samo ( tablica[i] ) ?

to zależy jakie komponenty się cche mieć zastosowane w jednym a drugim i jak to zostanie rpzetworzone w programie

0
Endrju napisał(a):

Przecież std::array to szablon klasy a nie tablica. Nie możesz jej przekazać jako int *. Jest kilka możliwości.

  • Możesz przekazywać wskaźnik, który zwróci .data() ale wtedy tracisz wszystko, co daje std::array.
  • Możesz przekazywać po prostu tablicę o określonym rozmiarze i typie jak napisał @grzesiek51114.
  • Możesz używać funkcji szablonowych:
template<typename T, std::size_t N>
U foo(const std::array<T, N> &array)
  • Możesz też przekazywać iteratory do początku i końca tablicy (kontenera), tak jak robią to funkcje z biblioteki standardowej C++. To ostatnie rozwiązanie, dobrze zaimplementowane, pozwala Ci używać takiej funkcji niezależnie od kontenera.

właśnie zależy mi aby przekazać różne tablice do funkcji, masz może jakiś banalny przykład do:

template<typename T, std::size_t N>
U foo(const std::array<T, N> &array)

dziękuję : )

4
template<typename T, size_t N>
void foo(const array<T, N>& ar)
{
    cout << "array's size is " << ar.size() << endl;  
}

int main() 
{
    array<int, 5> x;
    foo(x);
    array<int, 12> y;
    foo(y);
    array<double, 22> z;
    foo(z);
}
0

genialne, o to chodziło, dziękuję: )

0

a nie możesz sobie procedury napisać z którrej będziesz sobie co chciał zrobić

no masz jak z forum główny wątek jak nazwa ci zostaje a to co piszesz niezależnie wymieniasz tam typ danych const a i nawet procedure ominiesz w tej procedurze b ją funkcjami wywołujesz prosto napisane prawda

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