C ++ में आता है


हम श्रृंखला जारी रखते हैं "सी ++, गहरी खुदाई"। इस श्रृंखला का उद्देश्य आपको भाषा की विभिन्न विशेषताओं के बारे में यथासंभव बताना है, संभवतः काफी विशेष है। यह श्रृंखला का चौथा लेख है, C ++ में ओवरलोडिंग पर पहले तीन यहाँ , यहाँ और यहाँ हैं

यह लेख सरणियों के बारे में है। एरे को सी ++ की सबसे प्राचीन परतों के लिए जिम्मेदार ठहराया जा सकता है, वे सी। के पहले संस्करणों से आए थे। फिर भी, सरणियों को सी ++ के ऑब्जेक्ट-ओरिएंटेड टाइप सिस्टम में शामिल किया गया है, हालांकि कुछ कैविट्स के साथ। संभावित त्रुटियों से बचने के लिए प्रोग्रामर के लिए इन विशेषताओं के बारे में जानना महत्वपूर्ण है। लेख में एक और सी विरासत - तुच्छ प्रकार और असिंचित चर की भी खोज की गई है। C ++ 11 के नवाचारों में से कुछ, सरणियों के साथ काम को प्रभावित करते हैं, इन सभी नई विशेषताओं को भी विस्तार से वर्णित किया गया है। तो, आइए सरणियों के बारे में सब कुछ बताने की कोशिश करें।



विषय - सूची


विषय - सूची

  1.
    1.1.
    1.2.
    1.3.
    1.4.
  2.
    2.1.
    2.2.
  3.
    3.1.
    3.2.
      3.2.1
      3.2.2
      3.2.3
  4.
    4.1.
    4.2.
  5.
  6.
    6.1.
    6.2.
    6.3.
  7.
  8.
  




1. सामान्य प्रावधान


एक सरणी सबसे सरल कुल प्रकार है। वह स्मृति के निरंतर खंड में एक पंक्ति में व्यवस्थित समान तत्वों का एक सेट तैयार करता है। एक रूप या किसी अन्य में एरर्स लगभग सभी प्रोग्रामिंग भाषाओं द्वारा समर्थित हैं और यह आश्चर्य की बात नहीं है कि वे सी के पहले संस्करणों में दिखाई दिए और फिर सी ++ का हिस्सा बन गए।



1.1। ऐलान की घोषणा


यदि संकलन के समय Tकुछ प्रकार, Nस्थिर या अभिव्यक्ति का मूल्यांकन किया जाता है, तो निर्देश


T a[N];

a « N T» (array of N elements of the type T). N std::size_t, , , . sizeof(T) , , , N*sizeof(T) . . T[N], . , , , , .


(regular arrays), , «» C++ .

:


const int N = 8;
constexpr int Square(int n) { return n * n; }

int a1[1];
int a2[N];
int a3['Q'];
int a4[Square(2)];

:


int n;

int b1[0];   //  
int b2[n];   //      
int b3["Q"]; //     size_t

, 0 N-1. :


int a[4];
a[0] = 42;
int t = a[3];

, .


, .


int a[4], b[8];

. typedef:


typedef int I4[4];

(C++11) using:


using I4 = int[4];

:


I4 a, b;

,


int a[4], b[4];


1.2.


sizeof .


sizeof , .


_countof() ( MSVS <cstdlib>) , . ++17 std::size(), ( , ).


int a[4];
std::cout << sizeof(a) << ' ' << std::size(a) << '\n';

: 16 4


C++11 ( ) std::begin() std::end(). std::begin() , std::end() past-the-last . ( : std::cbegin(), std::cend().) for.


int a[4]{ 4, 3, 2, 1 };

for (auto t : a)
{
    std::cout << t << ' ';
}

:


std::sort(std::begin(a), std::end(a));


1.3.


, , , . , , . (, .) . (. 6) .



1.4.


, void.


.


int u, v;
int &rr[2] = { u, v }; // 

.


int * const rr[2] = { &u, &v };

( 3.2.)


C++11 std::reference_wrapper<>. , . , - get(). .


int u = 42, v = 5;
std::reference_wrapper<int> rr[2] = { u, v };
std::cout << rr[0] << ' ' << rr[1] << '\n'; // : 42 5
++rr[0];
rr[1].get() = 125;                          // get() 
std::cout << u << ' ' << v << '\n';         // : 43 125

.


int ff[2](double); // 

.


int (*ff[2])(double);

std::reference_wrapper<> , — , &. — std::function<>, .


auto.


auto x[2] = {1, 2}   // 

const , .


using I4 = int[4];
const I4 ci; //  ,   const int ci[4];


2.


, C++.



2.1.


, , «». (decay, array-to-pointer decay). (Decay .) , . sizeof, & ( ) . sizeof 1.2, 4. decltype , .


, . ( C) :


const int N = 100;
int a[N];
for (int *d = a, *end = d + N; d < end; ++d)
{
    *d = rand();
}

, .


.


void Foo(int a[4]);
void Foo(int a[]);
void Foo(int *a);

— . (, ).


.


// file 1
int A[4];

// file 2
extern int A[];

.


auto .


int a[4];
auto da = a; //  da   int*



template<typename T>
void Foo(T t);

, .


. ( C .) .


class B {/* ... */};
class D : public B {/* ... */};
void Foo(B[], int size); //     B

.


D d[4];
Foo(d, _countof(d));

sizeof(B) < sizeof(D), Foo() d ( , ) , , Foo() . , , .



2.2.


( ) , «». , :


using I4 = int[4];
I4 a;
I4 b = a; // 
I4 b2;
b2 = a; // 

.


I4 Foo(); // 

//, ( ) .


struct X 
{ 
    int A[4]; 
};

, .


X Foo();
X x;
X x2 = x;
X x3;
x3 = Foo();


3.


.



3.1.


++. , — . , . , . , ++, . , , , , , , . : , , , , .


, - . . , . , - , .


: (), , , , . , . .


, , .


++11 , ( <type_traits>). , . std::is_trivial<>::value true, T false .



3.2.



3.2.1.


, . , , . , , .


C :


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

++11 (uniform initialization) :


int a[4]{ 1, 2, 3, 4 };

=, , , , .


, .


int a[] { 1, 2, 3, 4 };

, . , (, , ), . , , .


int a[4]{};

.


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

, .


.


const char str[] = "meow";
const wchar_t wstr[] = L"meow";

, .


3.2.2.


++11 , . : .


class X
{
    int a[4]{ 1, 2, 3, 4 };
    int b[2];
// ...
public:
    X(int u, int v) : b{ u, v } 
    {}
// ...
};

, .


, , , .


class X
{
    static int A[];
// ...
};

int X::A[] = { 1, 2, 3, 4 };


3.2.3.


, , , (, , constexpr). , , — . :


T a[] = {x1 /*, ... */};



T a[]{x1 /*, ... */};



T t = x1;

. .


.


class Int
{
    int m_Value;
public:
    Int(int v) : m_Value(v) {}
// ...
};
// ...
int x, y;
// ...
Int rr[] = { x, y };

Int explicit, .


Int rr[] = { Int(x), Int(y) };

. .



4.



4.1.




T a[N];

:


T(*pa)[N] = &a;

&. T(*)[N].


, N T.


— ( , , ), . , «» . .


int a[4];
int(*pa)[4] = &a; // OK
int(*p2)[2] = &a; // ,   

, .


* .


(*pa)[3] = 42;

.


using I4 = int[4];
I4 a{ 1, 2, 3, 4 };
I4 *pa = &a;

auto, .


int a[4];
auto pa = &a; //  pa   int(*)[4]

, .



4.2.




T a[N];

:


T(&ra)[N] = a;

, . T(&)[N].


.


T(*pa)[N] = &a;
T(&ra)[N] = *pa;

, «» . .


int a[4];
int(&ra)[4] = a; // OK
int(&r2)[2] = a; // ,   

, .


ra[3] = 0;

, .




void Foo(T(&a)[N]);

T[N], .


.


using I4 = int[4];
I4 a{ 1, 2, 3, 4 };
I4 &ra = a;

auto, .


int a[4];
auto &ra = a; //  ra   int(&)[4]

& auto, , ra int*.




template<typename T>
void Foo(T& t);

, .


.


template<typename T, std::size_t N>
void Foo(T(&a)[N]);

T N ( ). , . _countof() std::size(), std::begin() std::end(), for . 5 .



5.


C++ , a[N, M] , « », a[N][M].


T , N M , ,


T a[N][M];

a , N , M T. . a[i][j], i 0 N-1, j 0 M-1, . , . N , M . T[N][M].


a[i] M T. , .


T *dai = a[i];
T(*pai)[M] = &a[i];
T(&rai)[M] = a[i];

. , .


T a[N][M];
T(*da)[M] = a;

, :


void Foo(T a[N][M]);
void Foo(T a[][M]);
void Foo(T(*a)[M]);

, .


.


using I4 = int[4];
I4 b[2];

,


int b[2][4];

:


int b[2][4] = {{1, 2, 3, 4}, {5, 6, 7, 8}};

, {}. .


int b[][4] = {{1, 2, 3, 4}, {5, 6, 7, 8}}; // 
int b[][] = {{1, 2, 3, 4}, {5, 6, 7, 8}};  // 

:


T a[N][M];
T(*pa)[N][M] = &a;

. .


template<typename T, std::size_t N, std::size_t M>
void Print2dArray(T(&a)[N][M])
{
    for (int i = 0; i < N; ++i)
    {
        for (int j = 0; j < M; ++j)
        {
            std::cout << a[i][j] << ' ';
        }
        std::cout << '\n';
    }
}
// ...
int b[2][4] = {{1, 2, 3, 4}, {5, 6, 7, 8}};
Print2dArray(b);

:


1 2 3 4
5 6 7 8

.


T mtx[N][M];

N , M , mtx[i][j] i- j- , mtx[i] M, i- . , . , .



6.


C++ « ». , ( ). . C++ .



6.1.


T , n , ,


T *pa = new T[n];

. n std::size_t, . , , n*sizeof(T), . pa .


T , , .


C++11 .


int *pa = new int[n]{1, 2, 3, 4};

, ( , n ). , , . , , .


new[] . , , T , . - , , , . std::bad_alloc.


delete[], , new[].


delete[] pa;

, , , ( ), .


pa, new[], , ( «») , . for.



6.2.


std::unique_ptr<> (. [Josuttis]). , [] -> delete[] . :


int n = 100; 
std::unique_ptr<int[]> aptr(new int[n]);
for (int i = 0; i < n; ++i)
{
    aptr[i] = i; 
}

: , , for. std::unique_ptr<> , std::vector<>. std::shared_ptr<> .



6.3.


, new T[n][m], n m , . , , . M , , :


T(*pa)[M] = new T[n][M];

new[] . pa[i][j], pa[i] M T.


.


using I4 = int[4];
I4 *pa = new I4[n];

[] , , . .


// 2D interface to a buffer
template<typename T>
class MatrixView 
{
    T * const m_Buff;
    int const m_RowCount;
    int const m_ColCount;
public:
    MatrixView(T* buff, int rowCount, int colCount)
        : m_Buff(buff)
        , m_RowCount(rowCount)
        , m_ColCount(colCount)
    {}
    T *operator[](int rowInd) const
    {
        return m_Buff + rowInd * m_ColCount;
    }
};
// buffer owner
template<typename T>
class DynBuffer 
{
    T* const m_Buff;
protected:
    T* Buff() const { return m_Buff; };
    DynBuffer(int length) : m_Buff(new T[length]{}) {}
    ~DynBuffer() { delete[] m_Buff; }
    DynBuffer(const DynBuffer&) = delete;
    DynBuffer& operator=(const DynBuffer&) = delete;
};

template<typename T>
class MatrixSimple 
    : DynBuffer<T>, public MatrixView<T>
{
    using Buff = DynBuffer<T>;
    using View = MatrixView<T>;
public:
    MatrixSimple(int rowCount, int colCount)
        : Buff(rowCount * colCount)
        , View(Buff::Buff(), rowCount, colCount)
    {}
};

:


MatrixSimple<int> mtx(3, 3);
mtx[1][2] = 42; //  ,  

proxy-, , RowProxy, . , , , - begin(), end(), etc. .



7.


, «». T[]. .


//  
template <typename T>
class U
{
public:
    const char* Tag() const { return "base"; }
};

//    
template <typename T>
class U<T*>
{
public:
    const char* Tag() const { return "pointer"; }
};

//    
template <typename T>
class U<T[]>
{
public:
    const char* Tag() const { return "array"; }
};

U<int> u1;
U<int*> u2;
U<int[]> u3;

std::cout << u1.Tag() << ' ' << u2.Tag() << ' ' << u3.Tag();

: base pointer array


std::unique_ptr<>, , . 6.2.



8.


( ), .


std::array<>. ( C++11, . [Josuttis].) , : . , . :


std::array<int, 4> a{1, 2, 3, 4};

.


for (int i = 0; i < a.size(); ++i)
{
    std::cout << a[i] << ' ';
}
for (auto it = a.begin(); it != a.end(); ++it)
{
    std::cout << *it << ' ';
}
for (auto t : a)
{
    std::cout << t << ' ';
}

std::vector<>. , ( №1), - .


std::valarray<>. .




[जोसटिस]
जोसाटिस, निकोलाई एम। सी। ++ मानक पुस्तकालय: संदर्भ गाइड, 2 एड ।: प्रति। अंग्रेजी से - एम।: एलएलसी “आई.डी. विलियम्स, 2014।




All Articles