Ответ 1
Учитывая ваш массив строк, вы можете, безусловно, использовать sizeof(array)/sizeof(array[0])
, чтобы получить его размер, и следующая программа работает очень хорошо:
int main()
{
std::string array[] = { "S1", "S2", "S3" };
std::cout << "A number of elements in array is: "
<< sizeof(array)/sizeof(array[0]) << '\n';
foo(array);
}
Неясно, что вы имеете в виду, говоря, что размер элементов меняется. Размер элементов любого массива всегда известен во время компиляции, без исключений.
Однако существуют ситуации, когда вышеизложенное не работает. Рассмотрим следующий пример:
void foo(std::string array[])
{
std::cout << "A number of elements in array is: "
<< sizeof(array)/sizeof(array[0]) << '\n';
}
Приведенный выше код обречен на провал. Сначала это может показаться немного странным, но причина этого на самом деле очень проста - это называется распадом массива. Это означает, что каждый раз, когда вы передаете массив функции, его тип автоматически разлагается до указателя. Таким образом, вышеуказанная функция на самом деле эквивалентна этому:
void foo(std::string *array)
{
}
И если в первом примере оператор sizeof
возвращает общий размер массива, во втором примере он возвращает размер указателя на этот массив, что совсем другое.
Обычно есть два способа, которыми люди обходятся. Первый заключается в том, чтобы добавить специальный "последний" элемент массива, чтобы приложение могло перемещаться по массиву, пока не увидит последний элемент, и вычислить длину массива. Строковые литералы - прекрасный пример этого - каждый строковый литерал заканчивается на '\ 0, и вы всегда можете рассчитать его длину. Вот пример:
static void foo(const std::string *array)
{
size_t i = 0;
while (!array[i].empty())
++i;
std::cout << "Array length is: " << i << std::endl;
}
Недостатком, очевидно, является необходимость пересечения массива для определения его длины. Второй способ всегда иметь длину массива, например:
static void foo(const std::string *array, size_t length)
{
// ...
}
void bar()
{
std::string array[] = { "S1", "S2", "S3" };
foo(array, sizeof(array)/sizeof(array[0]));
}
В С++ вы можете использовать шаблон для вычитания длины массивов, например:
template <size_t array_length>
static void foo(const std::string (&array)[array_length])
{
std::cout << "A number of elements in template array is: "
<< array_length << '\n';
}
Все вышеизложенное относится к простым массивам, встроенным в язык. С другой стороны, С++ предоставляет богатый набор контейнеров более высокого уровня, что дает вам большую гибкость. Поэтому вы можете захотеть использовать один из контейнеров, доступных вам как часть стандартной библиотеки С++. Список стандартных контейнеров см. В разделе http://en.cppreference.com/w/cpp/container
Надеюсь, это поможет. Удачи!