Вычислить длину массива в 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] ) )

Это, конечно, со всеми обычными оговорками макросов.

Изменить: (комментарии ниже действительно принадлежат ответу...)

  1. Вы не можете определить количество элементов, инициализированных в массиве, если вы сначала не инициализируете все элементы "недопустимым" значением и не выполните подсчет "допустимых" значений вручную. Если ваш массив был определен как имеющий 8 элементов, для компилятора он имеет 8 элементов, независимо от того, инициализированы ли вы только 5 из них.
  2. Вы не можете определить размер массива внутри функции, которой этот массив был передан в качестве параметра. Не напрямую, не через макрос, никоим образом. Можно только определить размер массива в объеме было объявлено в.

Невозможность определить размер массива в вызываемой функции можно понять, когда вы поймете, что 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));