У меня объявлен массив C ++, как указано ниже:

CString carray[] =
{
        "A",
        "B",
        "C",
        "D",
        "E"
}

Я хочу определить длину carray во время выполнения. Я делаю:

int iLength = sizeof(carray)/sizeof(CString);

Это правильно?

5
Ashish Ashu 14 Июл 2009 в 14:20

10 ответов

Лучший ответ

Да. В случае, если объявленный тип элемента когда-либо изменится, вы также можете написать

int iLength = sizeof(carray)/sizeof(carray[0]);
17
Timbo 14 Июл 2009 в 10:22

Вы можете использовать следующий шаблон функции. Если вы используете Boost, вы можете позвонить boost::size.

template <typename T, std::size_t N>
std::size_t size(T (&)[N])
{
    return N;
}

int iLength = size(carray);

Однако, как уже было сказано другими, вы должны предпочесть std::vector массивам в стиле C.

24
avakar 14 Июл 2009 в 10:37

Этот код правильный, но в большинстве случаев есть более эффективные способы обработки массивов в C ++. Тем более, что этот метод не будет работать с массивами динамического размера.

В таких случаях используйте класс стандартной библиотеки std::vector, который представляет собой массив динамического размера (т.е. вы можете вставлять и удалять записи).

5
Konrad Rudolph 14 Июл 2009 в 10:21

Да, это правильный способ сделать это, но он будет работать только в этой ситуации, когда размер массива известен во время компиляции и отображается на сайте оператора sizeof( array ). Он не будет работать с массивами динамического размера - вам понадобятся другие методы для них, например, использование контейнера, такого как stl :: vector, или передача / сохранение количества элементов в качестве отдельного параметра.

1
sharptooth 14 Июл 2009 в 10:22

Это не время выполнения, это время компиляции. То, как вы используете, правильный. Обратите внимание, что Visual Studio определяет функцию _countof, которая делает то же самое.

Во время выполнения длина не может быть определена. Вы либо сами сохраняете длину, либо используете std::vector

0
xtofl 14 Июл 2009 в 10:22

Если у вас есть динамический массив, вам, вероятно, следует использовать что-то вроде вектора STL. http://www.cppreference.com/wiki/stl/vector/start

Нормальные массивы в C ++ имеют фиксированный размер, и вам необходимо вручную выделить память для расширения динамических.

Если вы знаете размер своего массива во время компиляции, используйте константу, а не вычисление.

0
Glenn 14 Июл 2009 в 10:26

Прочтите эту статью Айвена Джонсона в журнале Dr . Доббс Журнал. Думаю, он охватывает большинство представленных здесь решений. Он также очень хорошо описывает достоинства и недостатки каждого подхода.

0
Abhay 14 Июл 2009 в 10:32

Windows SDK (т.е. заголовок windows.h) предлагает макрос ARRAYSIZE, который реализует эту функцию безопасным образом (т.е. не работает с нестатическими массивами).

0
Diaa Sami 14 Июл 2009 в 12:32

Лучше всего использовать макрос и использовать его там, где вам нужен размер.

#define MAX_ROWS 1048
int array[MAX_ROWS];

Таким образом, вы можете использовать MAX_ROWS даже в функции, в которой массив передается в качестве аргумента.

0
Saradhi 14 Июл 2009 в 12:56

Это правильно, поскольку здесь используется метапрограммирование:

template <typename T, std::size_t N>
inline std::size_t array_size( T (&)[N] ) {
   return N;
};

Вы должны знать, что это работает, когда компилятор видит определение массива, но не после того, как оно было передано функции (где оно распадается на указатель):

void f( int array[] )
{
   //std::cout << array_size( array ) << std::endl; // fails, at this point array is a pointer
   std::cout << sizeof(array)/sizeof(array[0]) << std::endl; // fails: sizeof(int*)/sizeof(int)
}
int main()
{
   int array[] = { 1, 2, 3, 4, 5 };
   f( array );
   std::cout << array_size( array ) << std::endl; // 5
   std::cout << sizeof(array)/sizeof(array[0]) << std::endl; // 5 
}
6
David Rodríguez - dribeas 14 Июл 2009 в 12:05