Вычислить длину массива в C с помощью функции
Я хочу сделать FUNCTION, который вычисляет размер переданного массива.
Я передам массив в качестве входных данных, и он должен вернуть его длину. Я хочу функцию
int ArraySize(int * Array /* Or int Array[] */)
{
/* Calculate Length of Array and Return it */
}
void main()
{
int MyArray[8]={1,2,3,0,5};
int length;
length=ArraySize(MyArray);
printf("Size of Array: %d",length);
}
Длина должна быть 5, поскольку она содержит 5 элементов, хотя размер 8
(Даже 8 будет делать, но 5 будет отлично)
Я пробовал это:
int ArraySize(int * Array)
{
return (sizeof(Array)/sizeof(int));
}
Это не будет работать, так как "sizeof(Array)
" будет перенастроить размер Int Pointer.
Это "sizeof
" работает только в том случае, если вы находитесь в одной и той же функции.
На самом деле я вернулся к C после нескольких дней с С#. Поэтому я не могу вспомнить (и Missing Array.Length()
)
Привет!
Ответы
Ответ 1
Вы не можете вычислить размер массива, когда у вас есть только указатель.
Единственный способ сделать это "подобным функции" - это определить макрос:
#define ARRAY_SIZE( array ) ( sizeof( array ) / sizeof( array[0] ) )
Это, конечно, со всеми обычными оговорками макросов.
Изменить: (комментарии ниже действительно принадлежат ответу...)
- Вы не можете определить количество элементов, инициализированных в массиве, если вы сначала не инициализируете все элементы "недопустимым" значением и не выполните подсчет "допустимых" значений вручную. Если ваш массив был определен как имеющий 8 элементов, для компилятора он имеет 8 элементов, независимо от того, инициализированы ли вы только 5 из них.
- Вы не можете определить размер массива внутри функции, которой этот массив был передан в качестве параметра. Не напрямую, не через макрос, никоим образом. Можно только определить размер массива в объеме было объявлено в.
Невозможность определить размер массива в вызываемой функции можно понять, когда вы поймете, что sizeof()
является оператором времени компиляции. Это может выглядеть как вызов функции времени выполнения, но это не так: компилятор определяет размер операндов и вставляет их как константы.
В области действия объявлен массив, у компилятора есть информация о том, что это на самом деле массив, и сколько у него элементов.
В функции, в которую передается массив, компилятор видит только указатель. (Учтите, что функция может вызываться со многими различными массивами, и помните, что sizeof()
является оператором времени компиляции.
Вы можете переключиться на C++ и использовать <vector>
. Вы можете определить struct vector
плюс функции, обрабатывающие это, но это не очень удобно:
#include <stdlib.h>
typedef struct
{
int * _data;
size_t _size;
} int_vector;
int_vector * create_int_vector( size_t size )
{
int_vector * _vec = malloc( sizeof( int_vector ) );
if ( _vec != NULL )
{
_vec._size = size;
_vec._data = (int *)malloc( size * sizeof( int ) );
}
return _vec;
}
void destroy_int_vector( int_vector * _vec )
{
free( _vec->_data );
free( _vec );
}
int main()
{
int_vector * myVector = create_int_vector( 8 );
if ( myVector != NULL && myVector->_data != NULL )
{
myVector->_data[0] = ...;
destroy_int_vector( myVector );
}
else if ( myVector != NULL )
{
free( myVector );
}
return 0;
}
Итог: C массивы ограничены. Вы не можете рассчитать их длину в подфункции, точка. Вы должны обойти это ограничение или использовать другой язык (например, C++).
Ответ 2
Вы не можете сделать это, как только массив разложится на указатель - вы всегда получите размер указателя.
Что вам нужно сделать, либо:
- если возможно, используйте значение контрольной суммы, например NULL для указателей или -1 для положительных чисел.
- вычислить его, когда он все еще является массивом, и передать этот размер любым функциям.
- то же самое, что и выше, но с использованием фанковой макромагии, что-то вроде:
#define arrSz(a) (sizeof(a)/sizeof(*a))
.
- создайте свой собственный абстрактный тип данных, который поддерживает длину как элемент в структуре, так что у вас есть способ получить ваш
Array.length()
.
Ответ 3
То, о чем вы просите, просто не может быть сделано.
Во время выполнения единственной информацией, доступной программе о массиве, является адрес ее первого элемента. Даже размер элементов определяется только из контекста типа, в котором используется массив.
Ответ 4
В C вы не можете, потому что массив распадается на указатель (на первый элемент) при передаче функции.
Однако в С++ вы можете использовать Депозицию аргументов шаблона для достижения того же.
Ответ 5
Вам нужно либо передать длину в качестве дополнительного параметра (например, strncpy
), либо обнулить конец массива (например, strcpy
).
Небольшие вариации этих методов существуют, например, связывание длины с указателем в своем классе или использование другого маркера для длины массива, но это в основном ваш единственный выбор.
Ответ 6
int getArraySize(void *x)
{
char *p = (char *)x;
char i = 0;
char dynamic_char = 0xfd;
char static_char = 0xcc;
while(1)
{
if(p[i]==dynamic_char || p[i]==static_char)
break;
i++;
}
return i;
}
int _tmain(int argc, _TCHAR* argv[])
{
void *ptr = NULL;
int array[]={1,2,3,4,5,6,7,8,9,0};
char *str;
int totalBytes;
ptr = (char *)malloc(sizeof(int)*3);
str = (char *)malloc(10);
totalBytes = getArraySize(ptr);
printf("ptr = total bytes = %d and allocated count = %d\n",totalBytes,(totalBytes/sizeof(int)));
totalBytes = getArraySize(array);
printf("array = total bytes = %d and allocated count = %d\n",totalBytes,(totalBytes/sizeof(int)));
totalBytes = getArraySize(str);
printf("str = total bytes = %d and allocated count = %d\n",totalBytes,(totalBytes/sizeof(char)));
return 0;
}
Ответ 7
Уже очень поздно. Но я нашел решение этой проблемы. Я знаю, что это не правильное решение, но может работать, если вы не хотите проходить целую цепочку целых чисел.
проверка '\ 0' не будет работать здесь
Сначала поместите любой символ в массив во время инициализации
for(i=0;i<1000;i++)
array[i]='x';
то после прохождения значений проверьте 'x'
i=0;
while(array[i]!='x')
{
i++;
return i;
}
сообщите мне, если это будет полезно.
Ответ 8
Невозможно. Вам нужно передать размер массива из функции, из которой вы вызываете эту функцию. Когда вы передаете массив в функцию, передается только начальный адрес, а не весь размер, и когда вы вычисляете размер массива, компилятор не знает, сколько размера/памяти, этот указатель был выделен компилятором. Итак, последний вызов - вам нужно передать размер массива во время вызова этой функции.
Ответ 9
Чтобы определить размер вашего массива в байтах, вы можете использовать оператор sizeof
:
int a[<any size>];
int n = sizeof(a);
Чтобы определить количество элементов в массиве, мы можем разделить общий размер массива на размер элемента массива. Вы можете сделать это с типом, например:
int a[<total size>];
int n = sizeof(a) / sizeof(int);
ПРИМЕЧАНИЕ. Введите требуемый размер в скобках angular.
Ответ 10
Размер arry в C:
int a[]={10,2,22,31,1,2,44,21,5,8};
printf("Size : %d",sizeof(a)/sizeof(int));