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

时间:2022-03-09 17:27:04

I want to make a FUNCTION which calculates size of passed array.

我想创建一个函数来计算传递数组的大小。

I will pass an Array as input and it should return its length. I want a 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);

}

Length should be 5 as it contains 5 elements though it's size is 8 (Even 8 will do but 5 would be excellent)

长度应该是5,因为它包含5个元素,虽然它的大小是8(即使8也可以,但是5也很好)

I tried this:

我试着这样的:

int ArraySize(int * Array)
{

  return (sizeof(Array)/sizeof(int));

}

This won't work as "sizeof(Array)" will retun size of Int Pointer. This "sizeof" thing works only if you are in same function.

这将不起作用,因为“sizeof(数组)”将重新设置Int指针的大小。这个“sizeof”的东西只有当你在相同的功能。

Actually I am back to C after lots of days from C# So I can't remember (and Missing Array.Length())

实际上,从c#到c#的很多天之后,我又回到了C,所以我记不起来了(并且丢失了Array.Length()))

Regards!

的问候!

9 个解决方案

#1


23  

You cannot calculate the size of an array when all you've got is a pointer.

当你只有一个指针时,你不能计算数组的大小。

The only way to make this "function-like" is to define a macro:

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

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

This comes with all the usual caveats of macros, of course.

当然,这也伴随着所有常见的宏警告。

Edit: (The comments below really belong into the answer...)

编辑:(下面的评论真的属于答案…)

  1. You cannot determine the number of elements initialized within an array, unless you initialize all elements to an "invalid" value first and doing the counting of "valid" values manually. If your array has been defined as having 8 elements, for the compiler it has 8 elements, no matter whether you initialized only 5 of them.
  2. 不能确定数组中初始化的元素的数量,除非首先将所有元素初始化为“无效”值,然后手工计算“有效”值。如果您的数组被定义为有8个元素,那么对于编译器来说,它有8个元素,不管您是否初始化了其中的5个元素。
  3. You cannot determine the size of an array within a function to which that array has been passed as parameter. Not directly, not through a macro, not in any way. You can only determine the size of an array in the scope it has been declared in.
  4. 不能确定作为参数传递给该数组的函数中的数组的大小。不是直接的,不是通过宏,不是任何方式。您只能在已声明的范围内确定数组的大小。

The impossibility of determining the size of the array in a called function can be understood once you realize that sizeof() is a compile-time operator. It might look like a run-time function call, but it isn't: The compiler determines the size of the operands, and inserts them as constants.

一旦您认识到sizeof()是一个编译时操作符,就可以理解在调用函数中确定数组大小的不可能性。它看起来像是一个运行时函数调用,但实际上不是:编译器决定操作数的大小,并将它们作为常量插入。

In the scope the array is declared, the compiler has the information that it is actually an array, and how many elements it has.

在声明数组的范围内,编译器有它实际上是一个数组的信息,以及它有多少元素。

In a function to which the array is passed, all the compiler sees is a pointer. (Consider that the function might be called with many different arrays, and remember that sizeof() is a compile-time operator.

在传递数组的函数中,编译器看到的是一个指针。(请考虑使用许多不同的数组来调用该函数,并记住sizeof()是一个编译时操作符。

You can switch to C++ and use <vector>. You can define a struct vector plus functions handling that, but it's not really comfortable:

您可以切换到c++并使用 。你可以定义一个结构向量加上函数来处理这个问题,但这并不容易:

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

Bottom line: C arrays are limited. You cannot calculate their length in a sub-function, period. You have to code your way around that limitation, or use a different language (like C++).

底线:C数组是有限的。不能用子函数周期来计算它们的长度。您必须围绕这个限制编写代码,或者使用不同的语言(如c++)。

#2


11  

You can't do this once the array has decayed to a pointer - you'll always get the pointer size.

一旦数组衰减到指针,你就不能这样做了——你总是会得到指针的大小。

What you need to do is either:

你需要做的是:

  • use a sentinel value if possible, like NULL for pointers or -1 for positive numbers.
  • 如果可能的话,使用一个前哨值,比如指针为空,正数为-1。
  • calculate it when it's still an array, and pass that size to any functions.
  • 当它还是一个数组时计算它,并将这个大小传递给任何函数。
  • same as above but using funky macro magic, something like:
    #define arrSz(a) (sizeof(a)/sizeof(*a)).
  • 和上面一样,但是使用时髦的宏魔法,比如:#define arrSz(a) (sizeof(a)/sizeof(*a))。
  • create your own abstract data type which maintains the length as an item in a structure, so that you have a way of getting your Array.length().
  • 创建您自己的抽象数据类型,该类型将长度保持为结构中的一个项,以便您能够获得Array.length()。

#3


2  

What you ask for simply can't be done.

你所要求的是根本做不到的。

At run time, the only information made available to the program about an array is the address of its first element. Even the size of the elements is only inferred from the type context in which the array is used.

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

#4


1  

In C you can't because array decays into a pointer(to the first element) when passed to a function.

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

However in C++ you can use Template Argument Deduction to achieve the same.

但是在c++中,您可以使用模板参数演绎来实现相同的效果。

#5


1  

You need to either pass the length as an additional parameter (like strncpy does) or zero-terminate the array (like strcpy does).

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

Small variations of these techniques exist, like bundling the length with the pointer in its own class, or using a different marker for the length of the array, but these are basically your only choices.

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

#6


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

#7


0  

Is is very late. But I found a workaround for this problem. I know it is not the proper solution but can work if you don't want to traverse a whole array of integers.

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

checking '\0' will not work here

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

First, put any character in array at the time of initialization

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

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

then after passing values check for 'x'

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

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

let me know if it is of any use.

如果有用的话,请告诉我。

#8


-1  

To determine the size of your array in bytes, you can use the sizeof operator:

要用字节来确定数组的大小,可以使用sizeof操作符:

int a[<any size>];
int n = sizeof(a);

To determine the number of elements in the array, we can divide the total size of the array by the size of the array element. You could do this with the type, like this:

要确定数组中的元素数量,可以将数组的总大小除以数组元素的大小。你可以这样做:

int a[<total size>];
int n = sizeof(a) / sizeof(int);

NOTE: Enter required size within the angular brackets above.

注意:在上面的角括号中输入所需的尺寸。

#9


-3  

Size of an arry in C is :

C中arry的尺寸为:

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

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

#1


23  

You cannot calculate the size of an array when all you've got is a pointer.

当你只有一个指针时,你不能计算数组的大小。

The only way to make this "function-like" is to define a macro:

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

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

This comes with all the usual caveats of macros, of course.

当然,这也伴随着所有常见的宏警告。

Edit: (The comments below really belong into the answer...)

编辑:(下面的评论真的属于答案…)

  1. You cannot determine the number of elements initialized within an array, unless you initialize all elements to an "invalid" value first and doing the counting of "valid" values manually. If your array has been defined as having 8 elements, for the compiler it has 8 elements, no matter whether you initialized only 5 of them.
  2. 不能确定数组中初始化的元素的数量,除非首先将所有元素初始化为“无效”值,然后手工计算“有效”值。如果您的数组被定义为有8个元素,那么对于编译器来说,它有8个元素,不管您是否初始化了其中的5个元素。
  3. You cannot determine the size of an array within a function to which that array has been passed as parameter. Not directly, not through a macro, not in any way. You can only determine the size of an array in the scope it has been declared in.
  4. 不能确定作为参数传递给该数组的函数中的数组的大小。不是直接的,不是通过宏,不是任何方式。您只能在已声明的范围内确定数组的大小。

The impossibility of determining the size of the array in a called function can be understood once you realize that sizeof() is a compile-time operator. It might look like a run-time function call, but it isn't: The compiler determines the size of the operands, and inserts them as constants.

一旦您认识到sizeof()是一个编译时操作符,就可以理解在调用函数中确定数组大小的不可能性。它看起来像是一个运行时函数调用,但实际上不是:编译器决定操作数的大小,并将它们作为常量插入。

In the scope the array is declared, the compiler has the information that it is actually an array, and how many elements it has.

在声明数组的范围内,编译器有它实际上是一个数组的信息,以及它有多少元素。

In a function to which the array is passed, all the compiler sees is a pointer. (Consider that the function might be called with many different arrays, and remember that sizeof() is a compile-time operator.

在传递数组的函数中,编译器看到的是一个指针。(请考虑使用许多不同的数组来调用该函数,并记住sizeof()是一个编译时操作符。

You can switch to C++ and use <vector>. You can define a struct vector plus functions handling that, but it's not really comfortable:

您可以切换到c++并使用 。你可以定义一个结构向量加上函数来处理这个问题,但这并不容易:

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

Bottom line: C arrays are limited. You cannot calculate their length in a sub-function, period. You have to code your way around that limitation, or use a different language (like C++).

底线:C数组是有限的。不能用子函数周期来计算它们的长度。您必须围绕这个限制编写代码,或者使用不同的语言(如c++)。

#2


11  

You can't do this once the array has decayed to a pointer - you'll always get the pointer size.

一旦数组衰减到指针,你就不能这样做了——你总是会得到指针的大小。

What you need to do is either:

你需要做的是:

  • use a sentinel value if possible, like NULL for pointers or -1 for positive numbers.
  • 如果可能的话,使用一个前哨值,比如指针为空,正数为-1。
  • calculate it when it's still an array, and pass that size to any functions.
  • 当它还是一个数组时计算它,并将这个大小传递给任何函数。
  • same as above but using funky macro magic, something like:
    #define arrSz(a) (sizeof(a)/sizeof(*a)).
  • 和上面一样,但是使用时髦的宏魔法,比如:#define arrSz(a) (sizeof(a)/sizeof(*a))。
  • create your own abstract data type which maintains the length as an item in a structure, so that you have a way of getting your Array.length().
  • 创建您自己的抽象数据类型,该类型将长度保持为结构中的一个项,以便您能够获得Array.length()。

#3


2  

What you ask for simply can't be done.

你所要求的是根本做不到的。

At run time, the only information made available to the program about an array is the address of its first element. Even the size of the elements is only inferred from the type context in which the array is used.

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

#4


1  

In C you can't because array decays into a pointer(to the first element) when passed to a function.

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

However in C++ you can use Template Argument Deduction to achieve the same.

但是在c++中,您可以使用模板参数演绎来实现相同的效果。

#5


1  

You need to either pass the length as an additional parameter (like strncpy does) or zero-terminate the array (like strcpy does).

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

Small variations of these techniques exist, like bundling the length with the pointer in its own class, or using a different marker for the length of the array, but these are basically your only choices.

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

#6


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

#7


0  

Is is very late. But I found a workaround for this problem. I know it is not the proper solution but can work if you don't want to traverse a whole array of integers.

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

checking '\0' will not work here

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

First, put any character in array at the time of initialization

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

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

then after passing values check for 'x'

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

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

let me know if it is of any use.

如果有用的话,请告诉我。

#8


-1  

To determine the size of your array in bytes, you can use the sizeof operator:

要用字节来确定数组的大小,可以使用sizeof操作符:

int a[<any size>];
int n = sizeof(a);

To determine the number of elements in the array, we can divide the total size of the array by the size of the array element. You could do this with the type, like this:

要确定数组中的元素数量,可以将数组的总大小除以数组元素的大小。你可以这样做:

int a[<total size>];
int n = sizeof(a) / sizeof(int);

NOTE: Enter required size within the angular brackets above.

注意:在上面的角括号中输入所需的尺寸。

#9


-3  

Size of an arry in C is :

C中arry的尺寸为:

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

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