Чи є спосіб знайти, скільки значень має масив? Визначення того, я дійшов до кінця масиву, також спрацює.
Чи є спосіб знайти, скільки значень має масив? Визначення того, я дійшов до кінця масиву, також спрацює.
Відповіді:
Якщо ви маєте на увазі масив у стилі С, то ви можете зробити щось на кшталт:
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);
У C ++, якщо ви хочете такого типу поведінки, тоді вам слід використовувати контейнерний клас; певно std::vector
.
Як говорили інші, ви можете використовувати, sizeof(arr)/sizeof(*arr)
але це дасть неправильну відповідь для типів вказівника, які не є масивами.
template<class T, size_t N>
constexpr size_t size(T (&)[N]) { return N; }
У цьому є приємна властивість неможливості компілювати для типів без масиву (це робить візуальна студія _countof
). Це constexpr
робить це виразом часу компіляції, щоб у нього не було недоліків щодо макросу (принаймні жодного я не знаю).
Ви також можете використовувати std::array
C ++ 11, який виставляє його довжину без накладних витрат над рідним масивом C.
std::size()
У <iterator>
заголовку C ++ 17 є те саме, що працює і для контейнерів STL (завдяки @Jon C ).
T(arg&)[N]
.
extent
, дивлячись на це, зараз у ньому є дві характеристики, які роблять його менш корисним, ніж функція вище (для цього випадку використання). (1) Він повертає нуль для покажчиків (а не помилки компіляції). (2) Для цього потрібен параметр типу, щоб перевірити змінну, яку вам доведеться зробитиdecltype
При sizeof( myArray )
цьому ви отримаєте загальну кількість байтів, виділених для цього масиву. Потім можна дізнатися кількість елементів у масиві, поділивши на розмір одного елемента в масиві:sizeof( myArray[0] )
Хоча це давнє запитання, варто оновити відповідь на C ++ 17. У стандартній бібліотеці тепер є функція шаблону std::size()
, яка повертає кількість елементів як в контейнері std, так і в масиві стилю C. Наприклад:
#include <iterator>
uint32_t data[] = {10, 20, 30, 40};
auto dataSize = std::size(data);
// dataSize == 4
Чи є спосіб знайти, скільки значень має масив?
Так!
Спробуйте sizeof(array)/sizeof(array[0])
Визначення того, я дійшов до кінця масиву, також спрацює.
Я не бачу для цього жодного способу, якщо ваш масив не є масивом символів (тобто рядком).
PS: У C ++ завжди використовуйте std::vector
. Є кілька вбудованих функцій та розширений функціонал.
std::vector
має метод, size()
який повертає кількість елементів у векторі.
(Так, це відповідь язиком у щоку)
#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;
}
Оскільки C ++ 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
, інакше тип є T
.
Щоб отримати довжину для будь-якого виміру багатовимірного масиву, 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;
}
Більше прикладів того, як їх використовувати, можна знайти за посиланнями.
Є також TR1 / C ++ 11 / C ++ 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
Замість використання вбудованої функції масиву aka:
int x[3] = {0, 1, 2};
ви повинні використовувати клас масиву та шаблон масиву. Спробуйте:
#include <array>
array<type_of_the_array, number_of_elements_in_the_array> Name_of_Array = {};
Отже, якщо ви хочете знайти довжину масиву, все, що вам потрібно зробити, - це використовувати функцію розміру в класі масиву.
Name_of_Array.size();
і це повинно повертати довжину елементів масиву.
У C ++, використовуючи клас 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 на C ++ std :: клас масиву
Посилання 2 на клас std :: масив
Приклади в посиланнях корисні.
Це досить старе і легендарне питання, і там вже є багато дивовижних відповідей. Але з часом з'являються нові функції до мов, тому нам потрібно продовжувати оновлювати речі відповідно до нових доступних функцій.
Я щойно помітив, що ще ніхто не згадував про C ++ 20. Тож думав написати відповідь.
У C ++ 20 в стандартну бібліотеку додається новий кращий спосіб пошуку довжини масиву, тобто std:ssize()
. Ця функція повертає a signed value
.
#include <iostream>
int main() {
int arr[] = {1, 2, 3};
std::cout << std::ssize(arr);
return 0;
}
У C ++ 17 був кращий спосіб (на той час) для того самого, який std::size()
визначено в iterator
.
#include <iostream>
#include <iterator> // required for std::size
int main(){
int arr[] = {1, 2, 3};
std::cout << "Size is " << std::size(arr);
return 0;
}
PS Цей метод також працює vector
.
Цей традиційний підхід вже згадується у багатьох інших відповідях.
#include <iostream>
int main() {
int array[] = { 1, 2, 3 };
std::cout << sizeof(array) / sizeof(array[0]);
return 0;
}
Просто FYI, якщо вам цікаво, чому такий підхід не працює, коли масив передається іншій функції . Причина в тому,
Масив не передається за значенням у C ++, натомість передається вказівник на масив. Як і в деяких випадках проходження цілих масивів може бути дорогою операцією. Ви можете перевірити це, передавши масив в якусь функцію і внести деякі зміни в масив, а потім знову надрукувати масив в основному. Ви отримаєте оновлені результати.
І як ви вже знали, sizeof()
функція дає кількість байтів, тому в іншій функції вона поверне кількість байтів, виділених для вказівника, а не для всього масиву. Тож такий підхід не працює.
Але я впевнений, що ви можете знайти хороший спосіб зробити це відповідно до вашої вимоги.
Щасливе кодування.
У вас є купа варіантів, які потрібно використовувати для отримання розміру масиву C.
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;
Ось одна реалізація 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 - це дійсно масив, і в цьому випадку результатом поділу є # елементів у масиві. Інакше arr не може бути масивом, і ми створюємо помилку компілятора, щоб запобігти компіляції коду.
Оскільки розмір bool визначається реалізацією, нам потрібно передати! (Sizeof (a) & sizeof (* (a))) на size_t, щоб забезпечити кінцевий результат типу size_t.
Цей макрос не є ідеальним, оскільки він помилково приймає певні вказівники, а саме там, де розмір вказівника ділиться на розмір pointee. Оскільки весь наш код повинен пройти через 32-розрядний компілятор, де вказівник становить 4 байти, це означає, що всі вказівники на тип, розмір якого становить 3 або більше 4, будуть (справедливо) відхилені.
int nombres[5] = { 9, 3 };
ця функція повертається 5
замість 2
.
Для C ++ / CX (під час написання, наприклад, програм UWP, що використовують C ++ у Visual Studio), ми можемо знайти кількість значень у масиві, просто скориставшись size()
функцією.
Вихідний код:
string myArray[] = { "Example1", "Example2", "Example3", "Example4" };
int size_of_array=size(myArray);
Якщо ви на виході буде:cout
size_of_array
>>> 4
sizeof(array_name)
надає розмір цілого масиву та sizeof(int)
надає розмір типу даних кожного елемента масиву.
Таким чином, ділення розміру всього масиву на розмір одного елемента масиву дає довжину масиву.
int array_name[] = {1, 2, 3, 4, 5, 6};
int length = sizeof(array_name)/sizeof(int);
ВІДПОВІДЬ :
int number_of_elements = sizeof(array)/sizeof(array[0])
ПОЯСНЕННЯ :
Оскільки компілятор відкладає певний розмір фрагмента пам'яті для кожного типу даних, а масив є просто групою таких, ви просто розділите розмір масиву на розмір типу даних. Якщо у мене є масив з 30 рядків, моя система виділяє 24 байти для кожного елемента (рядка) масиву. Що стосується 30 елементів, це загалом 720 байт. 720/24 == 30 елементів. Невеликий, жорсткий алгоритм для цього:
int number_of_elements = sizeof(array)/sizeof(array[0])
що прирівнюється до
number_of_elements = 720/24
Зауважте, що вам не потрібно знати, що таке тип масиву даних, навіть якщо це спеціальний тип даних.
Просто думка, але просто вирішив створити змінну лічильника і зберегти розмір масиву у позиції [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;
}
Гарне рішення, яке використовує дженерики:
template <typename T,unsigned S>
inline unsigned arraysize(const T (&v)[S]) { return S; }
Потім просто зателефонуйте, arraysize(_Array);
щоб отримати довжину масиву.
constexpr
- це виправлення. inline
не. constexpr
Хоча досить сучасний. Ви впевнені, що ваша тестова програма не використовує іншу сучасну функцію, де ви можете оголосити локальний масив, довжина якого задається змінною? Спробуйте це з двома глобальними масивами.
Для старого компілятора 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;
}
Я пропоную тут складне рішення:
Ви завжди можете зберігати length
в першому елементі:
// malloc/new
arr[0] = length;
arr++;
// do anything.
int len = *(arr-1);
free(--arr);
Вартість, яку ви маєте вимагати --arr
при викликуfree
arr
він сумісний із типом int
і масив не перевищує максимальне значення типу. Наприклад, рядки Pascal - це фактично масиви байтів, використовуючи цей трюк; максимальна довжина рядків у Pascal - 255 символів.
Ви можете знайти довжину масиву, виконавши:
int arr[] = {1, 2, 3, 4, 5, 6};
int size = *(&arr + 1) - arr;
cout << "Number of elements in arr[] is "<< size;
return 0;
Просто ви можете використовувати цей фрагмент:
#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/
Уникайте використання типу разом з sizeof, тому що sizeof(array)/sizeof(char)
раптом він пошкоджується, якщо змінити тип масиву.
У візуальній студії у вас є рівнозначний, якщо sizeof(array)/sizeof(*array)
. Ви можете просто ввести_countof(array)
Я особисто рекомендую (якщо ви не можете працювати зі спеціалізованими функціями з будь-якої причини) спершу розширити сумісність масивів минулого того, що ви зазвичай використовуєте як (якби ви зберігали значення ≥ 0:
unsigned int x[] -> int x[]
ніж ви зробите елемент масиву 1 більшим, ніж потрібно для його створення. Для останнього елемента ви б помістили якийсь тип, який включений у специфікатор розширеного типу, але який ви зазвичай не використовуєте, наприклад, використовуючи попередній приклад, останній елемент буде -1. Це дозволяє (за допомогою циклу for) знайти останній елемент масиву.
Однією з найпоширеніших причин, через яку ви шукаєте це, є те, що ви хочете передати масив функції, а не потрібно передавати інший аргумент за його розмір. Ви також хочете, щоб розмір масиву був динамічним. Цей масив може містити об'єкти, а не примітиви, а об'єкти можуть бути складними таким, що size_of () є не безпечним варіантом обчислення кількості.
Як запропонували інші, розгляньте можливість використання std :: vector чи списку тощо замість примітивного масиву. Однак у старих компіляторах ви все одно не матимете остаточного рішення, яке, мабуть, хочете, зробивши просто це, оскільки для заповнення контейнера потрібна купа некрасивих рядків 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) );
Таким чином, ви можете створити та передати динамічно розмірну колекцію об'єктів функції в одну єдину чисту лінію!
Скажімо, у вас є глобальний масив, оголошений вгорі сторінки
int global[] = { 1, 2, 3, 4 };
Щоб дізнатись, скільки елементів у масиві є (в c ++), введіть наступний код:
sizeof(global) / 4;
Sizeof (NAME_OF_ARRAY) / 4 поверне вам кількість елементів для даного імені масиву.