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

Как найти количество элементов в массиве?

У меня есть массив int, и мне нужно найти количество элементов в нем. Я знаю, что это имеет какое-то отношение к sizeof, но я не уверен, как его использовать.

4b9b3361

Ответ 1

Если у вас есть массив в области видимости, вы можете использовать sizeof для определения его размера в байтах и ​​использовать деление для вычисления количества элементов:

#define NUM_OF_ELEMS 10
int arr[NUM_OF_ELEMS];
size_t NumberOfElements = sizeof(arr)/sizeof(arr[0]);

Если вы получаете массив как аргумент функции или выделяете массив в кучу, вы не можете определить его размер с помощью sizeof. Вам нужно будет как можно скорее сохранить/передать информацию о размере, чтобы использовать его:

void DoSomethingWithArray(int* arr, int NumOfElems)
{
    for(int i = 0; i < NumOfElems; ++i) {
        arr[i] = /*...*/
    }
}

Ответ 2

int a[20];
int length;
length = sizeof(a) / sizeof(int);

и вы можете использовать другой способ, чтобы ваш код не был жестко закодирован до int

Скажем, если у вас есть массив array

вам просто нужно:

int len = sizeof(array) / sizeof(array[0]);

Ответ 3

Я лично считаю, что sizeof (a)/sizeof (* a) выглядит более чистым.

Я также предпочитаю определять его как макрос:

#define NUM(a) (sizeof(a) / sizeof(*a))

Затем вы можете использовать его для for-loops, таким образом:

for (i = 0; i < NUM(a); i++)

Ответ 4

Невозможно найти количество элементов в массиве, если это не массив символов. Рассмотрим приведенный ниже пример:

int main()
{
    int arr[100]={1,2,3,4,5};
    int size = sizeof(arr)/sizeof(arr[0]);
    printf("%d", &size);
    return 1;
}

Вышеприведенное значение дает нам значение 100, даже если число элементов равно пяти. Если это массив символов, вы можете искать линейно для нулевой строки в конце массива и увеличивать счетчик при прохождении.

Ответ 5

Я использовал следующий код, как было предложено выше, для оценки количества элементов в моем двумерном массиве:

#include <stdio.h>
#include <string.h>

void main(void)
{
    char strs[3][20] =
    {
        {"January"},
        {"February"},
        {""}
    };

    int arraysize = sizeof(strs)/sizeof(strs[0]);

    for (int i = 0; i < arraysize; i++)
    {
        printf("Month %d is: %s\n", i, strs[i]);
    }

}

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

  • количество байтов с функцией sizeof() из всего массива 2d (в этом случае 3 * 20 = 60 байт)
  • подсчитать количество байтов с функцией sizeof() из первого элемента массива strs [0] (в данном случае 20 байт)
  • разделите весь размер с размером одного элемента, что даст вам количество элементов

Этот снимок должен быть переносимым для 2d-массивов в C, однако на других языках программирования он не может работать, потому что вы можете использовать разные типы данных в массиве с разными размерами (например, в JAVA).

Ответ 6

#include<stdio.h>
int main()
{
    int arr[]={10,20,30,40,50,60};
    int *p;
    int count=0;

    for(p=arr;p<&arr+1;p++)
        count++;

    printf("The no of elements in array=%d",count);

    return 0;
}

ВЫХОД = 6

ОБЪЯСНЕНИЕ

p является указателем на одномерный массив, а в цикле for(p=arr,p<&arr+1;p++) Я сделал p указать на базовый адрес. Предположим, что его базовый адрес равен 1000; если мы увеличиваем p, то он указывает на 1002 и так далее. Теперь переход к понятию &arr - он в основном представляет весь массив, и если мы добавим 1 ко всему массиву, то есть &arr+1, он даст адрес 1012, то есть адрес следующего массива 1-D (в нашем случае размер int равен 2), поэтому условие становится 1000 < 1012.

Итак, в основном условие становится

for(p=1000;p<1012;p++)

Теперь давайте проверим условие и подсчитаем значение

  • 1-й раз p=1000 и p<1012 условие true: введите в цикл, увеличьте значение count до 1.
  • 2-й раз p=1002 и p<1012 условие true: введите в цикл, увеличьте значение count до 2.
  • ...
  • 6-й раз p=1010 и p<1012 условие true: введите в цикле, увеличьте значение count до 6.
  • Последнее время p=1012 и p<1012 условие false: напечатайте значение count=6 в printf.

Ответ 7

Если мы не знаем количество элементов в массиве и когда ввод дается пользователем во время выполнения. Тогда мы можем написать код как

C-код:

while(scanf("%d",&array[count])==1) { 
  count++;
}

C++ КОД:

while(cin>>a[count]) {
  count++;
}

Теперь счет будет иметь количество введенных элементов массива.

Ответ 8

Супер просто.

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

Например, заданный целочисленный массив myArray

int numArrElements = sizeof(myArray) / sizeof(int);

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

Например

int numArrElements = sizeof(myArray) / sizeof(myArray[0]);

Ответ 9

sizeof возвращает размер в байтах этого аргумента. Это не то, что вы хотите, но это может помочь.

Допустим, у вас есть массив:

int array[4];

Если применить sizeof к массиву (sizeof(array)), он будет возвращать его размер в байтах, который в данном случае 4 * размер в int, поэтому в общей сложности, может быть 16 байт ( в зависимости от реализации).

Если применить sizeof к элементу массива (sizeof(array[0])), он будет возвращать его размер в байтах, который в данном случае является размером с int, так что в общей сложности может быть, 4 байта ( в зависимости от вашего реализация).

Если вы разделите первое на второе, оно будет: (4 * размер int)/(размер int) = 4; Это именно то, что вы хотели.

Так что это должно сделать:

sizeof(array) / sizeof(array[0])

Теперь вы, вероятно, хотели бы иметь макрос для инкапсуляции этой логики, и вам больше никогда не придется думать, как это сделать:

#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))

Вам нужны круглые скобки, заключающие в себе весь макрос, как и в любом другом сложном макросе, а также в каждую переменную, чтобы избежать неожиданных ошибок, связанных с приоритетом операторов.

Теперь вы можете использовать его в любом массиве, например так:

int array[6];
ptrdiff_t nmemb;

nmemb = ARRAY_SIZE(array);
/* nmemb == 6 */

Помните, что аргументы функций, объявленных как массивы, на самом деле не являются массивами, а указателями на первый элемент массива, так что это НЕ будет работать с ними:

void foo(int false_array[6])
{
        ptrdiff_t nmemb;

        nmemb = ARRAY_SIZE(false_array);
        /* nmemb == sizeof(int *) / sizeof(int) */
        /* (maybe  ==2) */
}

Но это может использоваться в функциях, если вы передаете указатель на массив, а не только на массив:

void bar(int (*arrptr)[7])
{
        ptrdiff_t nmemb;

        nmemb = ARRAY_SIZE(*arrptr);
        /* nmemb == 7 */
}

Ответ 10

В основном я нашел простой способ выполнить длину массива внутри цикла точно так же, как

 int array[] = {10, 20, 30, 40};
 int i;
 for (i = 0; i < array[i]; i++) {
    printf("%d\n", array[i]);
 }

Ответ 11

Вопрос прост: учитывая массив C++ (например, x как в int x[10]), как бы вы получили количество элементов в нем?

Очевидным решением является следующий макрос (определение 1):

#define countof( array ) ( sizeof( array )/sizeof( array[0] ) )

Я не могу сказать, что это не правильно, потому что он дает правильный ответ, когда вы даете ему массив. Однако то же выражение дает вам что-то поддельное, когда вы предоставляете что-то, что не является массивом. Например, если у вас есть

int * p;

тогда countof( p ) всегда дает вам 1 на машине, где указатель int и int имеют одинаковый размер (например, на платформе Win32).

Этот макрос также ошибочно принимает любой объект класса, который имеет оператор-функцию-член []. Например, предположим, вы пишете

class IntArray {
private:
    int * p;
    size_t size;
public:
    int & operator [] ( size_t i );
} x;

тогда sizeof( x ) будет размером объекта x, а не размером буфера, на который указывает xp. Поэтому вы не получите правильный ответ по countof( x ).

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

Какой вариант лучше?

Что ж, если мы хотим, чтобы компилятор гарантировал, что параметр countof всегда является массивом, мы должны найти контекст, в котором разрешен только массив. Тот же контекст должен отклонять любое выражение, не являющееся массивом.

Некоторые новички могут попробовать это (определение 2):

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

Они полагают, что эта шаблонная функция примет массив из N элементов и вернет N.

К сожалению, это не компилируется, потому что C++ обрабатывает параметр массива так же, как параметр указателя, т.е. приведенное выше определение эквивалентно:

template <typename T, size_t N>
size_t countof( T * array )
{
    return N;
}

Теперь становится очевидным, что тело функции не может знать, что такое N.

Однако, если функция ожидает ссылку на массив, тогда компилятор удостоверяется, что размер фактического параметра соответствует объявлению. Это означает, что мы можем заставить определение 2 работать с незначительной модификацией (определение 3):

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

Это количество работает очень хорошо, и вы не можете обмануть его, указав ему указатель. Однако это функция, а не макрос. Это означает, что вы не можете использовать его там, где ожидается постоянная времени компиляции. В частности, вы не можете написать что-то вроде:

int x[10];

int y[ 2*countof(x) ]; // twice as big as x

Можем ли мы что-нибудь с этим сделать?

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

Чтобы быть точным, мы должны заставить функцию возвращать ссылку на массив, так как C++ не позволяет вам возвращать массив напрямую.

Реализация этого:

template <typename T, size_t N>
char ( &_ArraySizeHelper( T (&array)[N] ))[N];

#define countof( array ) (sizeof( _ArraySizeHelper( array ) ))

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

Во-первых, вещи верхнего уровня

char ( &_ArraySizeHelper( ... ))[N];

говорит, что _ArraySizeHelper - это функция, которая возвращает ссылку (обратите внимание на &) на массив символов из N элементов.

Далее, параметр функции

T (&array)[N]

который является ссылкой на массив из N элементов.

Наконец, countof определяется как размер результата функции _ArraySizeHelper. Обратите внимание, что нам даже не нужно определять _ArraySizeHelper(), - достаточно объявления.

С этим новым определением

int x[10];

int y[ 2*countof(x) ]; // twice as big as x

становится действительным, так как мы желаем.

Я счастлив сейчас? Ну, я думаю, что это определение определенно лучше, чем другие, которые мы посетили, но это все еще не совсем то, что я хочу. С одной стороны, он не работает с типами, определенными внутри функции. Это потому, что функция шаблона _ArraySizeHelper ожидает тип, который доступен в глобальной области видимости.

У меня нет лучшего решения. Если вы знаете, пожалуйста, дайте мне знать.

Ответ 12

template <typename Type, int N>
inline int getElementCount(Type (&array)[N])
{
    (void)array; // (required to avoid a spurious warning in MS compilers)
    (void)sizeof(0[array]); // This line should cause an error if you pass an object with a user-defined subscript operator
    return N;
}

Ответ 13

На самом деле, нет правильного способа подсчета элементов в динамическом целочисленном массиве. Тем не менее, команда sizeof работает правильно в Linux, но не работает в Windows. С точки зрения программиста, не рекомендуется использовать sizeof для определения количества элементов в динамическом массиве. Мы должны отслеживать количество элементов при создании массива.