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

Количество элементов массива в С++

Скажем, у меня есть массив arr. Когда следующее не даст количество элементов массива: sizeof(arr) / sizeof(arr[0])?

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

Я прав, и там (я почти уверен, что должны быть) другие такие случаи?

Извините за тривиальный вопрос, я разработчик Java, и я довольно новичок в С++.

Спасибо!

4b9b3361

Ответ 1

Скажем, у меня есть массив arr. когда будет ли следующее количество элементов массива: sizeof (arr)/sizeof (arr [0])?

Одна вещь, которую я часто видел, когда это делают новые программисты:

void f(Sample *arr)
{
   int count = sizeof(arr)/sizeof(arr[0]); //what would be count? 10?
}

Sample arr[10];
f(arr);

Итак, новые программисты считают, что значение count будет 10. Но это неправильно.

Даже это неверно:

void g(Sample arr[]) //even more deceptive form!
{
   int count = sizeof(arr)/sizeof(arr[0]); //count would not be 10  
}

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


EDIT:

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

template<size_t N>
void h(Sample (&arr)[N])
{
    size_t count = N; //N is 10, so would be count!
    //you can even do this now:
    //size_t count = sizeof(arr)/sizeof(arr[0]);  it'll return 10!
}
Sample arr[10];
h(arr); //pass : same as before!

Ответ 2

Массивы на С++ сильно отличаются от массивов на Java, поскольку они полностью неуправляемы. Компилятор или время выполнения не имеют представления о том, какой размер массива.

Информация известна только во время компиляции, если размер определяется в объявлении:

char array[256];

В этом случае sizeof (array) дает вам правильный размер.

Если вы используете указатель как массив, то "array" будет просто указателем, а sizeof не даст вам никакой информации о фактическом размере массива.

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

Ответ 3

Нет случаев, когда массив arr, если значение sizeof(arr) / sizeof(arr[0]) не является числом элементов, по определению массива и sizeof.

Фактически, он даже прямо упоминается (§5.3.3/2):

.... При применении к массиву результатом является общее количество байтов в массиве. Это означает, что размер массива из n элементов в n раз превышает размер элемента.

Акцент мой. Разделите размер элемента, sizeof(arr[0]), чтобы получить n.

Ответ 4

Нет, это все равно даст правильное значение, потому что вы должны определить массив как все элементы одного типа или указатели на тип. В любом случае размер массива известен во время компиляции, поэтому sizeof (arr)/sizeof (arr [0]) всегда возвращает счетчик элементов.

Вот пример правильного использования:

int nonDynamicArray[ 4 ];

#define nonDynamicArrayElementCount ( sizeof(nonDynamicArray) / sizeof(nonDynamicArray[ 0 ]) )

Далее я расскажу, когда использовать это правильно. Вы не будете использовать его очень часто. Это в первую очередь полезно, когда вы хотите определить массив специально, чтобы вы могли добавлять к нему элементы, не изменяя при этом много кода. Это конструкция, которая в первую очередь полезна для обслуживания. Канонический пример (когда я думаю об этом в любом случае;-) строит таблицу команд для некоторой программы, которую вы намерены добавить позже. В этом примере для поддержания/улучшения вашей программы все, что вам нужно сделать, это добавить еще одну команду в массив, а затем добавить обработчик команд:

char        *commands[] = {  // <--- note intentional lack of explicit array size
    "open",
    "close",
    "abort",
    "crash"
};

#define kCommandsCount  ( sizeof(commands) / sizeof(commands[ 0 ]) )

void processCommand( char *command ) {
    int i;

    for ( i = 0; i < kCommandsCount; ++i ) {
        // if command == commands[ i ] do something (be sure to compare full string)
    }
}

Ответ 5

Во-первых, вы можете обойти эту проблему, используя std::vector вместо массива. Во-вторых, если вы поместите объекты производного класса в массив суперкласса, вы испытаете нарезку, но хорошая новость заключается в том, что ваша формула будет работать. Полиморфные коллекции в С++ достигаются с помощью указателей. Здесь есть три основных варианта:

Ответ 6

Скажем, у меня есть массив arr. Когда следующее не даст количество элементов массива: sizeof(arr) / sizeof(arr[0])?

В контекстах, где arr на самом деле не массив (но вместо этого указатель на исходный элемент). Другие ответы объясняют, как это происходит.

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

Этого не может произойти (по сути, по той же причине, что Java-массивы не очень хорошо сочетаются с дженериками). Массив статически типизирован; он резервирует "слоты" памяти, которые имеют размер для определенного типа (базовый тип).

Извините за тривиальный вопрос, я разработчик Java, и я довольно новичок в С++.

Массивы С++ не являются первоклассными объектами. Вы можете использовать boost:: array, чтобы заставить их вести себя скорее как массивы Java, но имейте в виду, что у вас все еще будет семантика значений, а не ссылочная семантика, как и все остальное. (В частности, это означает, что вы не можете действительно объявить переменную типа, аналогичную Foo[] в Java, и не заменять массив другим другим размером, размер массива является частью этого типа.) Используйте .size() с этим классом, где вы бы использовали .length в Java. (Он также предоставляет итераторы, которые обеспечивают обычный интерфейс для итераторов С++.)

Ответ 7

Используйте макрос Microsoft "_countof (массив)". Эта ссылка на Сеть разработчиков Microsoft объясняет это и предлагает пример, демонстрирующий разницу между "sizeof (array)" и макросом "_countof (array)".

Microsoft и "_countof (array)" Macro

Ответ 8

_countof (my_array) в MSVC

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

Элементы массива в С++ являются объектами, а не указателями, поэтому вы не можете иметь объект производного типа как элемент.

И как уже упоминалось выше, sizeof (my_array) (например, _countof()) будет работать только в области определения массива.

Ответ 9

/* Я не совсем уверен, что понял вопрос, но вот что я понял. У вас есть массив с элементами, и вы хотите узнать, сколько элементов в массиве? Вот что я сделал *

int myArray [] = {B00011101, B00011011}//два элемента в массиве int Elements; // переменная, в которой мы будем хранить количество элементов в данном массиве

пустая функция(){

/* Elements = sizeof (myArray); Это дало мне результат 4, поэтому я подумал, что, возможно, мне нужно разделить его на 2, поэтому я ввел еще один элемент в массив, чтобы у меня было 3 элемента "int myArray [] = {B00011101, B00011011, B00011011}" и переменная If. Элементы дает мне номер 6, мое решение будет работать, и оно действительно показало мне номер 6, что означало, что количество элементов по некоторым причинам умножено на 2, так что в основном я сделал, я разделил его на 2 *

Elements = sizeof (myArray)/2;/* также я делал это в компиляторе arduino, не уверен, работает ли он в обычном компиляторе c++, но он должен работать. */

}

Ответ 10

Я знаю старую тему, но как насчет простого решения вроде цикла while?

int function count(array[]) {

    int i = 0;

    while(array[i] != NULL) {

        i++;

    }

    return i;

}

Я знаю, что это медленнее, чем sizeof(), но это еще один пример подсчета массива.