Ответ 1
Да. Если тип объявленного элемента когда-либо изменяется, вы также можете написать
int iLength = sizeof(carray)/sizeof(carray[0]);
У меня есть массив С++, который указан ниже:
CString carray[] =
{
"A",
"B",
"C",
"D",
"E"
}
Я хочу определить длину carray
во время выполнения. Я делаю:
int iLength = sizeof(carray)/sizeof(CString);
Правильно ли это?
Да. Если тип объявленного элемента когда-либо изменяется, вы также можете написать
int iLength = sizeof(carray)/sizeof(carray[0]);
Вы можете использовать следующий шаблон функции. Если вы используете 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.
Это правильно, поскольку он использует метапрограммирование следующим образом:
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
}
Этот код верен, но в большинстве случаев существуют лучшие способы обработки массивов на С++. Тем более, что этот метод не будет работать с массивами с динамическим размером.
В таких случаях используйте стандартный класс библиотеки std::vector
, который представляет массив динамического размера (т.е. вы можете вставлять и удалять записи).
Да, это правильный способ сделать это, но он будет работать только в этой ситуации, когда размер массива известен во время компиляции и отображается на сайте оператора sizeof( array )
. Он не будет работать с массивами с динамическим размером - вам понадобятся другие методы, например, использование контейнера типа stl:: vector или передача/сохранение количества элементов в качестве отдельного параметра.
Это не время выполнения, оно компилирует время. То, как вы используете, правильно. Обратите внимание, что Visual Studio определяет функцию _countof
, которая делает то же самое.
Во время выполнения длина не может быть определена. Вы либо сохраняете длину самостоятельно, либо используете std::vector
Если у вас есть динамический массив, вы, вероятно, должны использовать что-то вроде STL-вектора. http://www.cppreference.com/wiki/stl/vector/start
Нормальные массивы на С++ - это фиксированный размер, и вам необходимо вручную выделить память для расширения динамических.
Если вы знаете размер вашего массива во время компиляции, используйте константу, а не расчет.
Прочитайте эту статью Ивана Дж. Джонсона в Dr. Dobbs. Я думаю, что он охватывает большинство представленных здесь решений. В нем также очень хорошо описаны достоинства и недостатки каждого подхода.
Windows SDK (то есть заголовок windows.h) предлагает макрос ARRAYSIZE, который безопасно реализует эту функциональность (т.е. не работает с нестационарными массивами)
Лучший способ - использовать макрос и использовать его там, где требуется размер.
#define MAX_ROWS 1048
int array[MAX_ROWS];
Таким образом вы можете использовать MAX_ROWS даже в функции, где массив передается в качестве аргумента.