Подтвердить что ты не робот

Как найти длину массива?

Есть ли способ узнать, сколько значений имеет массив? Обнаружение того, достигло ли я конца массива, также будет работать.

4b9b3361

Ответ 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>.

  • std::rank<T>::value

    Если T является типом массива, он предоставляет значение константы элемента, равное количеству измерений массива. Для любого другого типа значение равно 0.

  • std::extent<T, N>::value

    Если T является типом массива, он предоставляет значение константы элемента, равное количеству элементов в N -м измерении массива, если N находится в [0, std::rank<T>::value). Для любого другого типа или если T - это массив неизвестных границ по его первому размеру, а N - 0, значение равно 0.

  • std::remove_extent<T>::type

    Если T - это массив некоторого типа X, он предоставляет тип typedef-члена, равный X, в противном случае тип T. Обратите внимание, что если T - многомерный массив, удаляется только первое измерение.

  • std::remove_all_extents<T>::type

    Если T является многомерным массивом какого-либо типа X, он предоставляет тип typedef-члена, равный X, иначе type is 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;
}

Дополнительные примеры того, как их использовать, можно найти, следуя ссылкам.

Ответ 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 вернет вам количество элементов для данного имени массива.