2009-05-17 4 views

ответ

12

Массивы в C/C++ не сохраняют свою длину в памяти, поэтому их размер не может быть найден с указанием указателя на массив. Любой код, использующий массивы в этих языках, опирается на постоянный известный размер или передается отдельная переменная, которая определяет их размер.

Общепринятое решение, если оно представляет проблему, состоит в том, чтобы использовать класс std::vector из стандартной библиотеки, которая намного ближе к управляемому (C#) массиву, то есть сохраняет свою длину и дополнительно имеет несколько полезных функции-члены (для поиска и манипуляции).

Используя std::vector, вы можете позвонить по телефону vector.size(), чтобы получить его размер/длину.

+0

Невозможно получить размер? –

+0

@John: Да, это невозможно. Я боюсь. См. Мой обновленный ответ. std :: vector может быть вашим лучшим вариантом. – Noldorin

+0

Это мой вопрос, как получить размер std :: vector? Это похоже на массив. Я сожалею о непонимании, я новичок в C++. –

0

В C/C++ массивы просто указывают на первый элемент массива, поэтому нет способа отслеживать размер или количество элементов. Вам нужно будет передать целое число, указывающее размер массива, если вам нужно его использовать.

Строки могут содержать, если они имеют нулевое завершение, используя функцию strlen(), но это просто считается до символа \ 0.

+2

-1 Массивы не являются указателями. – rightfold

0

Als Nolrodin указал выше, практически невозможно получить размер простого массива на C++, если у вас есть только указатель на его первый элемент. Однако, если у вас есть массив фиксированного размера есть хорошо известный C трюк, чтобы выработать количество элементов в массиве во время компиляции, а именно путем выполнения:

 
GrmblFx loadsOfElements[1027]; 
GrmblFx_length = sizeof(loadsOfElements)/sizeof(GrmblFx); 

14

Это действительно зависит от того, что вы имеете в виду по "массиву". Массивы в C++ будут иметь размер (что означает теперь «необработанный» размер байта), равный N разному размера одного элемента. Благодаря этому можно легко получить количество элементов, используя оператор sizeof. Но для этого требуется, чтобы у вас был доступ к типу этого массива. Как только вы передадите его функции, он будет преобразован в указатели, а затем вы потеряетесь. Никакой размер не может быть определен больше. Вам придется построить другой способ, который полагается на значение элементов для вычисления размера.

Вот некоторые примеры:

int a[5]; 
size_t size = (sizeof a/sizeof a[0]); // size == 5 

int *pa = a; 

Если мы теперь потерять имя «а» (и для этого его типа), например, пропускания «па» в функцию, где эта функция только тогда имеет значение этого указателя, тогда нам не повезло. Мы больше не можем получать размер. Нам нужно будет передать размер вместе с указателем на эту функцию.

Те же ограничения применяются, когда мы получаем массив с использованием new. Он возвращает указатель, указывающий на элементы этого массива, и, следовательно, размер будет потерян.

int *p = new int[5]; 
    // can't get the size of the array p points to. 
delete[] p; 

Он не может возвращать указатель, который имеет тип массива включены, так как размер массива, созданного с new можно вычислить во время выполнения. Но типы в C++ должны быть установлены во время компиляции. Таким образом, new стирает эту часть массива и вместо этого возвращает указатель на элементы. Обратите внимание, что вам не нужно возиться с new на C++. Вы можете использовать шаблон std::vector, как рекомендовано другим ответом.

+0

Кто-нибудь еще упоминал '' 'std :: extent'''? – ManuelAtWork

5

Для подсчета количества элементов в статическом массиве, вы можете создать шаблон функции:

template < typename T, size_t N > 
size_t countof(T const (&array)[ N ]) 
{ 
    return N; 
} 

Для стандартных контейнеров, таких как std::vector, функция size() используется. Этот шаблон также используется с boost arrays, которые представляют собой массивы фиксированного размера и не требуют ухудшения производительности для статических массивов. Код есть в комментариях выше, должен быть:

for (std::vector::size_type i(0); i < entries.size(); ++i) 

(при условии изменения размера в петле, в противном случае поднять ее,), а не рассматривать размер как переменные.

+0

Почему это работает? – Zingam

+0

@ Zingam шаблон? потому что ссылка на массив сохраняет тип массива, включая размер, в отличие от параметра без ссылки, который ухудшается до указателя. –

+0

Спасибо! Я понимаю не половину шаблона, но я все еще не могу понять, почему это утверждение работает: T const (& array) [N] Учебники по шаблонам, которые я читаю, не дают мне никаких подсказок. – Zingam

Смежные вопросы