Есть ли способ узнать, сколько значений имеет массив? Обнаружение того, достигло ли я конца массива, также будет работать.
Как найти длину массива?
Ответ 1
Если вы имеете в виду массив C-стиля, вы можете сделать что-то вроде:
int a[7];
std::cout << "Length of array = " << (sizeof(a)/sizeof(*a)) << std::endl;
Это не работает с указателями, т.е. он не будет работать для одного из следующих действий:
int *p = new int[7];
std::cout << "Length of array = " << (sizeof(p)/sizeof(*p)) << std::endl;
или
void func(int *p)
{
std::cout << "Length of array = " << (sizeof(p)/sizeof(*p)) << std::endl;
}
int a[7];
func(a);
В С++, если вы хотите такого поведения, то вы должны использовать контейнерный класс; вероятно std::vector
.
Ответ 2
Как уже говорилось, вы можете использовать sizeof(arr)/sizeof(*arr)
но это даст вам неправильный ответ для типов указателей, которые не являются массивами.
template<class T, size_t N>
constexpr size_t size(T (&)[N]) { return N; }
Это имеет приятное свойство не компилироваться для типов не массивов (Visual Studio имеет _countof
которая делает это). constexpr
делает это выражение времени компиляции, поэтому у него нет недостатков по сравнению с макросом (по крайней мере, ни одного из них я не знаю).
Вы также можете рассмотреть возможность использования std::array
из С++ 11, который показывает его длину без издержек над собственным массивом C.
С++ 17 имеет std::size()
в заголовке <iterator>
который делает то же самое и работает также для контейнеров STL (благодаря @Jon C).
Ответ 3
Выполнение sizeof( myArray )
даст вам общее количество байтов, выделенных для этого массива. Затем вы можете узнать количество элементов в массиве, разделив на размер одного элемента в массиве: sizeof( myArray[0] )
Ответ 4
Есть ли способ узнать, сколько значений имеет массив?
Да!
Попробуйте sizeof(array)/sizeof(array[0])
Обнаружение того, достигло ли я конца массива, также будет работать.
Я не вижу никакого способа для этого, если ваш массив не является массивом символов (например, строка).
P.S: В С++ всегда используйте std::vector
. Существует несколько встроенных функций и расширенная функциональность.
Ответ 5
Хотя это старый вопрос, стоит обновить ответ на С++ 17. В стандартной библиотеке теперь есть шаблонная функция std::size()
, которая возвращает количество элементов как в контейнере std, так и в массиве в стиле C. Например:
#include <iterator>
uint32_t data[] = {10, 20, 30, 40};
auto dataSize = std::size(data);
// dataSize == 4
Ответ 6
std::vector
имеет метод size()
, который возвращает количество элементов в векторе.
(Да, это ответ в ответ)
Ответ 7
#include <iostream>
int main ()
{
using namespace std;
int arr[] = {2, 7, 1, 111};
auto array_length = end(arr) - begin(arr);
cout << "Length of array: " << array_length << endl;
}
Ответ 8
Так как С++ 11, некоторые новые шаблоны вводятся, чтобы помочь уменьшить боль при работе с длиной массива. Все они определены в заголовке <type_traits>
.
-
Если
T
является типом массива, он предоставляет значение константы элемента, равное количеству измерений массива. Для любого другого типа значение равно 0. -
Если
T
является типом массива, он предоставляет значение константы элемента, равное количеству элементов вN
-м измерении массива, еслиN
находится в [0,std::rank<T>::value
). Для любого другого типа или еслиT
- это массив неизвестных границ по его первому размеру, аN
- 0, значение равно 0. -
Если
T
- это массив некоторого типаX
, он предоставляет тип typedef-члена, равныйX
, в противном случае типT
. Обратите внимание, что еслиT
- многомерный массив, удаляется только первое измерение. -
std::remove_all_extents<T>::type
Если
T
является многомерным массивом какого-либо типаX
, он предоставляет тип typedef-члена, равныйX
, иначе type isT
.
Чтобы получить длину по любому размеру многомерного массива, decltype
можно использовать для объединения с std::extent
. Например:
#include <iostream>
#include <type_traits> // std::remove_extent std::remove_all_extents std::rank std::extent
template<class T, size_t N>
constexpr size_t length(T(&)[N]) { return N; }
template<class T, size_t N>
constexpr size_t length2(T(&arr)[N]) { return sizeof(arr) / sizeof(*arr); }
int main()
{
int a[5][4][3]{{{1,2,3}, {4,5,6}}, { }, {{7,8,9}}};
// New way
constexpr auto l1 = std::extent<decltype(a)>::value; // 5
constexpr auto l2 = std::extent<decltype(a), 1>::value; // 4
constexpr auto l3 = std::extent<decltype(a), 2>::value; // 3
constexpr auto l4 = std::extent<decltype(a), 3>::value; // 0
// Mixed way
constexpr auto la = length(a);
//constexpr auto lpa = length(*a); // compile error
//auto lpa = length(*a); // get at runtime
std::remove_extent<decltype(a)>::type pa; // get at compile time
//std::remove_reference<decltype(*a)>::type pa; // same as above
constexpr auto lpa = length(pa);
std::cout << la << ' ' << lpa << '\n';
// Old way
constexpr auto la2 = sizeof(a) / sizeof(*a);
constexpr auto lpa2 = sizeof(*a) / sizeof(**a);
std::cout << la2 << ' ' << lpa2 << '\n';
return 0;
}
BTY, чтобы получить общее количество элементов в многомерном массиве:
constexpr auto l = sizeof(a) / sizeof(std::remove_all_extents<decltype(a)>::type);
Или поместите его в шаблон функции:
#include <iostream>
#include <type_traits>
template<class T>
constexpr size_t len(T &a)
{
return sizeof(a) / sizeof(typename std::remove_all_extents<T>::type);
}
int main()
{
int a[5][4][3]{{{1,2,3}, {4,5,6}}, { }, {{7,8,9}}};
constexpr auto ttt = len(a);
int i;
std::cout << ttt << ' ' << len(i) << '\n';
return 0;
}
Дополнительные примеры того, как их использовать, можно найти, следуя ссылкам.
Ответ 9
Также есть путь TR1/С++ 11/С++ 17 (см. Live on Coliru):
const std::string s[3] = { "1"s, "2"s, "3"s };
constexpr auto n = std::extent< decltype(s) >::value; // From <type_traits>
constexpr auto n2 = std::extent_v< decltype(s) >; // C++17 shorthand
const auto a = std::array{ "1"s, "2"s, "3"s }; // C++17 class template arg deduction -- http://en.cppreference.com/w/cpp/language/class_template_argument_deduction
constexpr auto size = std::tuple_size_v< decltype(a) >;
std::cout << n << " " << n2 << " " << size << "\n"; // Prints 3 3 3
Ответ 10
Вместо использования встроенной функции массива aka:
int x[2] = {0,1,2};
вы должны использовать класс массива и шаблон массива. Попробуйте:
#include <array>
array<type_of_the_array, number_of_elements_in_the_array> Name_of_Array = {};
Итак, теперь, если вы хотите найти длину массива, все, что вам нужно, использовать функцию размера в классе массива.
Name_of_Array.size();
и это должно возвращать длину элементов в массиве.
Ответ 11
В С++, используя класс std:: array для объявления массива, можно легко найти размер массива, а также последний элемент.
#include<iostream>
#include<array>
int main()
{
std::array<int,3> arr;
//To find the size of the array
std::cout<<arr.size()<<std::endl;
//Accessing the last element
auto it=arr.end();
std::cout<<arr.back()<<"\t"<<arr[arr.size()-1]<<"\t"<<*(--it);
return 0;
}
На самом деле класс массива имеет множество других функций, которые позволяют использовать массив стандартным контейнером.
Ссылка 1 на С++ std:: класс массива
Ссылка 2 на класс std:: array
Примеры в ссылках полезны.
Ответ 12
Для C++/CX (при написании, например, приложений UWP с использованием C++ в Visual Studio) мы можем найти количество значений в массиве, просто используя функцию size()
.
Исходный код:
string myArray[] = { "Example1", "Example2", "Example3", "Example4" };
int size_of_array=size(myArray);
Если вы cout
на size_of_array
выход будет:
>>> 4
Ответ 13
Вот одна реализация ArraySize
из Google Protobuf.
#define GOOGLE_ARRAYSIZE(a) \
((sizeof(a) / sizeof(*(a))) / static_cast<size_t>(!(sizeof(a) % sizeof(*(a)))))
// test codes...
char* ptr[] = { "you", "are", "here" };
int testarr[] = {1, 2, 3, 4};
cout << GOOGLE_ARRAYSIZE(testarr) << endl;
cout << GOOGLE_ARRAYSIZE(ptr) << endl;
ARRAYSIZE (arr) работает, проверяя sizeof (arr) (количество байтов в массив) и sizeof (* (arr)) (количество байтов в одном массиве элемент). Если первое делится последним, возможно, arr на самом деле массив, и в этом случае результатом деления является # of элементов в массиве. В противном случае arr не может быть массивом, и мы генерируем ошибку компилятора, чтобы предотвратить компилирование.
Поскольку размер bool определяется реализацией, нам нужно ! (sizeof (a) и sizeof (* (a))) до size_t, чтобы обеспечить окончательный результат имеет тип size_t.
Этот макрос не идеален, поскольку он ошибочно принимает определенные указатели, а именно, где размер указателя делится на указателя размер. Поскольку весь наш код должен пройти через 32-битный компилятор, где указатель равен 4 байтам, это означает, что все указатели относятся к типу, размер 3 или больше, чем 4 (будет отклонен).
Ответ 14
length = sizeof(array_name)/sizeof(int);
Ответ 15
Хорошее решение, использующее дженерики:
template <typename T,unsigned S>
inline unsigned arraysize(const T (&v)[S]) { return S; }
Затем просто вызовите arraysize(_Array);
, чтобы получить длину массива.
Ответ 16
Для старого компилятора g++ вы можете сделать это
template <class T, size_t N>
char (&helper(T (&)[N]))[N];
#define arraysize(array) (sizeof(helper(array)))
int main() {
int a[10];
std::cout << arraysize(a) << std::endl;
return 0;
}
Ответ 17
Я предлагаю хитрое решение здесь:
Вы всегда можете сохранить length
в первом элементе:
// malloc/new
arr[0] = length;
arr++;
// do anything.
int len = *(arr-1);
free(--arr);
Стоимость вы должны --arr
когда вызываете free
Ответ 18
Вы можете найти длину массива следующим образом:
int arr[] = {1, 2, 3, 4, 5, 6};
int size = *(&arr + 1) - arr;
cout << "Number of elements in arr[] is "<< size;
return 0;
Ответ 19
Просто подумал, но просто решил создать переменную счетчика и сохранить размер массива в позиции [0]. Я удалил большую часть кода, который у меня был в функции, но вы увидите после выхода из цикла, prime [0] получает окончательное значение "a". Я пробовал использовать векторы, но VS Express 2013 не очень понравился. Также обратите внимание, что "a" начинается с одного, чтобы избежать перезаписи [0], и он инициализировался в начале, чтобы избежать ошибок. Я не эксперт, просто подумал, что поделюсь.
int prime[] = {0};
int primes(int x, int y){
using namespace std; int a = 1;
for (int i = x; i <= y; i++){prime[a] = i; a++; }
prime[0] = a; return 0;
}
Ответ 20
Одна из наиболее распространенных причин, по которой вам придется искать это, заключается в том, что вы хотите передать массив функции, а не передавать другой аргумент для его размера. Вы также хотели бы, чтобы размер массива был динамическим. Этот массив может содержать объекты, а не примитивы, и объекты могут быть сложными, так что size_of() является небезопасной опцией для вычисления количества.
Как уже предлагали другие, рассмотрите возможность использования std :: vector или list и т.д. Вместо примитивного массива. Однако на старых компиляторах у вас все еще не было бы окончательного решения, которое вы, вероятно, хотели бы сделать, просто делая это, потому что для заполнения контейнера требуется куча уродливых строк push_back(). Если вы похожи на меня, вам нужно однострочное решение с участием анонимных объектов.
Если вы используете контейнер STL, альтернативный примитивному массиву, этот пост SO может пригодиться вам для способов его инициализации: Каков самый простой способ инициализации std :: vector с жестко закодированными элементами?
Вот метод, который я использую для этого, который будет работать универсально на всех компиляторах и платформах:
Создайте структуру или класс в качестве контейнера для вашей коллекции объектов. Определить функцию перегрузки оператора для <<.
class MyObject;
struct MyObjectList
{
std::list<MyObject> objects;
MyObjectList& operator<<( const MyObject o )
{
objects.push_back( o );
return *this;
}
};
Вы можете создавать функции, которые принимают вашу структуру в качестве параметра, например:
someFunc( MyObjectList &objects );
Затем вы можете вызвать эту функцию, например так:
someFunc( MyObjectList() << MyObject(1) << MyObject(2) << MyObject(3) );
Таким образом, вы можете построить и передать динамически измеренную коллекцию объектов в функцию в одну чистую строку!
Ответ 21
Избегайте использования типа вместе с sizeof, поскольку sizeof(array)/sizeof(char)
, внезапно становится поврежденным, если вы изменяете тип массива.
В визуальной студии у вас есть эквивалентный if sizeof(array)/sizeof(*array)
.
Вы можете просто набрать _countof(array)
Ответ 22
Просто вы можете использовать этот фрагмент:
#include <iostream>
#include <string>
#include <array>
using namespace std;
int main()
{
array<int,3> values;
cout << "No. elements in valuea array: " << values.size() << " elements." << endl;
cout << "sizeof(myints): " << sizeof(values) << endl;
}
и вот ссылка: http://www.cplusplus.com/reference/array/array/size/
Ответ 23
У вас есть куча опций, которые будут использоваться для получения размера массива Си.
int myArray [] = {0, 1, 2, 3, 4, 5, 7};
1) sizeof(<array>)/sizeof(<type>):
std::cout << "Size:" << sizeof(myArray) / sizeof(int) << std::endl;
2) sizeof(<array>)/sizeof(*<array>):
std::cout << "Size:" << sizeof(myArray) / sizeof(*myArray) << std::endl;
3) sizeof(<array>)/sizeof(<array>[<element>]):
std::cout << "Size:" << sizeof(myArray) / sizeof(myArray[0]) << std::endl;
Ответ 24
Я лично предложил бы (если вы не можете работать со специализированными функциями по какой-либо причине), чтобы сначала расширить совместимость типов массивов с тем, что вы обычно использовали бы в нем (если вы сохраняли значения ≥ 0:
unsigned int x[] -> int x[]
чем вы сделаете элемент массива 1 больше, чем вам нужно. Для последнего элемента вы бы поместили некоторый тип, который включен в расширенный спецификатор типа, но который вы обычно не используете, например. используя предыдущий пример, последний элемент будет равен -1. Это позволяет вам (используя цикл for) найти последний элемент массива.
Ответ 25
Допустим, у вас есть глобальный массив, объявленный в верхней части страницы
int global[] = { 1, 2, 3, 4 };
Чтобы узнать, сколько элементов существует (в С++) в массиве, введите следующий код:
sizeof(global) / 4;
sizeof (NAME_OF_ARRAY)/4 вернет вам количество элементов для данного имени массива.