Как найти размер интервала []?

Я имею

int list[] = {1, 2, 3};

Как я получаю размер list?

Я знаю, что для массива символов, мы можем использовать strlen(array) найти размер или свериться '\0' в конце массива.


Я попробовал sizeof(array) / sizeof(array[0]) как некоторые сказанные ответы, но это только работает в основном? Например:

int size(int arr1[]){
    return sizeof(arr1) / sizeof(arr1[0]);
}

int main() {
    int list[] = {1, 2, 3};

    int size1 = sizeof(list) / sizeof(list[0]); // ok
    int size2 = size(list_1); // no
    // size1 and size2 are not the same
}

Почему?

43
задан cmaher 29 June 2018 в 22:21
поделиться

7 ответов

когда u передает какой-либо массив в какую-либо функцию. u передает только его стартовый адрес, поэтому для того, чтобы он работал, u передает и его размер, чтобы он работал корректно. это та же самая причина, по которой мы передаем argc с argv[] в аргументе командной строки.

1
ответ дан 26 November 2019 в 22:45
поделиться

Попробуйте:

sizeof(list) / sizeof(list[0]);

Поскольку этот вопрос помечен C ++, всегда рекомендуется использовать STD: : Вектор в C ++, а не используя обычные массивы C-стиля C.


тип тип массива неявно преобразуется в тип указателя , когда вы передаете его на функцию. Посмотрите на это.

Чтобы правильно распечатать размер массива внутри любой функции, пройдите массив посредством ссылки на эту функцию (но вам нужно знать размер этого массива).

Вы бы сделаете это так для общего случая

template<typename T,int N> 
//template argument deduction
int size(T (&arr1)[N]) //Passing the array by reference 
{
   return sizeof(arr1)/sizeof(arr1[0]); //Correctly returns the size of 'list'
   // or
   return N; //Correctly returns the size too [cool trick ;-)]
}
53
ответ дан 26 November 2019 в 22:45
поделиться

«Стандартный» способ сделать это

sizeof(list) / sizeof(list[0])
13
ответ дан 26 November 2019 в 22:45
поделиться

Вы можете использовать Boost :: Размер , который в основном определяется таким образом:

template <typename T, std::size_t N>
std::size_t size(T const (&)[N])
{
    return N;
}

Обратите внимание, что если вы хотите использовать размер в качестве постоянного выражения, вам придется использовать размер A / Sizeof A [0] IDIOM или ждать следующей версии стандарта C ++.

10
ответ дан 26 November 2019 в 22:45
поделиться

Вы не могут сделать это для динамически выделенного массива (или указателя). Для статических массивов вы можете использовать SizeOf (Array) , чтобы получить весь размер массива в байтах и ​​разделить его по размеру каждого элемента:

#define COUNTOF(x) (sizeof(x)/sizeof(*x))

, чтобы получить размер динамического массива, вы должны Отслеживайте его вручную и передайте его с ним, или завершите его сентинельным значением (например, «\ 0» в NULL Clins Clins).

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

std::vector<int> v;
v.push_back(1);
v.push_back(2);
std::cout << v.size() << std::endl; // prints 2
8
ответ дан 26 November 2019 в 22:45
поделиться

Помимо ответа Карла, «Стандартный» путь C ++ - не использовать массив C INT , но скорее что-то вроде C ++ STL STD :: Vector список , который Вы можете запросить список List.size () .

4
ответ дан 26 November 2019 в 22:45
поделиться

Я никогда не был в восторге от этого решения. Для одного, это не обязательно очевидно, где все такие методы в коде, для другого, я просто не люблю синтаксис. Я хочу использовать. когда я вызываю методы!

И я хочу использовать $! --- & при вызове методов! Разберись. Если вы собираетесь написать код C++, придерживайтесь условных обозначений C++. И очень важным соглашением C++ является предпочтение функций, не являющихся членами, когда это возможно.

Есть причина, по которой гуру C++ рекомендуют это:

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

Лично я не вижу точки в вашем коде. Разве это не намного проще, понятнее и короче?

string OperateOnString( float num, string a, string b )
{
    string nameS;
    Format(nameS, "%f-%s-%s", num, a.c_str(), b.c_str() );
    return nameS;
}

// or even better, if `Format` is made to return the string it creates, instead of taking it as a parameter
string OperateOnString( float num, string a, string b )
{
    return Format("%f-%s-%s", num, a.c_str(), b.c_str() );
}

Когда в Риме, делайте, как римляне, как говорится. Особенно , когда у римлян есть веские причины поступать так, как у них есть. И особенно когда ваш собственный способ сделать это на самом деле не имеет ни одного преимущества. Он более подвержен ошибкам, сбивает с толку людей, читающих ваш код, не является идиоматическим, и это просто больше строк кода, чтобы сделать то же самое.

Что касается вашей проблемы, трудно найти функции, не являющиеся членами, которые расширяют последовательности , поместите их в пространство имен, если это связано. Для этого они и нужны. Создайте пространство имен StringUtil или что-то подобное и поместите их туда.

-121--3765849-

Изменение ответа Фредди при использовании MVC - пришлось использовать:

HttpContext.User.Identity.Name

Незначительное изменение, но я подумал, что опубликую его в случае, если кто-то еще попытается сделать это в MVC попадет в ту же загвоздку.

-121--2890584-

Поскольку вы отметили это как C++, стоит отметить, что существует несколько лучший способ, чем макрос в стиле C:

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

Это имеет то преимущество, что если вы случайно попытаетесь передать ему что-то, кроме массива, код просто не будет компилироваться (тогда как передача указателя на макрос C будет компилировать, но создаст Недостаток заключается в том, что это не дает вам постоянной времени компиляции, поэтому вы не можете сделать что-то подобное:

int a[20];

char x[countof(a)];

В C++ 11 или более поздней версии можно добавить constexpr , чтобы получить константу времени компиляции:

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

Если вы действительно хотите поддерживать то же самое на старых компиляторах, есть способ, первоначально придуманный Иваном Джонсоном, AFAIK:

#define COUNTOF(x)  (                                           \
  0 * sizeof( reinterpret_cast<const ::Bad_arg_to_COUNTOF*>(x) ) +  \
  0 * sizeof( ::Bad_arg_to_COUNTOF::check_type((x), &(x))      ) +  \
  sizeof(x) / sizeof((x)[0])  )                                  


class Bad_arg_to_COUNTOF
{
public:
   class Is_pointer;
   class Is_array {};  
   template<typename T>
   static Is_pointer check_type(const T*, const T* const*);
   static Is_array check_type(const void*, const void*);
};

Используется значение sizeof (x )/sizeof (x [0]) для вычисления размера, как это делает макрос C, поэтому он дает постоянную времени компиляции. Разница в том, что сначала используется магия шаблона, чтобы вызвать ошибку компиляции, если переданное вами имя не является именем массива. Это происходит путем перегрузки check_type, чтобы вернуть неполный тип для указателя, но полный тип для массива. Затем (действительно сложная часть) она вообще не вызывает эту функцию - она просто принимает размер типа, который функция возвращает, который равен нулю для перегрузки, которая возвращает полный тип, но не допускается (принудительная ошибка компиляции) для неполного типа.

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

5
ответ дан 26 November 2019 в 22:45
поделиться
Другие вопросы по тегам:

Похожие вопросы: