用函数计算C中的数组长度

时间:2010-11-12 08:51:52

标签: c arrays

我想制作一个计算传递数组大小的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指针的大小。 只有当你处于相同的功能时,这个“sizeof”才有效。

实际上我从C#开始很多天后回到C所以我不记得了(并且错过了Array.Length()

问候!

9 个答案:

答案 0 :(得分:27)

当你得到的只是指针时,你无法计算数组的大小。

使这个“类似函数”的唯一方法是定义一个宏:

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

当然,这包含所有常见的宏注意事项。

编辑(以下评论真的属于答案......)

  1. 无法确定数组中已初始化的元素数量,除非您首先将所有元素初始化为“无效”值并对“有效”值进行计数手动。如果你的数组被定义为有8个元素,那么对于编译器,它有8个元素,无论你是否只初始化了5个元素。
  2. 无法确定该数组作为参数传递到的函数中的数组大小。不是直接的,不是通过宏,不是以任何方式。您可以 确定中声明的范围中的数组的大小。
  3. 一旦您意识到 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 ++)。

答案 1 :(得分:11)

一旦数组衰减为指针,就无法执行此操作 - 您将始终获得指针大小。

您需要做的是:

  • 尽可能使用sentinel值,如指针为NULL或正数为-1。
  • 当它仍然是一个数组时计算它,并将该大小传递给任何函数。
  • 与上述相同,但使用时髦的宏魔法,例如:
    #define arrSz(a) (sizeof(a)/sizeof(*a))
  • 创建您自己的抽象数据类型,该类型将长度保持为结构中的项目,这样您就可以 获取Array.length()

答案 2 :(得分:2)

你要求的东西根本无法做到。

在运行时,程序可用于数组的唯一信息是其第一个元素的地址。甚至元素的大小也只能从使用数组的类型上下文中推断出来。

答案 3 :(得分:1)

在C中你不能因为数组在传递给函数时衰变成指针(第一个元素)。

但是在C ++中,您可以使用Template Argument Deduction来实现相同的目标。

答案 4 :(得分:1)

您需要将长度作为附加参数传递(如strncpy所做的那样)或者将数组终止(如strcpy那样)。

存在这些技术的小变化,比如将长度与指针捆绑在自己的类中,或者使用不同的标记来表示数组的长度,但这些基本上是您唯一的选择。

答案 5 :(得分:1)

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;
}

答案 6 :(得分:0)

已经很晚了。但是我找到了解决这个问题的方法。我知道这不是正确的解决方案,但如果你不想遍历整个数组的整数,它可以工作。

  

检查'\ 0'在这里不起作用

首先,在初始化时将任何字符放在数组中

for(i=0;i<1000;i++)
array[i]='x';

然后在传递值后检查'x'

i=0;
while(array[i]!='x')
{
i++;
return i;
}

让我知道它是否有用。

答案 7 :(得分:0)

不可能。您需要从函数中传递数组的大小,而您是从中调用此函数的。当您将数组传递给函数时,仅传递起始地址,而不传递整个大小,并且当您计算数组的大小时,编译器不知道该指针已由编译器分配多少大小/内存。因此,最后一次调用是,您在调用该函数时需要传递数组大小。

答案 8 :(得分:-3)

C中arry的大小是:

int a[]={10,2,22,31,1,2,44,21,5,8};

printf("Size : %d",sizeof(a)/sizeof(int));