определить размер массива, если он передан функции - PullRequest
33 голосов
/ 09 июня 2009

Можно ли определить размер массива, если он был передан другой функции (размер не передан)? Массив инициализируется как массив int [] = {XXX} ..

Я понимаю, что невозможно выполнить sizeof, поскольку он вернет размер указателя. Причина, по которой я спрашиваю, заключается в том, что мне нужно запустить цикл for внутри другой функции, где передается массив. Я пробовал что-то вроде:

for( int i = 0; array[i] != NULL; i++) {
........
}

Но я заметил, что в ближнем конце массива массив [i] иногда содержит значения мусора, например 758433, что не является значением, указанным при инициализации массива ..

Ответы [ 8 ]

48 голосов
/ 09 июня 2009

Другие ответы упускают из виду одну особенность c ++. Вы можете передавать массивы по ссылке и использовать шаблоны:

template <typename T, int N>
void func(T (&a) [N]) {
    for (int i = 0; i < N; ++i) a[i] = T(); // reset all elements
}

тогда вы можете сделать это:

int x[10];
func(x);

но обратите внимание, это работает только для массивов , а не указателей.

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

13 голосов
/ 09 июня 2009

Если это под вашим контролем, используйте вместо массива контейнер STL, такой как вектор или deque.

9 голосов
/ 09 июня 2009

Нет, это невозможно.

Один обходной путь: поместите специальное значение в последнее значение массива, чтобы вы могли его распознать.

6 голосов
/ 09 июня 2009

Одним из очевидных решений является использование STL. Если это не возможно, лучше передать длину массива явно. Я скептически отношусь к использованию трюка с ценностью для этого конкретного случая. Оно работает лучше с массивами указателей, потому что NULL - хорошее значение для часового. С массив целых чисел, это не так просто - нужно иметь «магическое» значение дозорного, которое не хорошо.

Примечание: если ваш массив определен и инициализирован как

 int array[] = { X, Y, Z };

в том же объеме, что и ваш цикл, тогда

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

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

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

4 голосов
/ 22 июля 2013

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

#include<iostream>
using namespace std;

int howBigIsBareArray(int arr[]){
    int counter = 0;
    while (arr[counter] != NULL){
        counter++;
    }
    return counter;
}
int main(){
    int a1[6] = {1,2,3,4,5,'\0'};
    cout << "SizeOfMyArray: " << howBigIsBareArray(a1);
}

Эта программа печатает:

SizeOfMyArray: 5

Это операция O (n) сложности времени, которая является плохой. Вы никогда не должны проходить через массив только для того, чтобы узнать его размер.

3 голосов
/ 09 июня 2009

Если вы не можете передать размер, вам нужно различимое значение sentinel в конце (и вам нужно поместить его туда самостоятельно - как вы обнаружили, вы не можете доверять C ++, чтобы сделать это автоматически для вас!). Невозможно просто вызвать вызываемую функцию волшебным образом, чтобы определить ее размер, если она не передана и не используется явный и надежный страж.

1 голос
/ 09 июня 2009

Можете ли вы добавить нулевой символ \0 в массив и затем отправить его? Таким образом, вы можете просто проверить \ 0 в цикле.

0 голосов
/ 04 января 2014

На самом деле список Чаков

для (int i = 0; массив [i]! = NULL; i ++) { ........ }

Размер перед каждым звонком расточителен и необходим, чтобы знать, что вы получаете.

Прекрасно работает, если вы ставите NULL в конце массивов.

Почему ?? Во встроенных проектах передача sizeof в каждой подпрограмме делает каждый вызов очень большим по сравнению с NULL для каждого массива. У меня чип 2K PIC16F684, и он занимает до 10 процентов чипа с 12 вызовами, используя переданный размер вместе с массивом. Только с массивом и кодом Чака с NULLS для каждого массива ... Мне нужно 4 процента.

Истинный пример. Спасибо, Чак, хороший звонок.

...